mirror of
https://github.com/libretro/RetroArch.git
synced 2025-04-02 10:51:52 -04:00
Style cleanups
This commit is contained in:
parent
f2429a99f4
commit
9d783b6627
15 changed files with 261 additions and 152 deletions
3
cheats.h
3
cheats.h
|
@ -19,10 +19,13 @@
|
|||
typedef struct cheat_manager cheat_manager_t;
|
||||
|
||||
cheat_manager_t* cheat_manager_new(const char *path);
|
||||
|
||||
void cheat_manager_free(cheat_manager_t *handle);
|
||||
|
||||
void cheat_manager_index_next(cheat_manager_t *handle);
|
||||
|
||||
void cheat_manager_index_prev(cheat_manager_t *handle);
|
||||
|
||||
void cheat_manager_toggle(cheat_manager_t *handle);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,7 +30,9 @@ core_option_manager_t *core_option_new(const char *conf_path,
|
|||
const struct retro_variable *vars);
|
||||
|
||||
bool core_option_updated(core_option_manager_t *opt);
|
||||
|
||||
void core_option_flush(core_option_manager_t *opt);
|
||||
|
||||
void core_option_free(core_option_manager_t *opt);
|
||||
|
||||
void core_option_get(core_option_manager_t *opt, struct retro_variable *var);
|
||||
|
@ -40,6 +42,7 @@ size_t core_option_size(core_option_manager_t *opt);
|
|||
|
||||
/* Gets description and current value for an option. */
|
||||
const char *core_option_get_desc(core_option_manager_t *opt, size_t index);
|
||||
|
||||
const char *core_option_get_val(core_option_manager_t *opt, size_t index);
|
||||
|
||||
/* Helpers to present a list of options */
|
||||
|
@ -51,6 +54,7 @@ void core_option_set_val(core_option_manager_t *opt,
|
|||
|
||||
/* Cycles through options for an option. Options wrap around. */
|
||||
void core_option_next(core_option_manager_t *opt, size_t index);
|
||||
|
||||
void core_option_prev(core_option_manager_t *opt, size_t index);
|
||||
|
||||
/* Sets default value for an option. */
|
||||
|
|
25
driver.h
25
driver.h
|
@ -439,16 +439,18 @@ typedef struct driver
|
|||
/* Set to true by driver if context caching succeeded. */
|
||||
bool video_cache_context_ack;
|
||||
|
||||
/* Set this to true if the platform in question needs to 'own' the respective
|
||||
* handle and therefore skip regular RetroArch driver teardown/reiniting procedure.
|
||||
/* Set this to true if the platform in question needs to 'own'
|
||||
* the respective handle and therefore skip regular RetroArch
|
||||
* driver teardown/reiniting procedure.
|
||||
*
|
||||
* If set to true, the 'free' function will get skipped. It is then up to the
|
||||
* driver implementation to properly handle 'reiniting' inside the 'init' function
|
||||
* and make sure it returns the existing handle instead of allocating and returning
|
||||
* a pointer to a new handle.
|
||||
* If set to true, the 'free' function will get skipped. It is
|
||||
* then up to the driver implementation to properly handle
|
||||
* 'reiniting' inside the 'init' function and make sure it
|
||||
* returns the existing handle instead of allocating and
|
||||
* returning a pointer to a new handle.
|
||||
*
|
||||
* Typically, if a driver intends to make use of this, it should set this to true
|
||||
* at the end of its 'init' function. */
|
||||
* Typically, if a driver intends to make use of this, it should
|
||||
* set this to true at the end of its 'init' function. */
|
||||
bool video_data_own;
|
||||
bool audio_data_own;
|
||||
bool input_data_own;
|
||||
|
@ -553,12 +555,12 @@ unsigned dspfilter_get_last_idx(void);
|
|||
|
||||
const char *rarch_dspfilter_get_name(void *data);
|
||||
|
||||
// Used by RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE
|
||||
/* Used by RETRO_ENVIRONMENT_GET_CAMERA_INTERFACE. */
|
||||
bool driver_camera_start(void);
|
||||
void driver_camera_stop(void);
|
||||
void driver_camera_poll(void);
|
||||
|
||||
// Used by RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE
|
||||
/* Used by RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE. */
|
||||
bool driver_location_start(void);
|
||||
void driver_location_stop(void);
|
||||
bool driver_location_get_position(double *lat, double *lon,
|
||||
|
@ -570,10 +572,9 @@ void driver_location_set_interval(unsigned interval_msecs,
|
|||
void find_menu_driver(void);
|
||||
#endif
|
||||
|
||||
// Used by RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO
|
||||
/* Used by RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO. */
|
||||
bool driver_update_system_av_info(const struct retro_system_av_info *info);
|
||||
|
||||
|
||||
extern driver_t driver;
|
||||
|
||||
/* Backends */
|
||||
|
|
|
@ -60,12 +60,14 @@ function_t dylib_proc(dylib_t lib, const char *proc);
|
|||
*
|
||||
* For statically linked cores, pass retro_set_environment as argument.
|
||||
*/
|
||||
void libretro_get_environment_info(void (*)(retro_environment_t), bool *load_no_content);
|
||||
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. */
|
||||
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);
|
||||
|
||||
void libretro_free_system_info(struct retro_system_info *info);
|
||||
#endif
|
||||
|
@ -121,7 +123,8 @@ 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 bool (*pretro_load_game_special)(unsigned,
|
||||
const struct retro_game_info*, size_t);
|
||||
|
||||
extern void (*pretro_unload_game)(void);
|
||||
|
||||
|
|
6
file.c
6
file.c
|
@ -165,12 +165,14 @@ static ssize_t read_content_file(const char *path, void **buf)
|
|||
return -1;
|
||||
}
|
||||
ret = read_compressed_file(g_extern.carchive_path,
|
||||
archive_found + strlen(g_extern.carchive_path) + 1, (void**)&ret_buf);
|
||||
archive_found + strlen(g_extern.carchive_path) + 1,
|
||||
(void**)&ret_buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we didn't actually find the archivename in the filename
|
||||
* the given path is not inside the archive. Then we proceed to just load the file.
|
||||
* the given path is not inside the archive. Then we proceed to
|
||||
* just load the file.
|
||||
*/
|
||||
ret = read_file(path, (void**)&ret_buf);
|
||||
}
|
||||
|
|
|
@ -25,14 +25,16 @@
|
|||
|
||||
#include "hash.h"
|
||||
|
||||
// File backends. Can be fleshed out later, but keep it simple for now.
|
||||
// The file is mapped to memory directly (via mmap() or just plain read_file()).
|
||||
/* File backends. Can be fleshed out later, but keep it simple for now.
|
||||
* The file is mapped to memory directly (via mmap() or just
|
||||
* plain read_file()).
|
||||
*/
|
||||
struct zlib_file_backend
|
||||
{
|
||||
void *(*open)(const char *path);
|
||||
const uint8_t *(*data)(void *handle);
|
||||
size_t (*size)(void *handle);
|
||||
void (*free)(void *handle); // Closes, unmaps and frees.
|
||||
void (*free)(void *handle); /* Closes, unmaps and frees. */
|
||||
};
|
||||
|
||||
#ifdef HAVE_MMAP
|
||||
|
@ -168,7 +170,7 @@ const struct zlib_file_backend *zlib_get_default_file_backend(void)
|
|||
}
|
||||
|
||||
|
||||
// Modified from nall::unzip (higan).
|
||||
/* Modified from nall::unzip (higan). */
|
||||
|
||||
#undef GOTO_END_ERROR
|
||||
#define GOTO_END_ERROR() do { \
|
||||
|
@ -292,7 +294,10 @@ bool zlib_parse_file(const char *file, zlib_file_cb file_cb, void *userdata)
|
|||
|
||||
const uint8_t *cdata = data + offset + 30 + offsetNL + offsetEL;
|
||||
|
||||
//RARCH_LOG("OFFSET: %u, CSIZE: %u, SIZE: %u.\n", offset + 30 + offsetNL + offsetEL, csize, size);
|
||||
#if 0
|
||||
RARCH_LOG("OFFSET: %u, CSIZE: %u, SIZE: %u.\n", offset + 30 +
|
||||
offsetNL + offsetEL, csize, size);
|
||||
#endif
|
||||
|
||||
if (!file_cb(filename, cdata, cmode, csize, size, crc32, userdata))
|
||||
break;
|
||||
|
@ -315,12 +320,13 @@ struct zip_extract_userdata
|
|||
bool found_content;
|
||||
};
|
||||
|
||||
static bool zip_extract_cb(const char *name, const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
|
||||
static bool zip_extract_cb(const char *name, const uint8_t *cdata,
|
||||
unsigned cmode, uint32_t csize, uint32_t size,
|
||||
uint32_t crc32, void *userdata)
|
||||
{
|
||||
struct zip_extract_userdata *data = (struct zip_extract_userdata*)userdata;
|
||||
|
||||
// Extract first content that matches our list.
|
||||
/* Extract first content that matches our list. */
|
||||
const char *ext = path_get_extension(name);
|
||||
if (ext && string_list_find_elem(data->ext, ext))
|
||||
{
|
||||
|
@ -335,11 +341,12 @@ static bool zip_extract_cb(const char *name, const uint8_t *cdata, unsigned cmod
|
|||
|
||||
switch (cmode)
|
||||
{
|
||||
case 0: // Uncompressed
|
||||
/* Uncompressed. */
|
||||
case 0:
|
||||
data->found_content = write_file(new_path, cdata, size);
|
||||
return false;
|
||||
|
||||
case 8: // Deflate
|
||||
/* Deflate. */
|
||||
case 8:
|
||||
if (zlib_inflate_data_to_file(new_path, cdata, csize, size, crc32))
|
||||
{
|
||||
strlcpy(data->zip_path, new_path, data->zip_path_size);
|
||||
|
@ -356,8 +363,8 @@ static bool zip_extract_cb(const char *name, const uint8_t *cdata, unsigned cmod
|
|||
return true;
|
||||
}
|
||||
|
||||
bool zlib_extract_first_content_file(char *zip_path, size_t zip_path_size, const char *valid_exts,
|
||||
const char *extraction_directory)
|
||||
bool zlib_extract_first_content_file(char *zip_path, size_t zip_path_size,
|
||||
const char *valid_exts, const char *extraction_directory)
|
||||
{
|
||||
bool ret;
|
||||
struct zip_extract_userdata userdata = {0};
|
||||
|
@ -397,9 +404,9 @@ end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool zlib_get_file_list_cb(const char *path, const uint8_t *cdata, unsigned cmode,
|
||||
uint32_t csize, uint32_t size,
|
||||
uint32_t crc32, void *userdata)
|
||||
static bool zlib_get_file_list_cb(const char *path, const uint8_t *cdata,
|
||||
unsigned cmode, uint32_t csize, uint32_t size, uint32_t crc32,
|
||||
void *userdata)
|
||||
{
|
||||
(void)cdata;
|
||||
(void)cmode;
|
||||
|
|
|
@ -21,16 +21,19 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Returns true when parsing should continue. False to stop.
|
||||
/* Returns true when parsing should continue. False to stop. */
|
||||
typedef bool (*zlib_file_cb)(const char *name,
|
||||
const uint8_t *cdata, unsigned cmode, uint32_t csize, uint32_t size,
|
||||
uint32_t crc32, void *userdata);
|
||||
|
||||
// Low-level file parsing. Enumerates over all files and calls file_cb with userdata.
|
||||
/* Low-level file parsing. Enumerates over all files and calls
|
||||
* file_cb with userdata. */
|
||||
bool zlib_parse_file(const char *file, zlib_file_cb file_cb, void *userdata);
|
||||
|
||||
// Built with zlib_parse_file.
|
||||
bool zlib_extract_first_content_file(char *zip_path, size_t zip_path_size, const char *valid_exts, const char *extraction_dir);
|
||||
/* Built with zlib_parse_file. */
|
||||
bool zlib_extract_first_content_file(char *zip_path, size_t zip_path_size,
|
||||
const char *valid_exts, const char *extraction_dir);
|
||||
|
||||
struct string_list *zlib_get_file_list(const char *path);
|
||||
|
||||
bool zlib_inflate_data_to_file(const char *path, const uint8_t *data,
|
||||
|
|
61
general.h
61
general.h
|
@ -415,7 +415,11 @@ typedef struct rarch_viewport
|
|||
unsigned full_height;
|
||||
} rarch_viewport_t;
|
||||
|
||||
// All run-time- / command line flag-related globals go here.
|
||||
#define AUDIO_BUFFER_FREE_SAMPLES_COUNT (8 * 1024)
|
||||
#define MEASURE_FRAME_TIME_SAMPLES_COUNT (2 * 1024)
|
||||
|
||||
/* All run-time- / command line flag-related globals go here. */
|
||||
|
||||
struct global
|
||||
{
|
||||
bool verbosity;
|
||||
|
@ -451,7 +455,7 @@ struct global
|
|||
bool has_set_netplay_delay_frames;
|
||||
bool has_set_netplay_ip_port;
|
||||
|
||||
// Config associated with global "default" config.
|
||||
/* Config associated with global "default" config. */
|
||||
char config_path[PATH_MAX];
|
||||
char append_config_path[PATH_MAX];
|
||||
char input_config_path[PATH_MAX];
|
||||
|
@ -464,24 +468,26 @@ struct global
|
|||
char fullpath[PATH_MAX];
|
||||
|
||||
#ifdef HAVE_COMPRESSION
|
||||
// In case of a compressed archive, this is the path to the archive. Fullpath contains everything
|
||||
/* In case of a compressed archive, this is the path
|
||||
* to the archive. Fullpath contains everything. */
|
||||
char carchive_path[PATH_MAX];
|
||||
|
||||
// True, in case of a compressed archive containing the rom.
|
||||
/* True, in case of a compressed archive
|
||||
* containing the content file. */
|
||||
bool is_carchive;
|
||||
#endif
|
||||
|
||||
// A list of save types and associated paths for all content.
|
||||
/* A list of save types and associated paths for all content. */
|
||||
struct string_list *savefiles;
|
||||
|
||||
// For --subsystem content.
|
||||
/* For --subsystem content. */
|
||||
char subsystem[256];
|
||||
struct string_list *subsystem_fullpaths;
|
||||
|
||||
char savefile_name[PATH_MAX];
|
||||
char savestate_name[PATH_MAX];
|
||||
|
||||
// Used on reentrancy to use a savestate dir.
|
||||
/* Used on reentrancy to use a savestate dir. */
|
||||
char savefile_dir[PATH_MAX];
|
||||
char savestate_dir[PATH_MAX];
|
||||
|
||||
|
@ -580,11 +586,9 @@ struct global
|
|||
|
||||
struct
|
||||
{
|
||||
#define AUDIO_BUFFER_FREE_SAMPLES_COUNT (8 * 1024)
|
||||
unsigned buffer_free_samples[AUDIO_BUFFER_FREE_SAMPLES_COUNT];
|
||||
uint64_t buffer_free_samples_count;
|
||||
|
||||
#define MEASURE_FRAME_TIME_SAMPLES_COUNT (2 * 1024)
|
||||
retro_time_t frame_time_samples[MEASURE_FRAME_TIME_SAMPLES_COUNT];
|
||||
uint64_t frame_time_samples_count;
|
||||
} measure_data;
|
||||
|
@ -603,19 +607,19 @@ struct global
|
|||
|
||||
bool exec;
|
||||
|
||||
// Rewind support.
|
||||
/* Rewind support. */
|
||||
state_manager_t *state_manager;
|
||||
size_t state_size;
|
||||
bool frame_is_reverse;
|
||||
|
||||
// Movie playback/recording support.
|
||||
/* Movie playback/recording support. */
|
||||
struct
|
||||
{
|
||||
bsv_movie_t *movie;
|
||||
char movie_path[PATH_MAX];
|
||||
bool movie_playback;
|
||||
|
||||
// Immediate playback/recording.
|
||||
/* Immediate playback/recording. */
|
||||
char movie_start_path[PATH_MAX];
|
||||
bool movie_start_recording;
|
||||
bool movie_start_playback;
|
||||
|
@ -632,22 +636,22 @@ struct global
|
|||
bool sram_save_disable;
|
||||
bool use_sram;
|
||||
|
||||
// Pausing support
|
||||
/* Pausing support. */
|
||||
bool is_paused;
|
||||
bool is_oneshot;
|
||||
bool is_slowmotion;
|
||||
|
||||
// Turbo support
|
||||
/* Turbo support. */
|
||||
bool turbo_frame_enable[MAX_PLAYERS];
|
||||
uint16_t turbo_enable[MAX_PLAYERS];
|
||||
unsigned turbo_count;
|
||||
|
||||
// Autosave support.
|
||||
/* Autosave support. */
|
||||
autosave_t **autosave;
|
||||
unsigned num_autosave;
|
||||
|
||||
// Netplay.
|
||||
#ifdef HAVE_NETPLAY
|
||||
/* Netplay. */
|
||||
netplay_t *netplay;
|
||||
char netplay_server[PATH_MAX];
|
||||
bool netplay_enable;
|
||||
|
@ -657,7 +661,7 @@ struct global
|
|||
unsigned netplay_port;
|
||||
#endif
|
||||
|
||||
// Recording.
|
||||
/* Recording. */
|
||||
const ffemu_backend_t *rec_driver;
|
||||
void *rec;
|
||||
|
||||
|
@ -700,7 +704,8 @@ struct global
|
|||
|
||||
bool block_config_read;
|
||||
|
||||
// Settings and/or global state that is specific to a console-style implementation.
|
||||
/* Settings and/or global state that is specific to
|
||||
* a console-style implementation. */
|
||||
struct
|
||||
{
|
||||
struct
|
||||
|
@ -739,7 +744,8 @@ struct global
|
|||
|
||||
uint64_t lifecycle_state;
|
||||
|
||||
// If this is non-NULL. RARCH_LOG and friends will write to this file.
|
||||
/* If this is non-NULL. RARCH_LOG and friends
|
||||
* will write to this file. */
|
||||
FILE *log_file;
|
||||
|
||||
bool main_is_init;
|
||||
|
@ -750,7 +756,7 @@ struct global
|
|||
bool libretro_no_content;
|
||||
bool libretro_dummy;
|
||||
|
||||
// Config file associated with per-core configs.
|
||||
/* Config file associated with per-core configs. */
|
||||
char core_specific_config_path[PATH_MAX];
|
||||
};
|
||||
|
||||
|
@ -767,13 +773,12 @@ struct rarch_main_wrap
|
|||
bool touched;
|
||||
};
|
||||
|
||||
// Public data structures
|
||||
/* Public data structures. */
|
||||
extern struct settings g_settings;
|
||||
extern struct global g_extern;
|
||||
extern struct defaults g_defaults;
|
||||
/////////
|
||||
|
||||
// Public functions
|
||||
/* Public functions. */
|
||||
void config_load(void);
|
||||
void config_set_defaults(void);
|
||||
const char *config_get_default_camera(void);
|
||||
|
@ -826,8 +831,6 @@ int rarch_defer_core(core_info_list_t *data,
|
|||
const char *dir, const char *path, char *deferred_path,
|
||||
size_t sizeof_deferred_path);
|
||||
|
||||
/////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -839,11 +842,13 @@ static inline float db_to_gain(float db)
|
|||
|
||||
static inline void rarch_fail(int error_code, const char *error)
|
||||
{
|
||||
// We cannot longjmp unless we're in rarch_main_init().
|
||||
// If not, something went very wrong, and we should just exit right away.
|
||||
/* We cannot longjmp unless we're in rarch_main_init().
|
||||
* If not, something went very wrong, and we should
|
||||
* just exit right away. */
|
||||
rarch_assert(g_extern.error_in_init);
|
||||
|
||||
strlcpy(g_extern.error_string, error, sizeof(g_extern.error_string));
|
||||
strlcpy(g_extern.error_string, error,
|
||||
sizeof(g_extern.error_string));
|
||||
longjmp(g_extern.error_sjlj_context, error_code);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Put this in a separate file so we don't have to rebuilt retroarch.c every single build.
|
||||
/* Put this in a separate file so we don't have to rebuilt
|
||||
* retroarch.c every single build. */
|
||||
extern const char rarch_git_version[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -121,7 +121,7 @@ static inline uint8_t is_little_endian(void)
|
|||
|
||||
static inline uint32_t swap_if_big32(uint32_t val)
|
||||
{
|
||||
if (is_little_endian()) // Little-endian
|
||||
if (is_little_endian())
|
||||
return val;
|
||||
return (val >> 24) | ((val >> 8) & 0xFF00) |
|
||||
((val << 8) & 0xFF0000) | (val << 24);
|
||||
|
|
10
movie.h
10
movie.h
|
@ -37,15 +37,17 @@ enum rarch_movie_type
|
|||
|
||||
bsv_movie_t *bsv_movie_init(const char *path, enum rarch_movie_type type);
|
||||
|
||||
// Playback
|
||||
/* Playback. */
|
||||
bool bsv_movie_get_input(bsv_movie_t *handle, int16_t *input);
|
||||
|
||||
// Recording
|
||||
/* Recording. */
|
||||
void bsv_movie_set_input(bsv_movie_t *handle, int16_t input);
|
||||
|
||||
// Used for rewinding while playback/record.
|
||||
void bsv_movie_set_frame_start(bsv_movie_t *handle); // Debugging purposes.
|
||||
/* Used for rewinding while playback/record. */
|
||||
void bsv_movie_set_frame_start(bsv_movie_t *handle);
|
||||
|
||||
void bsv_movie_set_frame_end(bsv_movie_t *handle);
|
||||
|
||||
void bsv_movie_frame_rewind(bsv_movie_t *handle);
|
||||
|
||||
void bsv_movie_free(bsv_movie_t *handle);
|
||||
|
|
191
netplay.c
191
netplay.c
|
@ -26,20 +26,25 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// Checks if input port/index is controlled by netplay or not.
|
||||
/* Checks if input port/index is controlled by netplay or not. */
|
||||
static bool netplay_is_alive(netplay_t *handle);
|
||||
|
||||
static bool netplay_poll(netplay_t *handle);
|
||||
|
||||
static int16_t netplay_input_state(netplay_t *handle, bool port,
|
||||
unsigned device, unsigned index, unsigned id);
|
||||
|
||||
// If we're fast-forward replaying to resync, check if we should actually show frame.
|
||||
/* If we're fast-forward replaying to resync, check if we
|
||||
* should actually show frame. */
|
||||
static bool netplay_should_skip(netplay_t *handle);
|
||||
|
||||
static bool netplay_can_poll(netplay_t *handle);
|
||||
|
||||
static void netplay_set_spectate_input(netplay_t *handle, int16_t input);
|
||||
|
||||
static bool netplay_send_cmd(netplay_t *handle, uint32_t cmd,
|
||||
const void *data, size_t size);
|
||||
|
||||
static bool netplay_get_cmd(netplay_t *handle);
|
||||
|
||||
#define PREV_PTR(x) ((x) == 0 ? handle->buffer_size - 1 : (x) - 1)
|
||||
|
@ -71,9 +76,12 @@ struct netplay
|
|||
struct sockaddr_storage other_addr;
|
||||
|
||||
struct retro_callbacks cbs;
|
||||
int fd; // TCP connection for state sending, etc. Also used for commands.
|
||||
int udp_fd; // UDP connection for game state updates.
|
||||
unsigned port; // Which port is governed by netplay (other player)?
|
||||
/* TCP connection for state sending, etc. Also used for commands */
|
||||
int fd;
|
||||
/* UDP connection for game state updates. */
|
||||
int udp_fd;
|
||||
/* Which port is governed by netplay (other player)? */
|
||||
unsigned port;
|
||||
bool has_connection;
|
||||
|
||||
struct delta_frame *buffer;
|
||||
|
@ -89,7 +97,8 @@ struct netplay
|
|||
bool is_replay; // Are we replaying old frames?
|
||||
bool can_poll; // We don't want to poll several times on a frame.
|
||||
|
||||
uint32_t packet_buffer[UDP_FRAME_PACKETS * 2]; // To compat UDP packet loss we also send old data along with the packets.
|
||||
// To compat UDP packet loss we also send old data along with the packets.
|
||||
uint32_t packet_buffer[UDP_FRAME_PACKETS * 2];
|
||||
uint32_t frame_count;
|
||||
uint32_t read_frame_count;
|
||||
uint32_t other_frame_count;
|
||||
|
@ -111,8 +120,8 @@ struct netplay
|
|||
// Player flipping
|
||||
// Flipping state. If ptr >= flip_frame, we apply the flip.
|
||||
// If not, we apply the opposite, effectively creating a trigger point.
|
||||
// To avoid collition we need to make sure our client/host is synced up well after flip_frame
|
||||
// before allowing another flip.
|
||||
// To avoid collition we need to make sure our client/host is synced up
|
||||
// well after flip_frame before allowing another flip.
|
||||
bool flip;
|
||||
uint32_t flip_frame;
|
||||
};
|
||||
|
@ -189,7 +198,7 @@ int16_t input_state_net(unsigned port, unsigned device, unsigned index, unsigned
|
|||
}
|
||||
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
// Custom inet_ntop. Win32 doesn't seem to support this ...
|
||||
/* Custom inet_ntop. Win32 doesn't seem to support this ... */
|
||||
static void log_connection(const struct sockaddr_storage *their_addr,
|
||||
unsigned slot, const char *nick)
|
||||
{
|
||||
|
@ -213,7 +222,8 @@ static void log_connection(const struct sockaddr_storage *their_addr,
|
|||
in.sin_family = AF_INET;
|
||||
memcpy(&in.sin_addr, &u.v4->sin_addr, sizeof(struct in_addr));
|
||||
|
||||
getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in), buf_v4, sizeof(buf_v4),
|
||||
getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in),
|
||||
buf_v4, sizeof(buf_v4),
|
||||
NULL, 0, NI_NUMERICHOST);
|
||||
}
|
||||
else if (their_addr->ss_family == AF_INET6)
|
||||
|
@ -231,14 +241,16 @@ static void log_connection(const struct sockaddr_storage *their_addr,
|
|||
if (str)
|
||||
{
|
||||
char msg[512];
|
||||
snprintf(msg, sizeof(msg), "Got connection from: \"%s (%s)\" (#%u)", nick, str, slot);
|
||||
snprintf(msg, sizeof(msg), "Got connection from: \"%s (%s)\" (#%u)",
|
||||
nick, str, slot);
|
||||
msg_queue_push(g_extern.msg_queue, msg, 1, 180);
|
||||
RARCH_LOG("%s\n", msg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int init_tcp_connection(const struct addrinfo *res, bool server, bool spectate,
|
||||
static int init_tcp_connection(const struct addrinfo *res,
|
||||
bool server, bool spectate,
|
||||
struct sockaddr *other_addr, socklen_t addr_size)
|
||||
{
|
||||
bool ret = true;
|
||||
|
@ -302,7 +314,8 @@ end:
|
|||
return fd;
|
||||
}
|
||||
|
||||
static bool init_tcp_socket(netplay_t *handle, const char *server, uint16_t port, bool spectate)
|
||||
static bool init_tcp_socket(netplay_t *handle, const char *server,
|
||||
uint16_t port, bool spectate)
|
||||
{
|
||||
struct addrinfo hints, *res = NULL;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
@ -326,13 +339,15 @@ static bool init_tcp_socket(netplay_t *handle, const char *server, uint16_t port
|
|||
if (!res)
|
||||
return false;
|
||||
|
||||
// If "localhost" is used, it is important to check every possible address for ipv4/ipv6.
|
||||
/* If "localhost" is used, it is important to check every possible
|
||||
* address for IPv4/IPv6. */
|
||||
const struct addrinfo *tmp_info = res;
|
||||
while (tmp_info)
|
||||
{
|
||||
int fd;
|
||||
if ((fd = init_tcp_connection(tmp_info, server, handle->spectate,
|
||||
(struct sockaddr*)&handle->other_addr, sizeof(handle->other_addr))) >= 0)
|
||||
(struct sockaddr*)&handle->other_addr,
|
||||
sizeof(handle->other_addr))) >= 0)
|
||||
{
|
||||
ret = true;
|
||||
handle->fd = fd;
|
||||
|
@ -351,7 +366,8 @@ static bool init_tcp_socket(netplay_t *handle, const char *server, uint16_t port
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool init_udp_socket(netplay_t *handle, const char *server, uint16_t port)
|
||||
static bool init_udp_socket(netplay_t *handle, const char *server,
|
||||
uint16_t port)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
@ -372,7 +388,9 @@ static bool init_udp_socket(netplay_t *handle, const char *server, uint16_t port
|
|||
if (!handle->addr)
|
||||
return false;
|
||||
|
||||
handle->udp_fd = socket(handle->addr->ai_family, handle->addr->ai_socktype, handle->addr->ai_protocol);
|
||||
handle->udp_fd = socket(handle->addr->ai_family,
|
||||
handle->addr->ai_socktype, handle->addr->ai_protocol);
|
||||
|
||||
if (handle->udp_fd < 0)
|
||||
{
|
||||
RARCH_ERR("Failed to initialize socket.\n");
|
||||
|
@ -381,11 +399,13 @@ static bool init_udp_socket(netplay_t *handle, const char *server, uint16_t port
|
|||
|
||||
if (!server)
|
||||
{
|
||||
// Note sure if we have to do this for UDP, but hey :)
|
||||
/* Not sure if we have to do this for UDP, but hey :) */
|
||||
int yes = 1;
|
||||
setsockopt(handle->udp_fd, SOL_SOCKET, SO_REUSEADDR, CONST_CAST &yes, sizeof(int));
|
||||
setsockopt(handle->udp_fd, SOL_SOCKET, SO_REUSEADDR,
|
||||
CONST_CAST &yes, sizeof(int));
|
||||
|
||||
if (bind(handle->udp_fd, handle->addr->ai_addr, handle->addr->ai_addrlen) < 0)
|
||||
if (bind(handle->udp_fd, handle->addr->ai_addr,
|
||||
handle->addr->ai_addrlen) < 0)
|
||||
{
|
||||
RARCH_ERR("Failed to bind socket.\n");
|
||||
close(handle->udp_fd);
|
||||
|
@ -399,7 +419,7 @@ static bool init_udp_socket(netplay_t *handle, const char *server, uint16_t port
|
|||
return true;
|
||||
}
|
||||
|
||||
// Platform specific socket library init.
|
||||
/* Platform specific socket library init. */
|
||||
bool netplay_init_network(void)
|
||||
{
|
||||
static bool inited = false;
|
||||
|
@ -417,7 +437,7 @@ bool netplay_init_network(void)
|
|||
cellSysmoduleLoadModule(CELL_SYSMODULE_NET);
|
||||
sys_net_initialize_network();
|
||||
#else
|
||||
signal(SIGPIPE, SIG_IGN); // Do not like SIGPIPE killing our app :(
|
||||
signal(SIGPIPE, SIG_IGN); /* Do not like SIGPIPE killing our app. */
|
||||
#endif
|
||||
|
||||
inited = true;
|
||||
|
@ -442,9 +462,13 @@ bool netplay_can_poll(netplay_t *handle)
|
|||
return handle->can_poll;
|
||||
}
|
||||
|
||||
// Not really a hash, but should be enough to differentiate implementations from each other.
|
||||
// Subtle differences in the implementation will not be possible to spot.
|
||||
// The alternative would have been checking serialization sizes, but it was troublesome for cross platform compat.
|
||||
/* Not really a hash, but should be enough to differentiate
|
||||
* implementations from each other.
|
||||
*
|
||||
* Subtle differences in the implementation will not be possible to spot.
|
||||
* The alternative would have been checking serialization sizes, but it
|
||||
* was troublesome for cross platform compat.
|
||||
*/
|
||||
static uint32_t implementation_magic_value(void)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -532,7 +556,7 @@ static bool send_info(netplay_t *handle)
|
|||
return false;
|
||||
}
|
||||
|
||||
// Get SRAM data from Player 1.
|
||||
/* Get SRAM data from Player 1. */
|
||||
void *sram = pretro_get_memory_data(RETRO_MEMORY_SAVE_RAM);
|
||||
unsigned sram_size = pretro_get_memory_size(RETRO_MEMORY_SAVE_RAM);
|
||||
|
||||
|
@ -731,7 +755,8 @@ static bool get_info_spectate(netplay_t *handle)
|
|||
static void init_buffers(netplay_t *handle)
|
||||
{
|
||||
unsigned i;
|
||||
handle->buffer = (struct delta_frame*)calloc(handle->buffer_size, sizeof(*handle->buffer));
|
||||
handle->buffer = (struct delta_frame*)calloc(handle->buffer_size,
|
||||
sizeof(*handle->buffer));
|
||||
handle->state_size = pretro_serialize_size();
|
||||
for (i = 0; i < handle->buffer_size; i++)
|
||||
{
|
||||
|
@ -852,8 +877,9 @@ static int poll_input(netplay_t *handle, bool block)
|
|||
{
|
||||
handle->timeout_cnt++;
|
||||
|
||||
// select() does not take pointer to const struct timeval.
|
||||
// Technically possible for select() to modify tmp_tv, so we go paranoia mode.
|
||||
/* select() does not take pointer to const struct timeval.
|
||||
* Technically possible for select() to modify tmp_tv, so
|
||||
* we go paranoia mode. */
|
||||
struct timeval tmp_tv = tv;
|
||||
|
||||
fd_set fds;
|
||||
|
@ -864,8 +890,8 @@ static int poll_input(netplay_t *handle, bool block)
|
|||
if (select(max_fd, &fds, NULL, NULL, &tmp_tv) < 0)
|
||||
return -1;
|
||||
|
||||
// Somewhat hacky,
|
||||
// but we aren't using the TCP connection for anything useful atm.
|
||||
/* Somewhat hacky,
|
||||
* but we aren't using the TCP connection for anything useful atm. */
|
||||
if (FD_ISSET(handle->fd, &fds) && !netplay_get_cmd(handle))
|
||||
return -1;
|
||||
|
||||
|
@ -891,19 +917,22 @@ static int poll_input(netplay_t *handle, bool block)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Grab our own input state and send this over the network.
|
||||
/* Grab our own input state and send this over the network. */
|
||||
static bool get_self_input_state(netplay_t *handle)
|
||||
{
|
||||
unsigned i;
|
||||
struct delta_frame *ptr = &handle->buffer[handle->self_ptr];
|
||||
|
||||
uint32_t state = 0;
|
||||
if (!driver.block_libretro_input && handle->frame_count > 0) // First frame we always give zero input since relying on input from first frame screws up when we use -F 0.
|
||||
if (!driver.block_libretro_input && handle->frame_count > 0)
|
||||
{
|
||||
/* First frame we always give zero input since relying on
|
||||
* input from first frame screws up when we use -F 0. */
|
||||
retro_input_state_t cb = handle->cbs.state_cb;
|
||||
for (i = 0; i < RARCH_FIRST_META_KEY; i++)
|
||||
{
|
||||
int16_t tmp = cb(g_settings.input.netplay_client_swap_input ? 0 : !handle->port,
|
||||
int16_t tmp = cb(g_settings.input.netplay_client_swap_input ?
|
||||
0 : !handle->port,
|
||||
RETRO_DEVICE_JOYPAD, 0, i);
|
||||
state |= tmp ? 1 << i : 0;
|
||||
}
|
||||
|
@ -926,13 +955,14 @@ static bool get_self_input_state(netplay_t *handle)
|
|||
return true;
|
||||
}
|
||||
|
||||
// TODO: Somewhat better prediction. :P
|
||||
/* TODO: Somewhat better prediction. :P */
|
||||
static void simulate_input(netplay_t *handle)
|
||||
{
|
||||
size_t ptr = PREV_PTR(handle->self_ptr);
|
||||
size_t prev = PREV_PTR(handle->read_ptr);
|
||||
|
||||
handle->buffer[ptr].simulated_input_state = handle->buffer[prev].real_input_state;
|
||||
handle->buffer[ptr].simulated_input_state =
|
||||
handle->buffer[prev].real_input_state;
|
||||
handle->buffer[ptr].is_simulated = true;
|
||||
handle->buffer[ptr].used_real = false;
|
||||
}
|
||||
|
@ -962,13 +992,16 @@ static void parse_packet(netplay_t *handle, uint32_t *buffer, unsigned size)
|
|||
static bool receive_data(netplay_t *handle, uint32_t *buffer, size_t size)
|
||||
{
|
||||
socklen_t addrlen = sizeof(handle->their_addr);
|
||||
if (recvfrom(handle->udp_fd, NONCONST_CAST buffer, size, 0, (struct sockaddr*)&handle->their_addr, &addrlen) != (ssize_t)size)
|
||||
if (recvfrom(handle->udp_fd, NONCONST_CAST buffer, size, 0,
|
||||
(struct sockaddr*)&handle->their_addr, &addrlen) != (ssize_t)size)
|
||||
return false;
|
||||
handle->has_client_addr = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Poll network to see if we have anything new. If our network buffer is full, we simply have to block for new input data.
|
||||
/* Poll network to see if we have anything new. If our
|
||||
* network buffer is full, we simply have to block for new input data. */
|
||||
|
||||
static bool netplay_poll(netplay_t *handle)
|
||||
{
|
||||
if (!handle->has_connection)
|
||||
|
@ -979,7 +1012,8 @@ static bool netplay_poll(netplay_t *handle)
|
|||
if (!get_self_input_state(handle))
|
||||
return false;
|
||||
|
||||
// We skip reading the first frame so the host has a chance to grab our host info so we don't block forever :')
|
||||
/* We skip reading the first frame so the host has a chance to grab
|
||||
* our host info so we don't block forever :') */
|
||||
if (handle->frame_count == 0)
|
||||
{
|
||||
handle->buffer[0].used_real = true;
|
||||
|
@ -990,7 +1024,8 @@ static bool netplay_poll(netplay_t *handle)
|
|||
return true;
|
||||
}
|
||||
|
||||
// We might have reached the end of the buffer, where we simply have to block.
|
||||
/* We might have reached the end of the buffer, where we
|
||||
* simply have to block. */
|
||||
int res = poll_input(handle, handle->other_ptr == handle->self_ptr);
|
||||
if (res == -1)
|
||||
{
|
||||
|
@ -1019,7 +1054,7 @@ static bool netplay_poll(netplay_t *handle)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Cannot allow this. Should not happen though.
|
||||
/* Cannot allow this. Should not happen though. */
|
||||
if (handle->self_ptr == handle->other_ptr)
|
||||
{
|
||||
warn_hangup();
|
||||
|
@ -1035,7 +1070,8 @@ static bool netplay_poll(netplay_t *handle)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool netplay_send_cmd(netplay_t *handle, uint32_t cmd, const void *data, size_t size)
|
||||
static bool netplay_send_cmd(netplay_t *handle, uint32_t cmd,
|
||||
const void *data, size_t size)
|
||||
{
|
||||
cmd = (cmd << 16) | (size & 0xffff);
|
||||
cmd = htonl(cmd);
|
||||
|
@ -1138,20 +1174,21 @@ void netplay_flip_players(netplay_t *handle)
|
|||
goto error;
|
||||
}
|
||||
|
||||
// Make sure both clients are definitely synced up.
|
||||
/* Make sure both clients are definitely synced up. */
|
||||
if (handle->frame_count < (handle->flip_frame + 2 * UDP_FRAME_PACKETS))
|
||||
{
|
||||
msg = "Cannot flip players yet. Wait a second or two before attempting flip.";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (netplay_send_cmd(handle, NETPLAY_CMD_FLIP_PLAYERS, &flip_frame_net, sizeof(flip_frame_net))
|
||||
if (netplay_send_cmd(handle, NETPLAY_CMD_FLIP_PLAYERS,
|
||||
&flip_frame_net, sizeof(flip_frame_net))
|
||||
&& netplay_get_response(handle))
|
||||
{
|
||||
RARCH_LOG("Netplay players are flipped.\n");
|
||||
msg_queue_push(g_extern.msg_queue, "Netplay players are flipped.", 1, 180);
|
||||
|
||||
// Queue up a flip well enough in the future.
|
||||
/* Queue up a flip well enough in the future. */
|
||||
handle->flip ^= true;
|
||||
handle->flip_frame = flip_frame;
|
||||
}
|
||||
|
@ -1173,15 +1210,18 @@ static bool netplay_flip_port(netplay_t *handle, bool port)
|
|||
if (handle->flip_frame == 0)
|
||||
return port;
|
||||
|
||||
size_t frame = handle->is_replay ? handle->tmp_frame_count : handle->frame_count;
|
||||
size_t frame = handle->is_replay ?
|
||||
handle->tmp_frame_count : handle->frame_count;
|
||||
|
||||
return port ^ handle->flip ^ (frame < handle->flip_frame);
|
||||
}
|
||||
|
||||
int16_t netplay_input_state(netplay_t *handle, bool port, unsigned device, unsigned index, unsigned id)
|
||||
int16_t netplay_input_state(netplay_t *handle, bool port, unsigned device,
|
||||
unsigned index, unsigned id)
|
||||
{
|
||||
uint16_t input_state = 0;
|
||||
size_t ptr = handle->is_replay ? handle->tmp_ptr : PREV_PTR(handle->self_ptr);
|
||||
size_t ptr = handle->is_replay ?
|
||||
handle->tmp_ptr : PREV_PTR(handle->self_ptr);
|
||||
|
||||
port = netplay_flip_port(handle, port);
|
||||
|
||||
|
@ -1234,7 +1274,8 @@ static bool netplay_should_skip(netplay_t *handle)
|
|||
|
||||
static void netplay_pre_frame_net(netplay_t *handle)
|
||||
{
|
||||
pretro_serialize(handle->buffer[handle->self_ptr].state, handle->state_size);
|
||||
pretro_serialize(handle->buffer[handle->self_ptr].state,
|
||||
handle->state_size);
|
||||
handle->can_poll = true;
|
||||
|
||||
input_poll_net();
|
||||
|
@ -1253,14 +1294,16 @@ static void netplay_set_spectate_input(netplay_t *handle, int16_t input)
|
|||
handle->spectate_input[handle->spectate_input_ptr++] = swap_if_big16(input);
|
||||
}
|
||||
|
||||
int16_t input_state_spectate(unsigned port, unsigned device, unsigned index, unsigned id)
|
||||
int16_t input_state_spectate(unsigned port, unsigned device,
|
||||
unsigned index, unsigned id)
|
||||
{
|
||||
int16_t res = g_extern.netplay->cbs.state_cb(port, device, index, id);
|
||||
netplay_set_spectate_input(g_extern.netplay, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int16_t netplay_get_spectate_input(netplay_t *handle, bool port, unsigned device, unsigned index, unsigned id)
|
||||
static int16_t netplay_get_spectate_input(netplay_t *handle, bool port,
|
||||
unsigned device, unsigned index, unsigned id)
|
||||
{
|
||||
int16_t inp;
|
||||
if (recv_all(handle->fd, NONCONST_CAST &inp, sizeof(inp)))
|
||||
|
@ -1269,16 +1312,19 @@ static int16_t netplay_get_spectate_input(netplay_t *handle, bool port, unsigned
|
|||
{
|
||||
RARCH_ERR("Connection with host was cut.\n");
|
||||
msg_queue_clear(g_extern.msg_queue);
|
||||
msg_queue_push(g_extern.msg_queue, "Connection with host was cut.", 1, 180);
|
||||
msg_queue_push(g_extern.msg_queue,
|
||||
"Connection with host was cut.", 1, 180);
|
||||
|
||||
pretro_set_input_state(g_extern.netplay->cbs.state_cb);
|
||||
return g_extern.netplay->cbs.state_cb(port, device, index, id);
|
||||
}
|
||||
}
|
||||
|
||||
int16_t input_state_spectate_client(unsigned port, unsigned device, unsigned index, unsigned id)
|
||||
int16_t input_state_spectate_client(unsigned port, unsigned device,
|
||||
unsigned index, unsigned id)
|
||||
{
|
||||
return netplay_get_spectate_input(g_extern.netplay, port, device, index, id);
|
||||
return netplay_get_spectate_input(g_extern.netplay, port,
|
||||
device, index, id);
|
||||
}
|
||||
|
||||
static void netplay_pre_frame_spectate(netplay_t *handle)
|
||||
|
@ -1317,7 +1363,7 @@ static void netplay_pre_frame_spectate(netplay_t *handle)
|
|||
}
|
||||
}
|
||||
|
||||
// No vacant client streams :(
|
||||
/* No vacant client streams :( */
|
||||
if (index == -1)
|
||||
{
|
||||
close(new_fd);
|
||||
|
@ -1339,7 +1385,9 @@ static void netplay_pre_frame_spectate(netplay_t *handle)
|
|||
}
|
||||
|
||||
size_t header_size;
|
||||
uint32_t *header = bsv_header_generate(&header_size, implementation_magic_value());
|
||||
uint32_t *header = bsv_header_generate(&header_size,
|
||||
implementation_magic_value());
|
||||
|
||||
if (!header)
|
||||
{
|
||||
RARCH_ERR("Failed to generate BSV header.\n");
|
||||
|
@ -1348,7 +1396,8 @@ static void netplay_pre_frame_spectate(netplay_t *handle)
|
|||
}
|
||||
|
||||
int bufsize = header_size;
|
||||
setsockopt(new_fd, SOL_SOCKET, SO_SNDBUF, CONST_CAST &bufsize, sizeof(int));
|
||||
setsockopt(new_fd, SOL_SOCKET, SO_SNDBUF, CONST_CAST &bufsize,
|
||||
sizeof(int));
|
||||
|
||||
if (!send_all(new_fd, header, header_size))
|
||||
{
|
||||
|
@ -1378,15 +1427,17 @@ static void netplay_post_frame_net(netplay_t *handle)
|
|||
{
|
||||
handle->frame_count++;
|
||||
|
||||
// Nothing to do...
|
||||
/* Nothing to do... */
|
||||
if (handle->other_frame_count == handle->read_frame_count)
|
||||
return;
|
||||
|
||||
// Skip ahead if we predicted correctly. Skip until our simulation failed.
|
||||
/* Skip ahead if we predicted correctly.
|
||||
* Skip until our simulation failed. */
|
||||
while (handle->other_frame_count < handle->read_frame_count)
|
||||
{
|
||||
const struct delta_frame *ptr = &handle->buffer[handle->other_ptr];
|
||||
if ((ptr->simulated_input_state != ptr->real_input_state) && !ptr->used_real)
|
||||
if ((ptr->simulated_input_state != ptr->real_input_state)
|
||||
&& !ptr->used_real)
|
||||
break;
|
||||
handle->other_ptr = NEXT_PTR(handle->other_ptr);
|
||||
handle->other_frame_count++;
|
||||
|
@ -1394,16 +1445,18 @@ static void netplay_post_frame_net(netplay_t *handle)
|
|||
|
||||
if (handle->other_frame_count < handle->read_frame_count)
|
||||
{
|
||||
// Replay frames
|
||||
/* Replay frames. */
|
||||
handle->is_replay = true;
|
||||
handle->tmp_ptr = handle->other_ptr;
|
||||
handle->tmp_frame_count = handle->other_frame_count;
|
||||
|
||||
pretro_unserialize(handle->buffer[handle->other_ptr].state, handle->state_size);
|
||||
pretro_unserialize(handle->buffer[handle->other_ptr].state,
|
||||
handle->state_size);
|
||||
bool first = true;
|
||||
while (first || (handle->tmp_ptr != handle->self_ptr))
|
||||
{
|
||||
pretro_serialize(handle->buffer[handle->tmp_ptr].state, handle->state_size);
|
||||
pretro_serialize(handle->buffer[handle->tmp_ptr].state,
|
||||
handle->state_size);
|
||||
#if defined(HAVE_THREADS) && !defined(RARCH_CONSOLE)
|
||||
lock_autosave();
|
||||
#endif
|
||||
|
@ -1434,7 +1487,8 @@ static void netplay_post_frame_spectate(netplay_t *handle)
|
|||
continue;
|
||||
|
||||
if (!send_all(handle->spectate_fds[i],
|
||||
handle->spectate_input, handle->spectate_input_ptr * sizeof(int16_t)))
|
||||
handle->spectate_input,
|
||||
handle->spectate_input_ptr * sizeof(int16_t)))
|
||||
{
|
||||
RARCH_LOG("Client (#%u) disconnected ...\n", i);
|
||||
|
||||
|
@ -1451,7 +1505,7 @@ static void netplay_post_frame_spectate(netplay_t *handle)
|
|||
handle->spectate_input_ptr = 0;
|
||||
}
|
||||
|
||||
// Here we check if we have new input and replay from recorded input.
|
||||
/* Here we check if we have new input and replay from recorded input. */
|
||||
void netplay_post_frame(netplay_t *handle)
|
||||
{
|
||||
if (handle->spectate)
|
||||
|
@ -1473,11 +1527,11 @@ void netplay_post_frame(netplay_t *handle)
|
|||
|
||||
#define addrinfo addrinfo_rarch__
|
||||
|
||||
// Yes, we love shitty implementations, don't we? :(
|
||||
/* Yes, we love shitty implementations, don't we? :( */
|
||||
#ifdef _XBOX
|
||||
struct hostent
|
||||
{
|
||||
char **h_addr_list; // Just do the minimal needed ...
|
||||
char **h_addr_list; /* Just do the minimal needed ... */
|
||||
};
|
||||
|
||||
static struct hostent *gethostbyname(const char *name)
|
||||
|
@ -1527,7 +1581,8 @@ int getaddrinfo_rarch__(const char *node, const char *service,
|
|||
info->ai_family = AF_INET;
|
||||
info->ai_socktype = hints->ai_socktype;
|
||||
|
||||
struct sockaddr_in *in_addr = (struct sockaddr_in*)calloc(1, sizeof(*in_addr));
|
||||
struct sockaddr_in *in_addr = (struct sockaddr_in*)
|
||||
calloc(1, sizeof(*in_addr));
|
||||
if (!in_addr)
|
||||
{
|
||||
free(info);
|
||||
|
|
28
netplay.h
28
netplay.h
|
@ -23,13 +23,22 @@
|
|||
#include "libretro.h"
|
||||
|
||||
void input_poll_net(void);
|
||||
int16_t input_state_net(unsigned port, unsigned device, unsigned index, unsigned id);
|
||||
void video_frame_net(const void *data, unsigned width, unsigned height, size_t pitch);
|
||||
|
||||
int16_t input_state_net(unsigned port, unsigned device,
|
||||
unsigned index, unsigned id);
|
||||
|
||||
void video_frame_net(const void *data, unsigned width,
|
||||
unsigned height, size_t pitch);
|
||||
|
||||
void audio_sample_net(int16_t left, int16_t right);
|
||||
|
||||
size_t audio_sample_batch_net(const int16_t *data, size_t frames);
|
||||
|
||||
int16_t input_state_spectate(unsigned port, unsigned device, unsigned index, unsigned id);
|
||||
int16_t input_state_spectate_client(unsigned port, unsigned device, unsigned index, unsigned id);
|
||||
int16_t input_state_spectate(unsigned port, unsigned device,
|
||||
unsigned index, unsigned id);
|
||||
|
||||
int16_t input_state_spectate_client(unsigned port, unsigned device,
|
||||
unsigned index, unsigned id);
|
||||
|
||||
typedef struct netplay netplay_t;
|
||||
|
||||
|
@ -43,19 +52,22 @@ struct retro_callbacks
|
|||
|
||||
bool netplay_init_network(void);
|
||||
|
||||
// Creates a new netplay handle. A NULL host means we're hosting (player 1). :)
|
||||
/* Creates a new netplay handle. A NULL host means we're
|
||||
* hosting (player 1). :) */
|
||||
netplay_t *netplay_new(const char *server,
|
||||
uint16_t port, unsigned frames,
|
||||
const struct retro_callbacks *cb, bool spectate,
|
||||
const char *nick);
|
||||
|
||||
void netplay_free(netplay_t *handle);
|
||||
|
||||
// On regular netplay, flip who controls player 1 and 2.
|
||||
/* On regular netplay, flip who controls player 1 and 2. */
|
||||
void netplay_flip_players(netplay_t *handle);
|
||||
|
||||
// Call this before running retro_run()
|
||||
/* Call this before running retro_run(). */
|
||||
void netplay_pre_frame(netplay_t *handle);
|
||||
// Call this after running retro_run()
|
||||
|
||||
/* Call this after running retro_run(). */
|
||||
void netplay_post_frame(netplay_t *handle);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,11 +37,18 @@ extern unsigned perf_ptr_rarch;
|
|||
extern unsigned perf_ptr_libretro;
|
||||
|
||||
retro_perf_tick_t rarch_get_perf_counter(void);
|
||||
|
||||
retro_time_t rarch_get_time_usec(void);
|
||||
|
||||
void rarch_perf_register(struct retro_perf_counter *perf);
|
||||
void retro_perf_register(struct retro_perf_counter *perf); // Same as rarch_perf_register, just for libretro cores.
|
||||
|
||||
/* Same as rarch_perf_register, just for libretro cores. */
|
||||
void retro_perf_register(struct retro_perf_counter *perf);
|
||||
|
||||
void retro_perf_clear(void);
|
||||
|
||||
void rarch_perf_log(void);
|
||||
|
||||
void retro_perf_log(void);
|
||||
|
||||
static inline void rarch_perf_start(struct retro_perf_counter *perf)
|
||||
|
@ -62,7 +69,7 @@ static inline void rarch_perf_stop(struct retro_perf_counter *perf)
|
|||
uint64_t rarch_get_cpu_features(void);
|
||||
unsigned rarch_get_cpu_cores(void);
|
||||
|
||||
// Used internally by RetroArch.
|
||||
/* Used internally by RetroArch. */
|
||||
#define RARCH_PERFORMANCE_INIT(X) \
|
||||
static struct retro_perf_counter X = {#X}; \
|
||||
do { \
|
||||
|
|
12
thread.c
12
thread.c
|
@ -178,7 +178,8 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us)
|
|||
slock_unlock(lock);
|
||||
DWORD res = WaitForSingleObject(cond->event, (DWORD)(timeout_us) / 1000);
|
||||
#else
|
||||
DWORD res = SignalObjectAndWait(lock->lock, cond->event, (DWORD)(timeout_us) / 1000, FALSE);
|
||||
DWORD res = SignalObjectAndWait(lock->lock, cond->event,
|
||||
(DWORD)(timeout_us) / 1000, FALSE);
|
||||
#endif
|
||||
|
||||
slock_lock(lock);
|
||||
|
@ -190,7 +191,8 @@ void scond_signal(scond_t *cond)
|
|||
SetEvent(cond->event);
|
||||
}
|
||||
|
||||
/* FIXME - check how this function should differ from scond_signal implementation */
|
||||
/* FIXME - check how this function should differ
|
||||
* from scond_signal implementation. */
|
||||
int scond_broadcast(scond_t *cond)
|
||||
{
|
||||
SetEvent(cond->event);
|
||||
|
@ -331,7 +333,8 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us)
|
|||
{
|
||||
struct timespec now = {0};
|
||||
|
||||
#ifdef __MACH__ // OSX doesn't have clock_gettime ... :(
|
||||
#ifdef __MACH__
|
||||
/* OSX doesn't have clock_gettime. */
|
||||
clock_serv_t cclock;
|
||||
mach_timespec_t mts;
|
||||
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
|
||||
|
@ -350,7 +353,8 @@ bool scond_wait_timeout(scond_t *cond, slock_t *lock, int64_t timeout_us)
|
|||
gettimeofday(&tm, NULL);
|
||||
now.tv_sec = tm.tv_sec;
|
||||
now.tv_nsec = tm.tv_usec * 1000;
|
||||
#elif !defined(GEKKO) // timeout on libogc is duration, not end time
|
||||
#elif !defined(GEKKO)
|
||||
/* timeout on libogc is duration, not end time. */
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue