mirror of
https://github.com/libretro/RetroArch.git
synced 2025-04-02 10:51:52 -04:00
updated with upstream
This commit is contained in:
commit
bc8b75148e
113 changed files with 1857 additions and 1737 deletions
|
@ -204,7 +204,7 @@ OBJ += frontend/frontend.o \
|
|||
movie.o \
|
||||
record/record_driver.o \
|
||||
record/drivers/record_null.o \
|
||||
performance.o \
|
||||
libretro-common/features/features_cpu.o \
|
||||
performance_counters.o \
|
||||
verbosity.o
|
||||
|
||||
|
@ -291,8 +291,11 @@ ifeq ($(HAVE_OSS_BSD), 1)
|
|||
endif
|
||||
|
||||
ifeq ($(HAVE_ALSA), 1)
|
||||
OBJ += audio/drivers/alsa.o \
|
||||
audio/drivers/alsathread.o
|
||||
OBJ += audio/drivers/alsa.o
|
||||
|
||||
ifeq ($(HAVE_THREADS), 1)
|
||||
OBJ += audio/drivers/alsathread.o
|
||||
endif
|
||||
LIBS += $(ALSA_LIBS)
|
||||
DEFINES += $(ALSA_CFLAGS)
|
||||
endif
|
||||
|
@ -575,11 +578,13 @@ ifeq ($(HAVE_UDEV), 1)
|
|||
endif
|
||||
|
||||
ifeq ($(HAVE_LIBUSB), 1)
|
||||
ifeq ($(HAVE_THREADS), 1)
|
||||
DEFINES += -DHAVE_LIBUSB
|
||||
OBJ += input/drivers_hid/libusb_hid.o
|
||||
LIBS += -lusb-1.0
|
||||
HAVE_HID = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_IOHIDMANAGER), 1)
|
||||
DEFINES += -DHAVE_IOHIDMANAGER
|
||||
|
@ -885,7 +890,6 @@ ifeq ($(HAVE_ZLIB), 1)
|
|||
tasks/task_decompress.o
|
||||
OBJ += $(ZLIB_OBJS)
|
||||
DEFINES += -DHAVE_ZLIB
|
||||
HAVE_RPNG = 1
|
||||
HAVE_COMPRESSION = 1
|
||||
ifeq ($(WANT_ZLIB), 1)
|
||||
DEFINES += -DWANT_ZLIB
|
||||
|
@ -895,19 +899,24 @@ ifeq ($(HAVE_ZLIB), 1)
|
|||
endif
|
||||
endif
|
||||
|
||||
ifdef HAVE_RPNG
|
||||
DEFINES += -DHAVE_RPNG
|
||||
endif
|
||||
|
||||
ifeq ($(HAVE_RPNG), 1)
|
||||
DEFINES += -DHAVE_RPNG
|
||||
OBJ += libretro-common/formats/png/rpng.o \
|
||||
libretro-common/formats/png/rpng_encode.o
|
||||
endif
|
||||
OBJ += libretro-common/formats/jpeg/rjpeg.o \
|
||||
libretro-common/formats/bmp/rbmp_encode.o \
|
||||
libretro-common/formats/tga/rtga.o \
|
||||
|
||||
ifeq ($(HAVE_RJPEG), 1)
|
||||
DEFINES += -DHAVE_RJPEG
|
||||
OBJ += libretro-common/formats/jpeg/rjpeg.o
|
||||
endif
|
||||
|
||||
OBJ += libretro-common/formats/bmp/rbmp_encode.o \
|
||||
libretro-common/formats/json/jsonsax.o
|
||||
|
||||
ifeq ($(HAVE_RTGA), 1)
|
||||
OBJ += libretro-common/formats/tga/rtga.o
|
||||
endif
|
||||
|
||||
ifdef HAVE_COMPRESSION
|
||||
DEFINES += -DHAVE_COMPRESSION
|
||||
endif
|
||||
|
|
|
@ -93,7 +93,7 @@ typedef struct audio_driver_input_data
|
|||
static const audio_driver_t *audio_drivers[] = {
|
||||
#ifdef HAVE_ALSA
|
||||
&audio_alsa,
|
||||
#ifndef __QNX__
|
||||
#if !defined(__QNX__) && defined(HAVE_THREADS)
|
||||
&audio_alsathread,
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -23,13 +23,13 @@
|
|||
|
||||
#include <file/file_path.h>
|
||||
#include <lists/dir_list.h>
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#include "audio_dsp_filter.h"
|
||||
#include "audio_filters/dspfilter.h"
|
||||
|
||||
#include "../config_file_userdata.h"
|
||||
#include "../frontend/frontend_driver.h"
|
||||
#include "../performance.h"
|
||||
#include "../performance_counters.h"
|
||||
#include "../dynamic.h"
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <string/stdstring.h>
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#include "audio_resampler_driver.h"
|
||||
#include "../config_file_userdata.h"
|
||||
#ifdef RARCH_INTERNAL
|
||||
#include "../performance.h"
|
||||
#include "../performance_counters.h"
|
||||
#endif
|
||||
#ifndef DONT_HAVE_STRING_LIST
|
||||
|
@ -142,11 +142,7 @@ retro_get_cpu_features_t perf_get_cpu_features_cb;
|
|||
|
||||
static resampler_simd_mask_t resampler_get_cpu_features(void)
|
||||
{
|
||||
#ifdef RARCH_INTERNAL
|
||||
return cpu_features_get();
|
||||
#else
|
||||
return perf_get_cpu_features_cb();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,12 +22,13 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
#include <boolean.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <boolean.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#define RESAMPLER_SIMD_SSE (1 << 0)
|
||||
#define RESAMPLER_SIMD_SSE2 (1 << 1)
|
||||
|
@ -200,10 +201,6 @@ bool rarch_resampler_realloc(void **re, const rarch_resampler_t **backend,
|
|||
(backend)->process(handle, data); \
|
||||
} while(0)
|
||||
|
||||
#ifndef RARCH_INTERNAL
|
||||
#include "libretro.h"
|
||||
extern retro_get_cpu_features_t perf_get_cpu_features_cb;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -13,18 +13,18 @@
|
|||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <boolean.h>
|
||||
#include "audio_utils.h"
|
||||
|
||||
#if defined(__SSE2__)
|
||||
#include <emmintrin.h>
|
||||
#elif defined(__ALTIVEC__)
|
||||
#include <altivec.h>
|
||||
#endif
|
||||
|
||||
#include <boolean.h>
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#include "audio_utils.h"
|
||||
|
||||
#ifdef RARCH_INTERNAL
|
||||
#include "../performance.h"
|
||||
#include "../performance_counters.h"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -41,8 +41,10 @@ typedef struct jack
|
|||
bool nonblock;
|
||||
bool is_paused;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
scond_t *cond;
|
||||
slock_t *cond_lock;
|
||||
#endif
|
||||
size_t buffer_size;
|
||||
} jack_t;
|
||||
|
||||
|
@ -54,7 +56,9 @@ static int process_cb(jack_nframes_t nframes, void *data)
|
|||
|
||||
if (nframes <= 0)
|
||||
{
|
||||
#ifdef HAVE_THREADS
|
||||
scond_signal(jd->cond);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -74,7 +78,9 @@ static int process_cb(jack_nframes_t nframes, void *data)
|
|||
for (f = min_avail; f < nframes; f++)
|
||||
out[f] = 0.0f;
|
||||
}
|
||||
#ifdef HAVE_THREADS
|
||||
scond_signal(jd->cond);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -86,7 +92,9 @@ static void shutdown_cb(void *data)
|
|||
return;
|
||||
|
||||
jd->shutdown = true;
|
||||
#ifdef HAVE_THREADS
|
||||
scond_signal(jd->cond);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int parse_ports(char **dest_ports, const char **jports)
|
||||
|
@ -149,8 +157,10 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency)
|
|||
if (!jd)
|
||||
return NULL;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
jd->cond = scond_new();
|
||||
jd->cond_lock = slock_new();
|
||||
#endif
|
||||
|
||||
jd->client = jack_client_open("RetroArch", JackNullOption, NULL);
|
||||
if (jd->client == NULL)
|
||||
|
@ -258,12 +268,14 @@ static size_t write_buffer(jack_t *jd, const float *buf, size_t size)
|
|||
}
|
||||
written += write_frames;
|
||||
}
|
||||
#ifdef HAVE_THREADS
|
||||
else
|
||||
{
|
||||
slock_lock(jd->cond_lock);
|
||||
scond_wait(jd->cond, jd->cond_lock);
|
||||
slock_unlock(jd->cond_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (jd->nonblock)
|
||||
break;
|
||||
|
@ -327,10 +339,12 @@ static void ja_free(void *data)
|
|||
if (jd->buffer[i] != NULL)
|
||||
jack_ringbuffer_free(jd->buffer[i]);
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
if (jd->cond_lock)
|
||||
slock_free(jd->cond_lock);
|
||||
if (jd->cond)
|
||||
scond_free(jd->cond);
|
||||
#endif
|
||||
free(jd);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,10 @@ typedef struct sdl_audio
|
|||
bool nonblock;
|
||||
bool is_paused;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
slock_t *lock;
|
||||
scond_t *cond;
|
||||
#endif
|
||||
fifo_buffer_t *buffer;
|
||||
} sdl_audio_t;
|
||||
|
||||
|
@ -47,7 +49,9 @@ static void sdl_audio_cb(void *data, Uint8 *stream, int len)
|
|||
size_t write_size = len > (int)avail ? avail : len;
|
||||
|
||||
fifo_read(sdl->buffer, stream, write_size);
|
||||
#ifdef HAVE_THREADS
|
||||
scond_signal(sdl->cond);
|
||||
#endif
|
||||
|
||||
/* If underrun, fill rest with silence. */
|
||||
memset(stream + write_size, 0, len - write_size);
|
||||
|
@ -109,8 +113,10 @@ static void *sdl_audio_init(const char *device,
|
|||
|
||||
settings->audio.out_rate = out.freq;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
sdl->lock = slock_new();
|
||||
sdl->cond = scond_new();
|
||||
#endif
|
||||
|
||||
RARCH_LOG("SDL audio: Requested %u ms latency, got %d ms\n",
|
||||
latency, (int)(out.samples * 4 * 1000 / settings->audio.out_rate));
|
||||
|
@ -160,9 +166,11 @@ static ssize_t sdl_audio_write(void *data, const void *buf, size_t size)
|
|||
if (avail == 0)
|
||||
{
|
||||
SDL_UnlockAudio();
|
||||
#ifdef HAVE_THREADS
|
||||
slock_lock(sdl->lock);
|
||||
scond_wait(sdl->cond, sdl->lock);
|
||||
slock_unlock(sdl->lock);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -220,8 +228,10 @@ static void sdl_audio_free(void *data)
|
|||
if (sdl)
|
||||
{
|
||||
fifo_free(sdl->buffer);
|
||||
#ifdef HAVE_THREADS
|
||||
slock_free(sdl->lock);
|
||||
scond_free(sdl->cond);
|
||||
#endif
|
||||
}
|
||||
free(sdl);
|
||||
}
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
#define __CAMERA_DRIVER__H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include "../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
@ -20,8 +20,10 @@
|
|||
#include <streams/file_stream.h>
|
||||
#include <rhash.h>
|
||||
#include <rthreads/async_job.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "cheevos.h"
|
||||
#include "command.h"
|
||||
#include "dynamic.h"
|
||||
#include "libretro.h"
|
||||
#include "system.h"
|
||||
|
|
176
command.c
176
command.c
|
@ -70,6 +70,7 @@
|
|||
|
||||
#ifdef HAVE_MENU
|
||||
#include "menu/menu_driver.h"
|
||||
#include "menu/menu_content.h"
|
||||
#include "menu/menu_display.h"
|
||||
#include "menu/menu_shader.h"
|
||||
#endif
|
||||
|
@ -200,40 +201,6 @@ static const struct cmd_map map[] = {
|
|||
{ "MENU_B", RETRO_DEVICE_ID_JOYPAD_B },
|
||||
};
|
||||
|
||||
#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY)
|
||||
static bool command_network_init(command_t *handle, uint16_t port)
|
||||
{
|
||||
int fd;
|
||||
struct addrinfo *res = NULL;
|
||||
|
||||
RARCH_LOG("Bringing up command interface on port %hu.\n",
|
||||
(unsigned short)port);
|
||||
|
||||
fd = socket_init((void**)&res, port, NULL, SOCKET_TYPE_DATAGRAM);
|
||||
|
||||
if (fd < 0)
|
||||
goto error;
|
||||
|
||||
handle->net_fd = fd;
|
||||
|
||||
if (!socket_nonblock(handle->net_fd))
|
||||
goto error;
|
||||
|
||||
if (!socket_bind(handle->net_fd, (void*)res))
|
||||
{
|
||||
RARCH_ERR("Failed to bind socket.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
freeaddrinfo_retro(res);
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (res)
|
||||
freeaddrinfo_retro(res);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool command_get_arg(const char *tok,
|
||||
const char **arg, unsigned *index)
|
||||
{
|
||||
|
@ -275,6 +242,75 @@ static bool command_get_arg(const char *tok,
|
|||
return false;
|
||||
}
|
||||
|
||||
static void command_parse_sub_msg(command_t *handle, const char *tok)
|
||||
{
|
||||
const char *arg = NULL;
|
||||
unsigned index = 0;
|
||||
|
||||
if (command_get_arg(tok, &arg, &index))
|
||||
{
|
||||
if (arg)
|
||||
{
|
||||
if (!action_map[index].action(arg))
|
||||
RARCH_ERR("Command \"%s\" failed.\n", arg);
|
||||
}
|
||||
else
|
||||
handle->state[map[index].id] = true;
|
||||
}
|
||||
else
|
||||
RARCH_WARN("%s \"%s\" %s.\n",
|
||||
msg_hash_to_str(MSG_UNRECOGNIZED_COMMAND),
|
||||
tok,
|
||||
msg_hash_to_str(MSG_RECEIVED));
|
||||
}
|
||||
|
||||
static void command_parse_msg(command_t *handle, char *buf)
|
||||
{
|
||||
char *save = NULL;
|
||||
const char *tok = strtok_r(buf, "\n", &save);
|
||||
|
||||
while (tok)
|
||||
{
|
||||
command_parse_sub_msg(handle, tok);
|
||||
tok = strtok_r(NULL, "\n", &save);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_NETWORK_CMD) && defined(HAVE_NETPLAY)
|
||||
static bool command_network_init(command_t *handle, uint16_t port)
|
||||
{
|
||||
int fd;
|
||||
struct addrinfo *res = NULL;
|
||||
|
||||
RARCH_LOG("Bringing up command interface on port %hu.\n",
|
||||
(unsigned short)port);
|
||||
|
||||
fd = socket_init((void**)&res, port, NULL, SOCKET_TYPE_DATAGRAM);
|
||||
|
||||
if (fd < 0)
|
||||
goto error;
|
||||
|
||||
handle->net_fd = fd;
|
||||
|
||||
if (!socket_nonblock(handle->net_fd))
|
||||
goto error;
|
||||
|
||||
if (!socket_bind(handle->net_fd, (void*)res))
|
||||
{
|
||||
RARCH_ERR("Failed to bind socket.\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
freeaddrinfo_retro(res);
|
||||
return true;
|
||||
|
||||
error:
|
||||
if (res)
|
||||
freeaddrinfo_retro(res);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static bool send_udp_packet(const char *host,
|
||||
uint16_t port, const char *msg)
|
||||
|
@ -389,39 +425,6 @@ bool command_network_send(const char *cmd_)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void command_parse_sub_msg(command_t *handle, const char *tok)
|
||||
{
|
||||
const char *arg = NULL;
|
||||
unsigned index = 0;
|
||||
|
||||
if (command_get_arg(tok, &arg, &index))
|
||||
{
|
||||
if (arg)
|
||||
{
|
||||
if (!action_map[index].action(arg))
|
||||
RARCH_ERR("Command \"%s\" failed.\n", arg);
|
||||
}
|
||||
else
|
||||
handle->state[map[index].id] = true;
|
||||
}
|
||||
else
|
||||
RARCH_WARN("%s \"%s\" %s.\n",
|
||||
msg_hash_to_str(MSG_UNRECOGNIZED_COMMAND),
|
||||
tok,
|
||||
msg_hash_to_str(MSG_RECEIVED));
|
||||
}
|
||||
|
||||
static void command_parse_msg(command_t *handle, char *buf)
|
||||
{
|
||||
char *save = NULL;
|
||||
const char *tok = strtok_r(buf, "\n", &save);
|
||||
|
||||
while (tok)
|
||||
{
|
||||
command_parse_sub_msg(handle, tok);
|
||||
tok = strtok_r(NULL, "\n", &save);
|
||||
}
|
||||
}
|
||||
|
||||
static void command_network_poll(command_t *handle)
|
||||
{
|
||||
|
@ -869,8 +872,8 @@ static bool command_event_disk_control_append_image(const char *path)
|
|||
* If we actually use append_image, we assume that we
|
||||
* started out in a single disk case, and that this way
|
||||
* of doing it makes the most sense. */
|
||||
rarch_ctl(RARCH_CTL_SET_PATHS, (void*)path);
|
||||
rarch_ctl(RARCH_CTL_FILL_PATHNAMES, NULL);
|
||||
retroarch_set_pathnames(path);
|
||||
retroarch_fill_pathnames();
|
||||
}
|
||||
|
||||
command_event(CMD_EVENT_AUTOSAVE_INIT, NULL);
|
||||
|
@ -1204,7 +1207,7 @@ static bool event_init_content(void)
|
|||
return true;
|
||||
|
||||
if (!content_does_not_need_content())
|
||||
rarch_ctl(RARCH_CTL_FILL_PATHNAMES, NULL);
|
||||
retroarch_fill_pathnames();
|
||||
|
||||
if (!content_init())
|
||||
return false;
|
||||
|
@ -1559,8 +1562,13 @@ static bool command_event_cmd_exec(void *data)
|
|||
}
|
||||
|
||||
#if defined(HAVE_DYNAMIC)
|
||||
if (!rarch_ctl(RARCH_CTL_LOAD_CONTENT, NULL))
|
||||
#ifdef HAVE_MENU
|
||||
if (!menu_content_ctl(MENU_CONTENT_CTL_LOAD, NULL))
|
||||
{
|
||||
rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
frontend_driver_set_fork(FRONTEND_FORK_CORE_WITH_ARGS);
|
||||
#endif
|
||||
|
@ -1620,15 +1628,16 @@ bool command_event(enum event_command cmd, void *data)
|
|||
#ifdef HAVE_DYNAMIC
|
||||
command_event(CMD_EVENT_LOAD_CORE, NULL);
|
||||
#endif
|
||||
rarch_ctl(RARCH_CTL_LOAD_CONTENT, NULL);
|
||||
break;
|
||||
#ifdef HAVE_FFMPEG
|
||||
/* fall-through */
|
||||
case CMD_EVENT_LOAD_CONTENT_FFMPEG:
|
||||
rarch_ctl(RARCH_CTL_LOAD_CONTENT_FFMPEG, NULL);
|
||||
break;
|
||||
#endif
|
||||
case CMD_EVENT_LOAD_CONTENT_IMAGEVIEWER:
|
||||
rarch_ctl(RARCH_CTL_LOAD_CONTENT_IMAGEVIEWER, NULL);
|
||||
#ifdef HAVE_MENU
|
||||
if (!menu_content_ctl(MENU_CONTENT_CTL_LOAD, NULL))
|
||||
{
|
||||
rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case CMD_EVENT_LOAD_CONTENT:
|
||||
{
|
||||
|
@ -1766,11 +1775,11 @@ bool command_event(enum event_command cmd, void *data)
|
|||
return false;
|
||||
break;
|
||||
case CMD_EVENT_UNLOAD_CORE:
|
||||
runloop_ctl(RUNLOOP_CTL_PREPARE_DUMMY, NULL);
|
||||
runloop_prepare_dummy();
|
||||
command_event(CMD_EVENT_LOAD_CORE_DEINIT, NULL);
|
||||
break;
|
||||
case CMD_EVENT_QUIT:
|
||||
rarch_ctl(RARCH_CTL_QUIT, NULL);
|
||||
retroarch_main_quit();
|
||||
break;
|
||||
case CMD_EVENT_CHEEVOS_HARDCORE_MODE_TOGGLE:
|
||||
#ifdef HAVE_CHEEVOS
|
||||
|
@ -2024,20 +2033,17 @@ bool command_event(enum event_command cmd, void *data)
|
|||
driver_ctl(RARCH_DRIVER_CTL_INIT, &flags);
|
||||
}
|
||||
break;
|
||||
case CMD_EVENT_QUIT_RETROARCH:
|
||||
rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL);
|
||||
break;
|
||||
case CMD_EVENT_SHUTDOWN:
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
runloop_msg_queue_push("Shutting down...", 1, 180, true);
|
||||
rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL);
|
||||
command_event(CMD_EVENT_QUIT, NULL);
|
||||
system("shutdown -P now");
|
||||
#endif
|
||||
break;
|
||||
case CMD_EVENT_REBOOT:
|
||||
#if defined(__linux__) && !defined(ANDROID)
|
||||
runloop_msg_queue_push("Rebooting...", 1, 180, true);
|
||||
rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL);
|
||||
command_event(CMD_EVENT_QUIT, NULL);
|
||||
system("shutdown -r now");
|
||||
#endif
|
||||
break;
|
||||
|
|
|
@ -44,9 +44,7 @@ enum event_command
|
|||
/* Loads content file. */
|
||||
CMD_EVENT_LOAD_CONTENT,
|
||||
CMD_EVENT_LOAD_CONTENT_PERSIST,
|
||||
#ifdef HAVE_FFMPEG
|
||||
CMD_EVENT_LOAD_CONTENT_FFMPEG,
|
||||
#endif
|
||||
CMD_EVENT_LOAD_CONTENT_IMAGEVIEWER,
|
||||
CMD_EVENT_SET_PER_GAME_RESOLUTION,
|
||||
CMD_EVENT_SET_FRAME_LIMIT,
|
||||
|
@ -131,8 +129,6 @@ enum event_command
|
|||
CMD_EVENT_RESET_CONTEXT,
|
||||
/* Restarts RetroArch. */
|
||||
CMD_EVENT_RESTART_RETROARCH,
|
||||
/* Force-quit RetroArch. */
|
||||
CMD_EVENT_QUIT_RETROARCH,
|
||||
/* Shutdown the OS */
|
||||
CMD_EVENT_SHUTDOWN,
|
||||
/* Reboot the OS */
|
||||
|
|
10
content.c
10
content.c
|
@ -90,6 +90,14 @@ struct sram_block
|
|||
size_t size;
|
||||
};
|
||||
|
||||
typedef struct content_stream
|
||||
{
|
||||
uint32_t a;
|
||||
const uint8_t *b;
|
||||
size_t c;
|
||||
uint32_t crc;
|
||||
} content_stream_t;
|
||||
|
||||
static const struct file_archive_file_backend *stream_backend = NULL;
|
||||
static struct string_list *temporary_content = NULL;
|
||||
static bool _content_is_inited = false;
|
||||
|
@ -892,7 +900,7 @@ bool content_load(content_ctx_info_t *info)
|
|||
wrap_args->argc = *rarch_argc_ptr;
|
||||
wrap_args->argv = rarch_argv_ptr;
|
||||
|
||||
if (!rarch_ctl(RARCH_CTL_MAIN_INIT, wrap_args))
|
||||
if (!retroarch_main_init(wrap_args->argc, wrap_args->argv))
|
||||
{
|
||||
retval = false;
|
||||
goto error;
|
||||
|
|
|
@ -36,14 +36,6 @@ typedef struct ram_type
|
|||
int type;
|
||||
} ram_type_t;
|
||||
|
||||
typedef struct content_stream
|
||||
{
|
||||
uint32_t a;
|
||||
const uint8_t *b;
|
||||
size_t c;
|
||||
uint32_t crc;
|
||||
} content_stream_t;
|
||||
|
||||
typedef struct content_ctx_info
|
||||
{
|
||||
int argc; /* Argument count. */
|
||||
|
|
2
core.h
2
core.h
|
@ -23,9 +23,9 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include <boolean.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "core_type.h"
|
||||
#include "libretro.h"
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
#include <retro_inline.h>
|
||||
#include <boolean.h>
|
||||
#include <lists/string_list.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "dynamic.h"
|
||||
#include "libretro.h"
|
||||
#include "core.h"
|
||||
#include "general.h"
|
||||
#include "msg_hash.h"
|
||||
|
|
|
@ -19,8 +19,9 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
#include "internal_cores.h"
|
||||
#include "../libretro.h"
|
||||
|
||||
static uint16_t *frame_buf;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#define INTERNAL_CORES_H__
|
||||
|
||||
#include <boolean.h>
|
||||
#include "../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
void libretro_dummy_retro_init(void);
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ extern "C" {
|
|||
#include <rthreads/rthreads.h>
|
||||
#include <queues/fifo_queue.h>
|
||||
|
||||
#include "libretro.h"
|
||||
#include <libretro.h>
|
||||
#ifdef RARCH_INTERNAL
|
||||
#include "internal_cores.h"
|
||||
#define CORE_PREFIX(s) libretro_ffmpeg_##s
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
#include "../../libretro.h"
|
|
@ -22,12 +22,12 @@
|
|||
|
||||
#include "../../deps/stb/stb_image.h"
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
#ifdef RARCH_INTERNAL
|
||||
#include "internal_cores.h"
|
||||
#include "../../libretro.h"
|
||||
#define IMAGE_CORE_PREFIX(s) libretro_imageviewer_##s
|
||||
#else
|
||||
#include "libretro.h"
|
||||
#define IMAGE_CORE_PREFIX(s) s
|
||||
#endif
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <glsym/glsym.h>
|
||||
|
||||
#include "../../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
static struct retro_hw_render_callback hw_render;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <glsym/glsym.h>
|
||||
|
||||
#include "../../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
static struct retro_hw_render_callback hw_render;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include "../../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
static uint32_t *frame_buf;
|
||||
static struct retro_log_callback logging;
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include "../../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
#ifndef SOCKET_ERROR
|
||||
#define SOCKET_ERROR -1
|
||||
|
|
1
deps/spir2cross
vendored
1
deps/spir2cross
vendored
|
@ -1 +0,0 @@
|
|||
Subproject commit 0ae2bcc3d0edc60e03180f6080a168f78edc82ca
|
1
driver.c
1
driver.c
|
@ -17,6 +17,7 @@
|
|||
#include <compat/posix_string.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "general.h"
|
||||
#include "msg_hash.h"
|
||||
#include "system.h"
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#include <string/stdstring.h>
|
||||
#include <retro_assert.h>
|
||||
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
@ -38,7 +40,6 @@
|
|||
#include "record/record_driver.h"
|
||||
#include "core.h"
|
||||
#include "performance_counters.h"
|
||||
#include "performance.h"
|
||||
#include "system.h"
|
||||
#include "gfx/video_context_driver.h"
|
||||
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
#define __DYNAMIC_H
|
||||
|
||||
#include <boolean.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "core_type.h"
|
||||
#include "libretro.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
|
|
|
@ -426,7 +426,7 @@ static bool frontend_gx_set_fork(enum frontend_fork fork_mode)
|
|||
case FRONTEND_FORK_RESTART:
|
||||
RARCH_LOG("FRONTEND_FORK_RESTART\n");
|
||||
gx_fork_mode = fork_mode;
|
||||
rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL);
|
||||
command_event(CMD_EVENT_QUIT, NULL);
|
||||
break;
|
||||
case FRONTEND_FORK_NONE:
|
||||
default:
|
||||
|
|
|
@ -51,396 +51,10 @@
|
|||
#include "../../verbosity.h"
|
||||
#include "platform_linux.h"
|
||||
|
||||
/* This small data type is used to represent a CPU list / mask,
|
||||
* as read from sysfs on Linux.
|
||||
*
|
||||
* See http://www.kernel.org/doc/Documentation/cputopology.txt
|
||||
*
|
||||
* For now, we don't expect more than 32 cores on mobile devices,
|
||||
* so keep everything simple.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t mask;
|
||||
} CpuList;
|
||||
|
||||
static bool cpu_inited_once;
|
||||
static enum cpu_family g_cpuFamily;
|
||||
static uint64_t g_cpuFeatures;
|
||||
static int g_cpuCount;
|
||||
|
||||
#ifndef HAVE_DYNAMIC
|
||||
static enum frontend_fork linux_fork_mode = FRONTEND_FORK_NONE;
|
||||
#endif
|
||||
|
||||
#ifdef __arm__
|
||||
# define DEFAULT_CPU_FAMILY CPU_FAMILY_ARM
|
||||
#elif defined __i386__
|
||||
# define DEFAULT_CPU_FAMILY CPU_FAMILY_X86
|
||||
#else
|
||||
# define DEFAULT_CPU_FAMILY CPU_FAMILY_UNKNOWN
|
||||
#endif
|
||||
|
||||
#ifdef __i386__
|
||||
void x86_cpuid(int func, int flags[4]);
|
||||
#endif
|
||||
|
||||
#ifdef __ARM_ARCH__
|
||||
/* Extract the content of a the first occurrence of a given field in
|
||||
* the content of /proc/cpuinfo and return it as a heap-allocated
|
||||
* string that must be freed by the caller.
|
||||
*
|
||||
* Return NULL if not found
|
||||
*/
|
||||
static char *extract_cpuinfo_field(char* buffer,
|
||||
ssize_t length, const char* field)
|
||||
{
|
||||
int len;
|
||||
const char *q;
|
||||
int fieldlen = strlen(field);
|
||||
char* bufend = buffer + length;
|
||||
char* result = NULL;
|
||||
/* Look for first field occurrence,
|
||||
* and ensures it starts the line. */
|
||||
const char *p = buffer;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
p = memmem(p, bufend-p, field, fieldlen);
|
||||
if (p == NULL)
|
||||
return result;
|
||||
|
||||
if (p == buffer || p[-1] == '\n')
|
||||
break;
|
||||
|
||||
p += fieldlen;
|
||||
}
|
||||
|
||||
/* Skip to the first column followed by a space */
|
||||
p += fieldlen;
|
||||
p = memchr(p, ':', bufend-p);
|
||||
if (p == NULL || p[1] != ' ')
|
||||
return result;
|
||||
|
||||
/* Find the end of the line */
|
||||
p += 2;
|
||||
q = memchr(p, '\n', bufend-p);
|
||||
if (q == NULL)
|
||||
q = bufend;
|
||||
|
||||
/* Copy the line into a heap-allocated buffer */
|
||||
len = q-p;
|
||||
result = malloc(len+1);
|
||||
if (result == NULL)
|
||||
return result;
|
||||
|
||||
memcpy(result, p, len);
|
||||
result[len] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Checks that a space-separated list of items
|
||||
* contains one given 'item'.
|
||||
* Returns 1 if found, 0 otherwise.
|
||||
*/
|
||||
static int has_list_item(const char* list, const char* item)
|
||||
{
|
||||
const char* p = list;
|
||||
int itemlen = strlen(item);
|
||||
|
||||
if (list == NULL)
|
||||
return 0;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
const char* q;
|
||||
|
||||
/* skip spaces */
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
|
||||
/* find end of current list item */
|
||||
q = p;
|
||||
while (*q && *q != ' ' && *q != '\t')
|
||||
q++;
|
||||
|
||||
if (itemlen == q-p && !memcmp(p, item, itemlen))
|
||||
return 1;
|
||||
|
||||
/* skip to next item */
|
||||
p = q;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Parse an decimal integer starting from 'input', but not going further
|
||||
* than 'limit'. Return the value into '*result'.
|
||||
*
|
||||
* NOTE: Does not skip over leading spaces, or deal with sign characters.
|
||||
* NOTE: Ignores overflows.
|
||||
*
|
||||
* The function returns NULL in case of error (bad format), or the new
|
||||
* position after the decimal number in case of success (which will always
|
||||
* be <= 'limit').
|
||||
*/
|
||||
static const char *parse_decimal(const char* input,
|
||||
const char* limit, int* result)
|
||||
{
|
||||
const char* p = input;
|
||||
int val = 0;
|
||||
|
||||
while (p < limit)
|
||||
{
|
||||
int d = (*p - '0');
|
||||
if ((unsigned)d >= 10U)
|
||||
break;
|
||||
val = val*10 + d;
|
||||
p++;
|
||||
}
|
||||
if (p == input)
|
||||
return NULL;
|
||||
|
||||
*result = val;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/* Parse a textual list of cpus and store the result inside a CpuList object.
|
||||
* Input format is the following:
|
||||
* - comma-separated list of items (no spaces)
|
||||
* - each item is either a single decimal number (cpu index), or a range made
|
||||
* of two numbers separated by a single dash (-). Ranges are inclusive.
|
||||
*
|
||||
* Examples: 0
|
||||
* 2,4-127,128-143
|
||||
* 0-1
|
||||
*/
|
||||
static void cpulist_parse(CpuList* list, char **buf, ssize_t length)
|
||||
{
|
||||
const char* p = (const char*)buf;
|
||||
const char* end = p + length;
|
||||
|
||||
/* NOTE: the input line coming from sysfs typically contains a
|
||||
* trailing newline, so take care of it in the code below
|
||||
*/
|
||||
while (p < end && *p != '\n')
|
||||
{
|
||||
int val, start_value, end_value;
|
||||
/* Find the end of current item, and put it into 'q' */
|
||||
const char *q = (const char*)memchr(p, ',', end-p);
|
||||
|
||||
if (!q)
|
||||
q = end;
|
||||
|
||||
/* Get first value */
|
||||
p = parse_decimal(p, q, &start_value);
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
end_value = start_value;
|
||||
|
||||
/* If we're not at the end of the item, expect a dash and
|
||||
* and integer; extract end value.
|
||||
*/
|
||||
if (p < q && *p == '-')
|
||||
{
|
||||
p = parse_decimal(p+1, q, &end_value);
|
||||
if (p == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set bits CPU list bits */
|
||||
for (val = start_value; val <= end_value; val++)
|
||||
{
|
||||
if ((unsigned)val < 32)
|
||||
list->mask |= (uint32_t)(1U << val);
|
||||
}
|
||||
|
||||
/* Jump to next item */
|
||||
p = q;
|
||||
if (p < end)
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a CPU list from one sysfs file */
|
||||
static void cpulist_read_from(CpuList* list, const char* filename)
|
||||
{
|
||||
ssize_t length;
|
||||
char *buf = NULL;
|
||||
|
||||
list->mask = 0;
|
||||
|
||||
if (filestream_read_file(filename, (void**)&buf, &length) != 1)
|
||||
{
|
||||
RARCH_ERR("Could not read %s: %s\n", filename, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
cpulist_parse(list, &buf, length);
|
||||
if (buf)
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
/* Return the number of cpus present on a given device.
|
||||
*
|
||||
* To handle all weird kernel configurations, we need to compute the
|
||||
* intersection of the 'present' and 'possible' CPU lists and count
|
||||
* the result.
|
||||
*/
|
||||
static int get_cpu_count(void)
|
||||
{
|
||||
CpuList cpus_present[1];
|
||||
CpuList cpus_possible[1];
|
||||
|
||||
cpulist_read_from(cpus_present, "/sys/devices/system/cpu/present");
|
||||
cpulist_read_from(cpus_possible, "/sys/devices/system/cpu/possible");
|
||||
|
||||
/* Compute the intersection of both sets to get the actual number of
|
||||
* CPU cores that can be used on this device by the kernel.
|
||||
*/
|
||||
cpus_present->mask &= cpus_possible->mask;
|
||||
|
||||
return __builtin_popcount(cpus_present->mask);
|
||||
}
|
||||
|
||||
static void linux_cpu_init(void)
|
||||
{
|
||||
ssize_t length;
|
||||
void *buf = NULL;
|
||||
|
||||
g_cpuFamily = DEFAULT_CPU_FAMILY;
|
||||
g_cpuFeatures = 0;
|
||||
g_cpuCount = 1;
|
||||
|
||||
if (filestream_read_file("/proc/cpuinfo", &buf, &length) != 1)
|
||||
return;
|
||||
|
||||
/* Count the CPU cores, the value may be 0 for single-core CPUs */
|
||||
g_cpuCount = get_cpu_count();
|
||||
if (g_cpuCount == 0)
|
||||
g_cpuCount = 1;
|
||||
|
||||
RARCH_LOG("found cpuCount = %d\n", g_cpuCount);
|
||||
|
||||
#ifdef __ARM_ARCH__
|
||||
/* Extract architecture from the "CPU Architecture" field.
|
||||
* The list is well-known, unlike the the output of
|
||||
* the 'Processor' field which can vary greatly.
|
||||
*
|
||||
* See the definition of the 'proc_arch' array in
|
||||
* $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in
|
||||
* same file.
|
||||
*/
|
||||
char* cpu_arch = extract_cpuinfo_field(buf, length, "CPU architecture");
|
||||
|
||||
if (cpu_arch)
|
||||
{
|
||||
char* end;
|
||||
int has_armv7 = 0;
|
||||
/* read the initial decimal number, ignore the rest */
|
||||
long arch_number = strtol(cpu_arch, &end, 10);
|
||||
|
||||
RARCH_LOG("Found CPU architecture = '%s'\n", cpu_arch);
|
||||
|
||||
/* Here we assume that ARMv8 will be upwards compatible with v7
|
||||
* in the future. Unfortunately, there is no 'Features' field to
|
||||
* indicate that Thumb-2 is supported.
|
||||
*/
|
||||
if (end > cpu_arch && arch_number >= 7)
|
||||
has_armv7 = 1;
|
||||
|
||||
/* Unfortunately, it seems that certain ARMv6-based CPUs
|
||||
* report an incorrect architecture number of 7!
|
||||
*
|
||||
* See http://code.google.com/p/android/issues/detail?id=10812
|
||||
*
|
||||
* We try to correct this by looking at the 'elf_format'
|
||||
* field reported by the 'Processor' field, which is of the
|
||||
* form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
|
||||
* an ARMv6-one.
|
||||
*/
|
||||
if (has_armv7)
|
||||
{
|
||||
char *cpu_proc = extract_cpuinfo_field(buf, length,
|
||||
"Processor");
|
||||
|
||||
if (cpu_proc != NULL)
|
||||
{
|
||||
RARCH_LOG("found cpu_proc = '%s'\n", cpu_proc);
|
||||
if (has_list_item(cpu_proc, "(v6l)"))
|
||||
{
|
||||
RARCH_ERR("CPU processor and architecture mismatch!!\n");
|
||||
has_armv7 = 0;
|
||||
}
|
||||
free(cpu_proc);
|
||||
}
|
||||
}
|
||||
|
||||
if (has_armv7)
|
||||
g_cpuFeatures |= CPU_ARM_FEATURE_ARMv7;
|
||||
|
||||
/* The LDREX / STREX instructions are available from ARMv6 */
|
||||
if (arch_number >= 6)
|
||||
g_cpuFeatures |= CPU_ARM_FEATURE_LDREX_STREX;
|
||||
|
||||
free(cpu_arch);
|
||||
}
|
||||
|
||||
/* Extract the list of CPU features from 'Features' field */
|
||||
char* cpu_features = extract_cpuinfo_field(buf, length, "Features");
|
||||
|
||||
if (cpu_features)
|
||||
{
|
||||
RARCH_LOG("found cpu_features = '%s'\n", cpu_features);
|
||||
|
||||
if (has_list_item(cpu_features, "vfpv3"))
|
||||
g_cpuFeatures |= CPU_ARM_FEATURE_VFPv3;
|
||||
|
||||
else if (has_list_item(cpu_features, "vfpv3d16"))
|
||||
g_cpuFeatures |= CPU_ARM_FEATURE_VFPv3;
|
||||
|
||||
/* Note: Certain kernels only report NEON but not VFPv3
|
||||
* in their features list. However, ARM mandates
|
||||
* that if NEON is implemented, so must be VFPv3
|
||||
* so always set the flag.
|
||||
*/
|
||||
if (has_list_item(cpu_features, "neon"))
|
||||
g_cpuFeatures |= CPU_ARM_FEATURE_NEON | CPU_ARM_FEATURE_VFPv3;
|
||||
free(cpu_features);
|
||||
}
|
||||
#endif /* __ARM_ARCH__ */
|
||||
|
||||
#ifdef __i386__
|
||||
g_cpuFamily = CPU_FAMILY_X86;
|
||||
#elif defined(_MIPS_ARCH)
|
||||
g_cpuFamily = CPU_FAMILY_MIPS;
|
||||
#endif
|
||||
|
||||
if (buf)
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
enum cpu_family linux_get_cpu_platform(void)
|
||||
{
|
||||
return g_cpuFamily;
|
||||
}
|
||||
|
||||
uint64_t linux_get_cpu_features(void)
|
||||
{
|
||||
return g_cpuFeatures;
|
||||
}
|
||||
|
||||
int linux_get_cpu_count(void)
|
||||
{
|
||||
return g_cpuCount;
|
||||
}
|
||||
|
||||
int system_property_get(const char *command,
|
||||
const char *args, char *value)
|
||||
{
|
||||
|
@ -2165,11 +1779,6 @@ static void frontend_linux_init(void *data)
|
|||
"getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
|
||||
#endif
|
||||
|
||||
if (!cpu_inited_once)
|
||||
{
|
||||
linux_cpu_init();
|
||||
cpu_inited_once = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
|
@ -2218,7 +1827,7 @@ static bool frontend_linux_set_fork(enum frontend_fork fork_mode)
|
|||
fill_pathname_application_path(executable_path, sizeof(executable_path));
|
||||
strlcpy(settings->path.libretro, executable_path, sizeof(settings->path.libretro));
|
||||
}
|
||||
rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL);
|
||||
command_event(CMD_EVENT_QUIT, NULL);
|
||||
break;
|
||||
case FRONTEND_FORK_NONE:
|
||||
default:
|
||||
|
|
|
@ -23,31 +23,6 @@
|
|||
|
||||
#include <boolean.h>
|
||||
|
||||
enum cpu_family
|
||||
{
|
||||
CPU_FAMILY_UNKNOWN = 0,
|
||||
CPU_FAMILY_ARM,
|
||||
CPU_FAMILY_X86,
|
||||
CPU_FAMILY_MIPS,
|
||||
|
||||
CPU_FAMILY_MAX /* do not remove */
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CPU_ARM_FEATURE_ARMv7 = (1 << 0),
|
||||
CPU_ARM_FEATURE_VFPv3 = (1 << 1),
|
||||
CPU_ARM_FEATURE_NEON = (1 << 2),
|
||||
CPU_ARM_FEATURE_LDREX_STREX = (1 << 3)
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CPU_X86_FEATURE_SSSE3 = (1 << 0),
|
||||
CPU_X86_FEATURE_POPCNT = (1 << 1),
|
||||
CPU_X86_FEATURE_MOVBE = (1 << 2)
|
||||
};
|
||||
|
||||
#ifndef MAX_PADS
|
||||
#define MAX_PADS 8
|
||||
#endif
|
||||
|
@ -56,12 +31,6 @@ enum
|
|||
#define MAX_AXIS 10
|
||||
#endif
|
||||
|
||||
enum cpu_family linux_get_cpu_family(void);
|
||||
|
||||
uint64_t linux_get_cpu_features(void);
|
||||
|
||||
int linux_get_cpu_count(void);
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <jni.h>
|
||||
#include <poll.h>
|
||||
|
|
|
@ -481,7 +481,9 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
|||
submit_info.commandBufferCount = 1;
|
||||
submit_info.pCommandBuffers = &staging;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
slock_lock(vk->context->queue_lock);
|
||||
#endif
|
||||
VKFUNC(vkQueueSubmit)(vk->context->queue,
|
||||
1, &submit_info, VK_NULL_HANDLE);
|
||||
|
||||
|
@ -489,7 +491,9 @@ struct vk_texture vulkan_create_texture(vk_t *vk,
|
|||
* during init, so waiting for GPU to complete transfer
|
||||
* and blocking isn't a big deal. */
|
||||
VKFUNC(vkQueueWaitIdle)(vk->context->queue);
|
||||
#ifdef HAVE_THREADS
|
||||
slock_unlock(vk->context->queue_lock);
|
||||
#endif
|
||||
|
||||
VKFUNC(vkFreeCommandBuffers)(vk->context->device, vk->staging_pool, 1, &staging);
|
||||
vulkan_destroy_texture(
|
||||
|
@ -1423,9 +1427,11 @@ bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk,
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
vk->context.queue_lock = slock_new();
|
||||
if (!vk->context.queue_lock)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1577,7 +1583,9 @@ void vulkan_present(gfx_ctx_vulkan_data_t *vk, unsigned index)
|
|||
present.pWaitSemaphores = &vk->context.swapchain_semaphores[index];
|
||||
|
||||
/* Better hope QueuePresent doesn't block D: */
|
||||
#ifdef HAVE_THREADS
|
||||
slock_lock(vk->context.queue_lock);
|
||||
#endif
|
||||
err = VKFUNC(vkQueuePresentKHR)(vk->context.queue, &present);
|
||||
|
||||
if (err != VK_SUCCESS || result != VK_SUCCESS)
|
||||
|
@ -1586,7 +1594,9 @@ void vulkan_present(gfx_ctx_vulkan_data_t *vk, unsigned index)
|
|||
vk->context.invalid_swapchain = true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
slock_unlock(vk->context.queue_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void vulkan_context_destroy(gfx_ctx_vulkan_data_t *vk,
|
||||
|
|
|
@ -38,13 +38,14 @@
|
|||
#include <rthreads/rthreads.h>
|
||||
#include <formats/image.h>
|
||||
|
||||
#include <libretro.h>
|
||||
#include <libretro_vulkan.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../../libretro.h"
|
||||
#include "../../general.h"
|
||||
#include "../../retroarch.h"
|
||||
#include "../font_driver.h"
|
||||
#include "../video_context_driver.h"
|
||||
#include "../../libretro_vulkan.h"
|
||||
#include "../drivers_shader/shader_vulkan.h"
|
||||
|
||||
typedef struct vulkan_filter_chain vulkan_filter_chain_t;
|
||||
|
|
|
@ -17,10 +17,11 @@
|
|||
#ifndef __D3D_RENDER_CHAIN_H
|
||||
#define __D3D_RENDER_CHAIN_H
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../video_driver.h"
|
||||
#include "../video_shader_parse.h"
|
||||
#include "../video_state_tracker.h"
|
||||
#include "../../libretro.h"
|
||||
#include "../../defines/d3d_defines.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -31,12 +31,12 @@
|
|||
#include <retro_inline.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../../record/record_driver.h"
|
||||
#include "../../performance_counters.h"
|
||||
|
||||
#include "../../libretro.h"
|
||||
#include "../../general.h"
|
||||
#include "../../retroarch.h"
|
||||
#include "../../verbosity.h"
|
||||
|
@ -230,7 +230,8 @@ static bool gl_init_vao(gl_t *gl)
|
|||
#elif !defined(HAVE_OPENGLES2)
|
||||
static bool gl_check_fbo_proc(gl_t *gl)
|
||||
{
|
||||
if (!gl->core_context && !gl_query_extension(gl, "ARB_framebuffer_object"))
|
||||
if (!gl->core_context && !gl_query_extension(gl, "ARB_framebuffer_object")
|
||||
&& !gl_query_extension(gl, "EXT_framebuffer_object"))
|
||||
return false;
|
||||
|
||||
return glGenFramebuffers
|
||||
|
@ -2493,7 +2494,7 @@ static void DEBUG_CALLBACK_TYPE gl_debug_cb(GLenum source, GLenum type,
|
|||
const GLchar *message, void *userParam)
|
||||
{
|
||||
const char *src = NULL;
|
||||
const char **typestr = NULL;
|
||||
const char *typestr = NULL;
|
||||
gl_t *gl = (gl_t*)userParam; /* Useful for debugger. */
|
||||
|
||||
(void)gl;
|
||||
|
@ -3786,6 +3787,7 @@ static void video_texture_load_gl(
|
|||
);
|
||||
}
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
static int video_texture_load_wrap_gl_mipmap(void *data)
|
||||
{
|
||||
uintptr_t id = 0;
|
||||
|
@ -3807,6 +3809,7 @@ static int video_texture_load_wrap_gl(void *data)
|
|||
TEXTURE_FILTER_LINEAR, &id);
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uintptr_t gl_load_texture(void *video_data, void *data,
|
||||
bool threaded, enum texture_filter_type filter_type)
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
#include <retro_inline.h>
|
||||
#include <retro_assert.h>
|
||||
#include <gfx/math/matrix_3x3.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../video_context_driver.h"
|
||||
#include "../../libretro.h"
|
||||
#include "../../general.h"
|
||||
#include "../../retroarch.h"
|
||||
#include "../../driver.h"
|
||||
|
|
|
@ -13,6 +13,20 @@
|
|||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <gfx/scaler/scaler.h>
|
||||
#include <formats/image.h>
|
||||
#include <retro_inline.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <retro_assert.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../common/vulkan_common.h"
|
||||
#include "vulkan_shaders/alpha_blend.vert.inc"
|
||||
#include "vulkan_shaders/alpha_blend.frag.inc"
|
||||
|
@ -22,23 +36,10 @@
|
|||
#include "vulkan_shaders/ribbon_simple.vert.inc"
|
||||
#include "vulkan_shaders/ribbon_simple.frag.inc"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <gfx/scaler/scaler.h>
|
||||
#include <formats/image.h>
|
||||
#include <retro_inline.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <retro_assert.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../../record/record_driver.h"
|
||||
#include "../../performance_counters.h"
|
||||
|
||||
#include "../../libretro.h"
|
||||
#include "../../general.h"
|
||||
#include "../../retroarch.h"
|
||||
|
||||
|
@ -884,13 +885,17 @@ static void vulkan_set_command_buffers(void *handle, uint32_t num_cmd,
|
|||
static void vulkan_lock_queue(void *handle)
|
||||
{
|
||||
vk_t *vk = (vk_t*)handle;
|
||||
#ifdef HAVE_THREADS
|
||||
slock_lock(vk->context->queue_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void vulkan_unlock_queue(void *handle)
|
||||
{
|
||||
vk_t *vk = (vk_t*)handle;
|
||||
#ifdef HAVE_THREADS
|
||||
slock_unlock(vk->context->queue_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void vulkan_init_hw_render(vk_t *vk)
|
||||
|
@ -1740,10 +1745,14 @@ static bool vulkan_frame(void *data, const void *frame,
|
|||
|
||||
retro_perf_start(&queue_submit);
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
slock_lock(vk->context->queue_lock);
|
||||
#endif
|
||||
VKFUNC(vkQueueSubmit)(vk->context->queue, 1,
|
||||
&submit_info, vk->context->swapchain_fences[frame_index]);
|
||||
#ifdef HAVE_THREADS
|
||||
slock_unlock(vk->context->queue_lock);
|
||||
#endif
|
||||
retro_perf_stop(&queue_submit);
|
||||
|
||||
retro_perf_start(&swapbuffers);
|
||||
|
@ -2007,7 +2016,9 @@ static const video_poke_interface_t vulkan_poke_interface = {
|
|||
NULL,
|
||||
NULL,
|
||||
#endif
|
||||
#ifdef HAVE_MENU
|
||||
vulkan_set_osd_msg,
|
||||
#endif
|
||||
vulkan_show_mouse,
|
||||
NULL,
|
||||
vulkan_get_current_shader,
|
||||
|
@ -2260,9 +2271,13 @@ static bool vulkan_overlay_load(void *data,
|
|||
if (!vk)
|
||||
return false;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
slock_lock(vk->context->queue_lock);
|
||||
#endif
|
||||
VKFUNC(vkQueueWaitIdle)(vk->context->queue);
|
||||
#ifdef HAVE_THREADS
|
||||
slock_unlock(vk->context->queue_lock);
|
||||
#endif
|
||||
vulkan_overlay_free(vk);
|
||||
|
||||
vk->overlay.images = (struct vk_texture*)
|
||||
|
|
|
@ -706,7 +706,7 @@ static void gfx_ctx_wl_destroy(void *data)
|
|||
switch (wl_api)
|
||||
{
|
||||
case GFX_CTX_VULKAN_API:
|
||||
#ifdef HAVE_VULKAN
|
||||
#if defined(HAVE_VULKAN) && defined(HAVE_THREADS)
|
||||
if (wl->vk.context.queue_lock)
|
||||
slock_free(wl->vk.context.queue_lock);
|
||||
#endif
|
||||
|
|
|
@ -167,7 +167,7 @@ static void gfx_ctx_x_destroy(void *data)
|
|||
switch (x_api)
|
||||
{
|
||||
case GFX_CTX_VULKAN_API:
|
||||
#ifdef HAVE_VULKAN
|
||||
#if defined(HAVE_VULKAN) && defined(HAVE_THREADS)
|
||||
if (x->vk.context.queue_lock)
|
||||
slock_free(x->vk.context.queue_lock);
|
||||
#endif
|
||||
|
|
|
@ -189,16 +189,13 @@ static EGLint *xegl_fill_attribs(xegl_ctx_data_t *xegl, EGLint *attr)
|
|||
#ifdef EGL_KHR_create_context
|
||||
case GFX_CTX_OPENGL_API:
|
||||
{
|
||||
bool debug = false;
|
||||
unsigned version = xegl->egl.major * 1000 + xegl->egl.minor;
|
||||
bool core = version >= 3001;
|
||||
struct retro_hw_render_callback *hwr = NULL;
|
||||
|
||||
hwr = video_driver_get_hw_context();
|
||||
#ifdef GL_DEBUG
|
||||
debug = true;
|
||||
bool debug = true;
|
||||
#else
|
||||
debug = hwr->debug_context;
|
||||
struct retro_hw_render_callback *hwr = video_driver_get_hw_context();
|
||||
bool debug = hwr->debug_context;
|
||||
#endif
|
||||
|
||||
if (core)
|
||||
|
|
|
@ -1153,7 +1153,10 @@ static void gl_glsl_set_params(void *data, void *shader_data,
|
|||
orig_uniforms[1].enabled = true;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
gl_glsl_set_uniform_parameter(glsl, &orig_uniforms[j], NULL);
|
||||
{
|
||||
if (orig_uniforms[j].enabled)
|
||||
gl_glsl_set_uniform_parameter(glsl, &orig_uniforms[j], NULL);
|
||||
}
|
||||
|
||||
/* Pass texture coordinates. */
|
||||
if (uni->orig.tex_coord >= 0)
|
||||
|
@ -1204,7 +1207,10 @@ static void gl_glsl_set_params(void *data, void *shader_data,
|
|||
feedback_uniforms[1].enabled = true;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
gl_glsl_set_uniform_parameter(glsl, &feedback_uniforms[j], NULL);
|
||||
{
|
||||
if (feedback_uniforms[j].enabled)
|
||||
gl_glsl_set_uniform_parameter(glsl, &feedback_uniforms[j], NULL);
|
||||
}
|
||||
|
||||
/* Pass texture coordinates. */
|
||||
if (uni->feedback.tex_coord >= 0)
|
||||
|
@ -1255,7 +1261,10 @@ static void gl_glsl_set_params(void *data, void *shader_data,
|
|||
fbo_tex_params[2].enabled = true;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
gl_glsl_set_uniform_parameter(glsl, &fbo_tex_params[j], NULL);
|
||||
{
|
||||
if (fbo_tex_params[j].enabled)
|
||||
gl_glsl_set_uniform_parameter(glsl, &fbo_tex_params[j], NULL);
|
||||
}
|
||||
|
||||
if (uni->pass[i].tex_coord >= 0)
|
||||
{
|
||||
|
@ -1307,7 +1316,10 @@ static void gl_glsl_set_params(void *data, void *shader_data,
|
|||
prev_tex_params[2].enabled = true;
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
gl_glsl_set_uniform_parameter(glsl, &prev_tex_params[j], NULL);
|
||||
{
|
||||
if (prev_tex_params[j].enabled)
|
||||
gl_glsl_set_uniform_parameter(glsl, &prev_tex_params[j], NULL);
|
||||
}
|
||||
|
||||
/* Pass texture coordinates. */
|
||||
if (uni->prev[i].tex_coord >= 0)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#endif
|
||||
|
||||
#include <file/config_file.h>
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#include "video_thread_wrapper.h"
|
||||
#include "../frontend/frontend_driver.h"
|
||||
|
@ -33,7 +34,6 @@
|
|||
#include "../config.def.h"
|
||||
#include "../retroarch.h"
|
||||
#include "../runloop.h"
|
||||
#include "../performance.h"
|
||||
#include "../performance_counters.h"
|
||||
#include "../list_special.h"
|
||||
#include "../core.h"
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "font_driver.h"
|
||||
#include "video_filter.h"
|
||||
#include "video_shader_parse.h"
|
||||
|
||||
#include "../libretro.h"
|
||||
#include "../input/input_driver.h"
|
||||
|
||||
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
#include <file/file_path.h>
|
||||
#include <lists/dir_list.h>
|
||||
#include <dynamic/dylib.h>
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#include "../frontend/frontend_driver.h"
|
||||
#include "../config_file_userdata.h"
|
||||
#include "../dynamic.h"
|
||||
#include "../general.h"
|
||||
#include "../performance.h"
|
||||
#include "../performance_counters.h"
|
||||
#include "../verbosity.h"
|
||||
#include "video_filter.h"
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
#ifndef RARCH_FILTER_H__
|
||||
#define RARCH_FILTER_H__
|
||||
|
||||
#include "../libretro.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
#define RARCH_SOFTFILTER_THREADS_AUTO 0
|
||||
typedef struct rarch_softfilter rarch_softfilter_t;
|
||||
|
||||
|
|
|
@ -14,18 +14,20 @@
|
|||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Python.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <compat/posix_string.h>
|
||||
#include <streams/file_stream.h>
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
#include "video_state_python.h"
|
||||
#include "../dynamic.h"
|
||||
#include "../libretro.h"
|
||||
#include "../core.h"
|
||||
#include "../general.h"
|
||||
#include "../verbosity.h"
|
||||
|
|
|
@ -29,8 +29,12 @@
|
|||
#ifdef HAVE_RPNG
|
||||
#include <formats/rpng.h>
|
||||
#endif
|
||||
#ifdef HAVE_RJPEG
|
||||
#include <formats/rjpeg.h>
|
||||
#endif
|
||||
#ifdef HAVE_RTGA
|
||||
#include <formats/tga.h>
|
||||
#endif
|
||||
|
||||
#include "../general.h"
|
||||
|
||||
|
@ -264,9 +268,11 @@ bool video_texture_image_load(struct texture_image *out_img,
|
|||
switch (fmt)
|
||||
{
|
||||
case IMAGE_FORMAT_TGA:
|
||||
#ifdef HAVE_RTGA
|
||||
if (rtga_image_load_shift((uint8_t*)ptr, out_img,
|
||||
a_shift, r_shift, g_shift, b_shift))
|
||||
goto success;
|
||||
#endif
|
||||
break;
|
||||
case IMAGE_FORMAT_PNG:
|
||||
#ifdef HAVE_RPNG
|
||||
|
@ -276,9 +282,11 @@ bool video_texture_image_load(struct texture_image *out_img,
|
|||
#endif
|
||||
break;
|
||||
case IMAGE_FORMAT_JPEG:
|
||||
#ifdef HAVE_RJPEG
|
||||
if (rjpeg_image_load((uint8_t*)ptr, out_img, file_len,
|
||||
a_shift, r_shift, g_shift, b_shift))
|
||||
goto success;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
case IMAGE_FORMAT_NONE:
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <features/features_cpu.h>
|
||||
#include <rthreads/rthreads.h>
|
||||
|
||||
#include "video_thread_wrapper.h"
|
||||
#include "font_driver.h"
|
||||
#include "video_shader_driver.h"
|
||||
#include "../performance.h"
|
||||
#include "../performance_counters.h"
|
||||
#include "../runloop.h"
|
||||
#include "../verbosity.h"
|
||||
|
|
|
@ -17,5 +17,5 @@
|
|||
#include "git_version.h"
|
||||
#define STR_(x) #x
|
||||
#define STR(x) STR_(x)
|
||||
const char rarch_git_version[] = STR(GIT_VERSION);
|
||||
const char retroarch_git_version[] = STR(GIT_VERSION);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ extern "C" {
|
|||
|
||||
/* Put this in a separate file so we don't have to rebuilt
|
||||
* retroarch.c every single build. */
|
||||
extern const char rarch_git_version[];
|
||||
extern const char retroarch_git_version[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ ENCODINGS
|
|||
/*============================================================
|
||||
PERFORMANCE
|
||||
============================================================ */
|
||||
#include "../performance.c"
|
||||
#include "../libretro-common/features/features_cpu.c"
|
||||
#include "../performance_counters.c"
|
||||
|
||||
/*============================================================
|
||||
|
@ -222,7 +222,9 @@ VIDEO IMAGE
|
|||
|
||||
#include "../gfx/video_texture_image.c"
|
||||
|
||||
#ifdef HAVE_RTGA
|
||||
#include "../libretro-common/formats/tga/rtga.c"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IMAGEVIEWER
|
||||
#include "../cores/libretro-imageviewer/image_core.c"
|
||||
|
@ -232,7 +234,9 @@ VIDEO IMAGE
|
|||
#include "../libretro-common/formats/png/rpng.c"
|
||||
#include "../libretro-common/formats/png/rpng_encode.c"
|
||||
#endif
|
||||
#ifdef HAVE_RJPEG
|
||||
#include "../libretro-common/formats/jpeg/rjpeg.c"
|
||||
#endif
|
||||
#include "../libretro-common/formats/bmp/rbmp_encode.c"
|
||||
|
||||
/*============================================================
|
||||
|
@ -430,7 +434,7 @@ INPUT (HID)
|
|||
|
||||
#include "../input/drivers_hid/null_hid.c"
|
||||
|
||||
#if defined(HAVE_LIBUSB)
|
||||
#if defined(HAVE_LIBUSB) && defined(HAVE_THREADS)
|
||||
#include "../input/drivers_hid/libusb_hid.c"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
#include "input_x11_common.h"
|
||||
#include "../../libretro.h"
|
||||
|
||||
static bool x11_mouse_wu;
|
||||
static bool x11_mouse_wd;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "../../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
typedef void (*send_control_t)(void *data, uint8_t *buf, size_t size);
|
||||
|
||||
|
|
|
@ -15,10 +15,11 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../../libretro.h"
|
||||
#include "../../general.h"
|
||||
#include "../input_config.h"
|
||||
#include "../input_joypad_driver.h"
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
#include <boolean.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../../libretro.h"
|
||||
|
||||
#ifndef MAX_PADS
|
||||
#define MAX_PADS 4
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#include <sdk_version.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../../defines/ps3_defines.h"
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../../libretro.h"
|
||||
#include "../../general.h"
|
||||
|
||||
#ifdef HAVE_MOUSE
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#if defined(SN_TARGET_PSP2)
|
||||
#include <sceerror.h>
|
||||
#include <kernel.h>
|
||||
|
@ -29,10 +27,12 @@
|
|||
#include <pspctrl.h>
|
||||
#endif
|
||||
|
||||
#include <boolean.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../../defines/psp_defines.h"
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../../libretro.h"
|
||||
#include "../../general.h"
|
||||
#include "../input_config.h"
|
||||
#ifdef HAVE_KERNEL_PRX
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <boolean.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
|
||||
|
@ -26,7 +27,6 @@
|
|||
#include "../../gfx/video_context_driver.h"
|
||||
#include "../../general.h"
|
||||
#include "../../verbosity.h"
|
||||
#include "../../libretro.h"
|
||||
#include "../input_autodetect.h"
|
||||
#include "../input_config.h"
|
||||
#include "../input_joypad_driver.h"
|
||||
|
|
|
@ -17,15 +17,15 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#ifdef _XBOX
|
||||
#include <xtl.h>
|
||||
#endif
|
||||
|
||||
#include <boolean.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../../general.h"
|
||||
#include "../../libretro.h"
|
||||
|
||||
#define MAX_PADS 4
|
||||
|
||||
|
|
|
@ -18,12 +18,13 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
#include "../../libretro.h"
|
||||
|
||||
#include <input/input.h>
|
||||
#include <usb/usbmain.h>
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../../driver.h"
|
||||
|
||||
#define MAX_PADS 4
|
||||
|
||||
static uint64_t state[MAX_PADS];
|
||||
|
|
|
@ -29,7 +29,7 @@ static hid_driver_t *hid_drivers[] = {
|
|||
#if defined(__APPLE__) && defined(HAVE_IOHIDMANAGER)
|
||||
&iohidmanager_hid,
|
||||
#endif
|
||||
#ifdef HAVE_LIBUSB
|
||||
#if defined(HAVE_LIBUSB) && defined(HAVE_THREADS)
|
||||
&libusb_hid,
|
||||
#endif
|
||||
#ifdef HW_RVL
|
||||
|
|
|
@ -24,7 +24,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
#include <boolean.h>
|
||||
|
||||
#include "../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
typedef struct hid_driver hid_driver_t;
|
||||
|
||||
|
|
|
@ -23,8 +23,7 @@ extern "C" {
|
|||
|
||||
#include <stdint.h>
|
||||
#include <boolean.h>
|
||||
|
||||
#include "../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
typedef struct rarch_joypad_driver input_device_driver_t;
|
||||
|
||||
|
|
|
@ -24,8 +24,7 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#include "../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
enum rarch_input_keyboard_ctl_state
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
892
libretro-common/features/features_cpu.c
Normal file
892
libretro-common/features/features_cpu.c
Normal file
|
@ -0,0 +1,892 @@
|
|||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (features_cpu.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <streams/file_stream.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#ifndef _PPU_INTRINSICS_H
|
||||
#include <ppu_intrinsics.h>
|
||||
#endif
|
||||
#elif defined(_XBOX360)
|
||||
#include <PPCIntrinsics.h>
|
||||
#elif defined(_POSIX_MONOTONIC_CLOCK) || defined(ANDROID) || defined(__QNX__)
|
||||
/* POSIX_MONOTONIC_CLOCK is not being defined in Android headers despite support being present. */
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if defined(__QNX__) && !defined(CLOCK_MONOTONIC)
|
||||
#define CLOCK_MONOTONIC 2
|
||||
#endif
|
||||
|
||||
#if defined(PSP)
|
||||
#include <sys/time.h>
|
||||
#include <psprtc.h>
|
||||
#endif
|
||||
|
||||
#if defined(VITA)
|
||||
#include <psp2/kernel/processmgr.h>
|
||||
#include <psp2/rtc.h>
|
||||
#endif
|
||||
|
||||
#if defined(__PSL1GHT__)
|
||||
#include <sys/time.h>
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
#include <sys/sys_time.h>
|
||||
#endif
|
||||
|
||||
#ifdef GEKKO
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
#endif
|
||||
|
||||
/* iOS/OSX specific. Lacks clock_gettime(), so implement it. */
|
||||
#ifdef __MACH__
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef CLOCK_MONOTONIC
|
||||
#define CLOCK_MONOTONIC 0
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_REALTIME
|
||||
#define CLOCK_REALTIME 0
|
||||
#endif
|
||||
|
||||
static int clock_gettime(int clk_ik, struct timespec *t)
|
||||
{
|
||||
struct timeval now;
|
||||
int rv = gettimeofday(&now, NULL);
|
||||
if (rv)
|
||||
return rv;
|
||||
t->tv_sec = now.tv_sec;
|
||||
t->tv_nsec = now.tv_usec * 1000;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#if defined(BSD) || defined(__APPLE__)
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* cpu_features_get_perf_counter:
|
||||
*
|
||||
* Gets performance counter.
|
||||
*
|
||||
* Returns: performance counter.
|
||||
**/
|
||||
retro_perf_tick_t cpu_features_get_perf_counter(void)
|
||||
{
|
||||
retro_perf_tick_t time_ticks = 0;
|
||||
#if defined(__linux__) || defined(__QNX__) || defined(__MACH__)
|
||||
struct timespec tv;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tv) == 0)
|
||||
time_ticks = (retro_perf_tick_t)tv.tv_sec * 1000000000 +
|
||||
(retro_perf_tick_t)tv.tv_nsec;
|
||||
|
||||
#elif defined(__GNUC__) && defined(__i386__) || defined(__i486__) || defined(__i686__)
|
||||
__asm__ volatile ("rdtsc" : "=A" (time_ticks));
|
||||
#elif defined(__GNUC__) && defined(__x86_64__)
|
||||
unsigned a, d;
|
||||
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
|
||||
time_ticks = (retro_perf_tick_t)a | ((retro_perf_tick_t)d << 32);
|
||||
#elif defined(__ARM_ARCH_6__)
|
||||
__asm__ volatile( "mrc p15, 0, %0, c9, c13, 0" : "=r"(time_ticks) );
|
||||
#elif defined(__CELLOS_LV2__) || defined(_XBOX360) || defined(__powerpc__) || defined(__ppc__) || defined(__POWERPC__)
|
||||
time_ticks = __mftb();
|
||||
#elif defined(GEKKO)
|
||||
time_ticks = gettime();
|
||||
#elif defined(PSP) || defined(VITA)
|
||||
sceRtcGetCurrentTick(&time_ticks);
|
||||
#elif defined(_3DS)
|
||||
time_ticks = svcGetSystemTick();
|
||||
#elif defined(__mips__)
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv,NULL);
|
||||
time_ticks = (1000000 * tv.tv_sec + tv.tv_usec);
|
||||
#elif defined(_WIN32)
|
||||
long tv_sec, tv_usec;
|
||||
static const unsigned __int64 epoch = 11644473600000000Ui64;
|
||||
FILETIME file_time;
|
||||
SYSTEMTIME system_time;
|
||||
ULARGE_INTEGER ularge;
|
||||
|
||||
GetSystemTime(&system_time);
|
||||
SystemTimeToFileTime(&system_time, &file_time);
|
||||
ularge.LowPart = file_time.dwLowDateTime;
|
||||
ularge.HighPart = file_time.dwHighDateTime;
|
||||
|
||||
tv_sec = (long)((ularge.QuadPart - epoch) / 10000000L);
|
||||
tv_usec = (long)(system_time.wMilliseconds * 1000);
|
||||
|
||||
time_ticks = (1000000 * tv_sec + tv_usec);
|
||||
#endif
|
||||
|
||||
return time_ticks;
|
||||
}
|
||||
|
||||
/**
|
||||
* cpu_features_get_time_usec:
|
||||
*
|
||||
* Gets time in microseconds.
|
||||
*
|
||||
* Returns: time in microseconds.
|
||||
**/
|
||||
retro_time_t cpu_features_get_time_usec(void)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
static LARGE_INTEGER freq;
|
||||
LARGE_INTEGER count;
|
||||
|
||||
/* Frequency is guaranteed to not change. */
|
||||
if (!freq.QuadPart && !QueryPerformanceFrequency(&freq))
|
||||
return 0;
|
||||
|
||||
if (!QueryPerformanceCounter(&count))
|
||||
return 0;
|
||||
return count.QuadPart * 1000000 / freq.QuadPart;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
return sys_time_get_system_time();
|
||||
#elif defined(GEKKO)
|
||||
return ticks_to_microsecs(gettime());
|
||||
#elif defined(_POSIX_MONOTONIC_CLOCK) || defined(__QNX__) || defined(ANDROID) || defined(__MACH__)
|
||||
struct timespec tv = {0};
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tv) < 0)
|
||||
return 0;
|
||||
return tv.tv_sec * INT64_C(1000000) + (tv.tv_nsec + 500) / 1000;
|
||||
#elif defined(EMSCRIPTEN)
|
||||
return emscripten_get_now() * 1000;
|
||||
#elif defined(__mips__)
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv,NULL);
|
||||
return (1000000 * tv.tv_sec + tv.tv_usec);
|
||||
#elif defined(_3DS)
|
||||
return osGetTime() * 1000;
|
||||
#elif defined(VITA)
|
||||
return sceKernelGetProcessTimeWide();
|
||||
#else
|
||||
#error "Your platform does not have a timer function implemented in cpu_features_get_time_usec(). Cannot continue."
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__i486__) || defined(__i686__)
|
||||
#define CPU_X86
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_XBOX)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#if defined(CPU_X86) && !defined(__MACH__)
|
||||
void x86_cpuid(int func, int flags[4])
|
||||
{
|
||||
/* On Android, we compile RetroArch with PIC, and we
|
||||
* are not allowed to clobber the ebx register. */
|
||||
#ifdef __x86_64__
|
||||
#define REG_b "rbx"
|
||||
#define REG_S "rsi"
|
||||
#else
|
||||
#define REG_b "ebx"
|
||||
#define REG_S "esi"
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__asm__ volatile (
|
||||
"mov %%" REG_b ", %%" REG_S "\n"
|
||||
"cpuid\n"
|
||||
"xchg %%" REG_b ", %%" REG_S "\n"
|
||||
: "=a"(flags[0]), "=S"(flags[1]), "=c"(flags[2]), "=d"(flags[3])
|
||||
: "a"(func));
|
||||
#elif defined(_MSC_VER)
|
||||
__cpuid(flags, func);
|
||||
#else
|
||||
printf("Unknown compiler. Cannot check CPUID with inline assembly.\n");
|
||||
memset(flags, 0, 4 * sizeof(int));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Only runs on i686 and above. Needs to be conditionally run. */
|
||||
static uint64_t xgetbv_x86(uint32_t idx)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
uint32_t eax, edx;
|
||||
__asm__ volatile (
|
||||
/* Older GCC versions (Apple's GCC for example) do
|
||||
* not understand xgetbv instruction.
|
||||
* Stamp out the machine code directly.
|
||||
*/
|
||||
".byte 0x0f, 0x01, 0xd0\n"
|
||||
: "=a"(eax), "=d"(edx) : "c"(idx));
|
||||
return ((uint64_t)edx << 32) | eax;
|
||||
#elif _MSC_FULL_VER >= 160040219
|
||||
/* Intrinsic only works on 2010 SP1 and above. */
|
||||
return _xgetbv(idx);
|
||||
#else
|
||||
printf("Unknown compiler. Cannot check xgetbv bits.\n");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_NEON__)
|
||||
static void arm_enable_runfast_mode(void)
|
||||
{
|
||||
/* RunFast mode. Enables flush-to-zero and some
|
||||
* floating point optimizations. */
|
||||
static const unsigned x = 0x04086060;
|
||||
static const unsigned y = 0x03000000;
|
||||
int r;
|
||||
__asm__ volatile(
|
||||
"fmrx %0, fpscr \n\t" /* r0 = FPSCR */
|
||||
"and %0, %0, %1 \n\t" /* r0 = r0 & 0x04086060 */
|
||||
"orr %0, %0, %2 \n\t" /* r0 = r0 | 0x03000000 */
|
||||
"fmxr fpscr, %0 \n\t" /* FPSCR = r0 */
|
||||
: "=r"(r)
|
||||
: "r"(x), "r"(y)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && !defined(CPU_X86)
|
||||
|
||||
/* Extract the content of a the first occurrence of a given field in
|
||||
* the content of /proc/cpuinfo and return it as a heap-allocated
|
||||
* string that must be freed by the caller.
|
||||
*
|
||||
* Return NULL if not found
|
||||
*/
|
||||
static char *extract_cpuinfo_field(char* buffer,
|
||||
ssize_t length, const char* field)
|
||||
{
|
||||
int len;
|
||||
const char *q;
|
||||
int fieldlen = strlen(field);
|
||||
char* bufend = buffer + length;
|
||||
char* result = NULL;
|
||||
/* Look for first field occurrence,
|
||||
* and ensures it starts the line. */
|
||||
const char *p = buffer;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
p = memmem(p, bufend-p, field, fieldlen);
|
||||
if (p == NULL)
|
||||
return result;
|
||||
|
||||
if (p == buffer || p[-1] == '\n')
|
||||
break;
|
||||
|
||||
p += fieldlen;
|
||||
}
|
||||
|
||||
/* Skip to the first column followed by a space */
|
||||
p += fieldlen;
|
||||
p = memchr(p, ':', bufend-p);
|
||||
if (p == NULL || p[1] != ' ')
|
||||
return result;
|
||||
|
||||
/* Find the end of the line */
|
||||
p += 2;
|
||||
q = memchr(p, '\n', bufend-p);
|
||||
if (q == NULL)
|
||||
q = bufend;
|
||||
|
||||
/* Copy the line into a heap-allocated buffer */
|
||||
len = q-p;
|
||||
result = malloc(len+1);
|
||||
if (result == NULL)
|
||||
return result;
|
||||
|
||||
memcpy(result, p, len);
|
||||
result[len] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Checks that a space-separated list of items
|
||||
* contains one given 'item'.
|
||||
* Returns 1 if found, 0 otherwise.
|
||||
*/
|
||||
static int has_list_item(const char* list, const char* item)
|
||||
{
|
||||
const char* p = list;
|
||||
int itemlen = strlen(item);
|
||||
|
||||
if (list == NULL)
|
||||
return 0;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
const char* q;
|
||||
|
||||
/* skip spaces */
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
|
||||
/* find end of current list item */
|
||||
q = p;
|
||||
while (*q && *q != ' ' && *q != '\t')
|
||||
q++;
|
||||
|
||||
if (itemlen == q-p && !memcmp(p, item, itemlen))
|
||||
return 1;
|
||||
|
||||
/* skip to next item */
|
||||
p = q;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t mask;
|
||||
} CpuList;
|
||||
|
||||
|
||||
#if !defined(_SC_NPROCESSORS_ONLN)
|
||||
/* Parse an decimal integer starting from 'input', but not going further
|
||||
* than 'limit'. Return the value into '*result'.
|
||||
*
|
||||
* NOTE: Does not skip over leading spaces, or deal with sign characters.
|
||||
* NOTE: Ignores overflows.
|
||||
*
|
||||
* The function returns NULL in case of error (bad format), or the new
|
||||
* position after the decimal number in case of success (which will always
|
||||
* be <= 'limit').
|
||||
*/
|
||||
static const char *parse_decimal(const char* input,
|
||||
const char* limit, int* result)
|
||||
{
|
||||
const char* p = input;
|
||||
int val = 0;
|
||||
|
||||
while (p < limit)
|
||||
{
|
||||
int d = (*p - '0');
|
||||
if ((unsigned)d >= 10U)
|
||||
break;
|
||||
val = val*10 + d;
|
||||
p++;
|
||||
}
|
||||
if (p == input)
|
||||
return NULL;
|
||||
|
||||
*result = val;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Parse a textual list of cpus and store the result inside a CpuList object.
|
||||
* Input format is the following:
|
||||
* - comma-separated list of items (no spaces)
|
||||
* - each item is either a single decimal number (cpu index), or a range made
|
||||
* of two numbers separated by a single dash (-). Ranges are inclusive.
|
||||
*
|
||||
* Examples: 0
|
||||
* 2,4-127,128-143
|
||||
* 0-1
|
||||
*/
|
||||
static void cpulist_parse(CpuList* list, char **buf, ssize_t length)
|
||||
{
|
||||
const char* p = (const char*)buf;
|
||||
const char* end = p + length;
|
||||
|
||||
/* NOTE: the input line coming from sysfs typically contains a
|
||||
* trailing newline, so take care of it in the code below
|
||||
*/
|
||||
while (p < end && *p != '\n')
|
||||
{
|
||||
int val, start_value, end_value;
|
||||
/* Find the end of current item, and put it into 'q' */
|
||||
const char *q = (const char*)memchr(p, ',', end-p);
|
||||
|
||||
if (!q)
|
||||
q = end;
|
||||
|
||||
/* Get first value */
|
||||
p = parse_decimal(p, q, &start_value);
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
end_value = start_value;
|
||||
|
||||
/* If we're not at the end of the item, expect a dash and
|
||||
* and integer; extract end value.
|
||||
*/
|
||||
if (p < q && *p == '-')
|
||||
{
|
||||
p = parse_decimal(p+1, q, &end_value);
|
||||
if (p == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set bits CPU list bits */
|
||||
for (val = start_value; val <= end_value; val++)
|
||||
{
|
||||
if ((unsigned)val < 32)
|
||||
list->mask |= (uint32_t)(1U << val);
|
||||
}
|
||||
|
||||
/* Jump to next item */
|
||||
p = q;
|
||||
if (p < end)
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read a CPU list from one sysfs file */
|
||||
static void cpulist_read_from(CpuList* list, const char* filename)
|
||||
{
|
||||
ssize_t length;
|
||||
char *buf = NULL;
|
||||
|
||||
list->mask = 0;
|
||||
|
||||
if (filestream_read_file(filename, (void**)&buf, &length) != 1)
|
||||
return;
|
||||
|
||||
cpulist_parse(list, &buf, length);
|
||||
if (buf)
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cpu_features_get_core_amount:
|
||||
*
|
||||
* Gets the amount of available CPU cores.
|
||||
*
|
||||
* Returns: amount of CPU cores available.
|
||||
**/
|
||||
unsigned cpu_features_get_core_amount(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
/* Win32 */
|
||||
SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
return sysinfo.dwNumberOfProcessors;
|
||||
#elif defined(GEKKO)
|
||||
return 1;
|
||||
#elif defined(PSP)
|
||||
return 1;
|
||||
#elif defined(VITA)
|
||||
return 4;
|
||||
#elif defined(_3DS)
|
||||
return 1;
|
||||
#elif defined(_SC_NPROCESSORS_ONLN)
|
||||
/* Linux, most UNIX-likes. */
|
||||
long ret = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (ret <= 0)
|
||||
return (unsigned)1;
|
||||
return ret;
|
||||
#elif defined(BSD) || defined(__APPLE__)
|
||||
/* BSD */
|
||||
/* Copypasta from stackoverflow, dunno if it works. */
|
||||
int num_cpu = 0;
|
||||
int mib[4];
|
||||
size_t len = sizeof(num_cpu);
|
||||
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_AVAILCPU;
|
||||
sysctl(mib, 2, &num_cpu, &len, NULL, 0);
|
||||
if (num_cpu < 1)
|
||||
{
|
||||
mib[1] = HW_NCPU;
|
||||
sysctl(mib, 2, &num_cpu, &len, NULL, 0);
|
||||
if (num_cpu < 1)
|
||||
num_cpu = 1;
|
||||
}
|
||||
return num_cpu;
|
||||
#elif defined(__linux__)
|
||||
CpuList cpus_present[1];
|
||||
CpuList cpus_possible[1];
|
||||
int amount = 0;
|
||||
|
||||
cpulist_read_from(cpus_present, "/sys/devices/system/cpu/present");
|
||||
cpulist_read_from(cpus_possible, "/sys/devices/system/cpu/possible");
|
||||
|
||||
/* Compute the intersection of both sets to get the actual number of
|
||||
* CPU cores that can be used on this device by the kernel.
|
||||
*/
|
||||
cpus_present->mask &= cpus_possible->mask;
|
||||
amount = __builtin_popcount(cpus_present->mask);
|
||||
|
||||
if (amount == 0)
|
||||
return 1;
|
||||
return amount;
|
||||
#elif defined(_XBOX360)
|
||||
return 3;
|
||||
#else
|
||||
/* No idea, assume single core. */
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* According to http://en.wikipedia.org/wiki/CPUID */
|
||||
#define VENDOR_INTEL_b 0x756e6547
|
||||
#define VENDOR_INTEL_c 0x6c65746e
|
||||
#define VENDOR_INTEL_d 0x49656e69
|
||||
|
||||
/**
|
||||
* cpu_features_get:
|
||||
*
|
||||
* Gets CPU features..
|
||||
*
|
||||
* Returns: bitmask of all CPU features available.
|
||||
**/
|
||||
uint64_t cpu_features_get(void)
|
||||
{
|
||||
int flags[4];
|
||||
int vendor_shuffle[3];
|
||||
char vendor[13] = {0};
|
||||
size_t len = 0;
|
||||
uint64_t cpu_flags = 0;
|
||||
uint64_t cpu = 0;
|
||||
unsigned max_flag = 0;
|
||||
#if defined(CPU_X86) && !defined(__MACH__)
|
||||
int vendor_is_intel = 0;
|
||||
const int avx_flags = (1 << 27) | (1 << 28);
|
||||
#endif
|
||||
|
||||
char buf[sizeof(" MMX MMXEXT SSE SSE2 SSE3 SSSE3 SS4 SSE4.2 AES AVX AVX2 NEON VMX VMX128 VFPU PS")];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
(void)len;
|
||||
(void)cpu_flags;
|
||||
(void)flags;
|
||||
(void)max_flag;
|
||||
(void)vendor;
|
||||
(void)vendor_shuffle;
|
||||
|
||||
#if defined(__MACH__)
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.mmx", NULL, &len, NULL, 0) == 0)
|
||||
{
|
||||
cpu |= RETRO_SIMD_MMX;
|
||||
cpu |= RETRO_SIMD_MMXEXT;
|
||||
}
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSE;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse2", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSE2;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse3", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSE3;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.supplementalsse3", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSSE3;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse4_1", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSE4;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse4_2", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_SSE42;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.aes", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_AES;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.avx1_0", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_AVX;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.avx2_0", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_AVX2;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.altivec", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_VMX;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.neon", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= RETRO_SIMD_NEON;
|
||||
|
||||
#elif defined(CPU_X86)
|
||||
(void)avx_flags;
|
||||
|
||||
x86_cpuid(0, flags);
|
||||
vendor_shuffle[0] = flags[1];
|
||||
vendor_shuffle[1] = flags[3];
|
||||
vendor_shuffle[2] = flags[2];
|
||||
memcpy(vendor, vendor_shuffle, sizeof(vendor_shuffle));
|
||||
|
||||
printf("[CPUID]: Vendor: %s\n", vendor);
|
||||
|
||||
vendor_is_intel = (
|
||||
flags[1] == VENDOR_INTEL_b &&
|
||||
flags[2] == VENDOR_INTEL_c &&
|
||||
flags[3] == VENDOR_INTEL_d);
|
||||
|
||||
max_flag = flags[0];
|
||||
if (max_flag < 1) /* Does CPUID not support func = 1? (unlikely ...) */
|
||||
return 0;
|
||||
|
||||
x86_cpuid(1, flags);
|
||||
|
||||
if (flags[3] & (1 << 23))
|
||||
cpu |= RETRO_SIMD_MMX;
|
||||
|
||||
if (flags[3] & (1 << 25))
|
||||
{
|
||||
/* SSE also implies MMXEXT (according to FFmpeg source). */
|
||||
cpu |= RETRO_SIMD_SSE;
|
||||
cpu |= RETRO_SIMD_MMXEXT;
|
||||
}
|
||||
|
||||
|
||||
if (flags[3] & (1 << 26))
|
||||
cpu |= RETRO_SIMD_SSE2;
|
||||
|
||||
if (flags[2] & (1 << 0))
|
||||
cpu |= RETRO_SIMD_SSE3;
|
||||
|
||||
if (flags[2] & (1 << 9))
|
||||
cpu |= RETRO_SIMD_SSSE3;
|
||||
|
||||
if (flags[2] & (1 << 19))
|
||||
cpu |= RETRO_SIMD_SSE4;
|
||||
|
||||
if (flags[2] & (1 << 20))
|
||||
cpu |= RETRO_SIMD_SSE42;
|
||||
|
||||
if ((flags[2] & (1 << 23)))
|
||||
cpu |= RETRO_SIMD_POPCNT;
|
||||
|
||||
if (vendor_is_intel && (flags[2] & (1 << 22)))
|
||||
cpu |= RETRO_SIMD_MOVBE;
|
||||
|
||||
if (flags[2] & (1 << 25))
|
||||
cpu |= RETRO_SIMD_AES;
|
||||
|
||||
|
||||
/* Must only perform xgetbv check if we have
|
||||
* AVX CPU support (guaranteed to have at least i686). */
|
||||
if (((flags[2] & avx_flags) == avx_flags)
|
||||
&& ((xgetbv_x86(0) & 0x6) == 0x6))
|
||||
cpu |= RETRO_SIMD_AVX;
|
||||
|
||||
if (max_flag >= 7)
|
||||
{
|
||||
x86_cpuid(7, flags);
|
||||
if (flags[1] & (1 << 5))
|
||||
cpu |= RETRO_SIMD_AVX2;
|
||||
}
|
||||
|
||||
x86_cpuid(0x80000000, flags);
|
||||
max_flag = flags[0];
|
||||
if (max_flag >= 0x80000001u)
|
||||
{
|
||||
x86_cpuid(0x80000001, flags);
|
||||
if (flags[3] & (1 << 23))
|
||||
cpu |= RETRO_SIMD_MMX;
|
||||
if (flags[3] & (1 << 22))
|
||||
cpu |= RETRO_SIMD_MMXEXT;
|
||||
}
|
||||
#elif defined(__linux__)
|
||||
|
||||
static bool cpu_inited_once = false;
|
||||
static uint64_t g_cpuFeatures = 0;
|
||||
|
||||
enum
|
||||
{
|
||||
CPU_ARM_FEATURE_ARMv7 = (1 << 0),
|
||||
CPU_ARM_FEATURE_VFPv3 = (1 << 1),
|
||||
CPU_ARM_FEATURE_NEON = (1 << 2),
|
||||
CPU_ARM_FEATURE_LDREX_STREX = (1 << 3)
|
||||
};
|
||||
|
||||
if (!cpu_inited_once)
|
||||
{
|
||||
ssize_t length;
|
||||
void *buf = NULL;
|
||||
|
||||
if (filestream_read_file("/proc/cpuinfo", &buf, &length) == 1)
|
||||
{
|
||||
char* cpu_features = NULL;
|
||||
/* Extract architecture from the "CPU Architecture" field.
|
||||
* The list is well-known, unlike the the output of
|
||||
* the 'Processor' field which can vary greatly.
|
||||
*
|
||||
* See the definition of the 'proc_arch' array in
|
||||
* $KERNEL/arch/arm/kernel/setup.c and the 'c_show' function in
|
||||
* same file.
|
||||
*/
|
||||
char* cpu_arch = extract_cpuinfo_field(buf, length, "CPU architecture");
|
||||
|
||||
if (cpu_arch)
|
||||
{
|
||||
char* end = NULL;
|
||||
int has_armv7 = 0;
|
||||
/* Read the initial decimal number, ignore the rest */
|
||||
long arch_number = strtol(cpu_arch, &end, 10);
|
||||
|
||||
/* Here we assume that ARMv8 will be upwards compatible with v7
|
||||
* in the future. Unfortunately, there is no 'Features' field to
|
||||
* indicate that Thumb-2 is supported.
|
||||
*/
|
||||
if (end > cpu_arch && arch_number >= 7)
|
||||
has_armv7 = 1;
|
||||
|
||||
/* Unfortunately, it seems that certain ARMv6-based CPUs
|
||||
* report an incorrect architecture number of 7!
|
||||
*
|
||||
* See http://code.google.com/p/android/issues/detail?id=10812
|
||||
*
|
||||
* We try to correct this by looking at the 'elf_format'
|
||||
* field reported by the 'Processor' field, which is of the
|
||||
* form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
|
||||
* an ARMv6-one.
|
||||
*/
|
||||
if (has_armv7)
|
||||
{
|
||||
char *cpu_proc = extract_cpuinfo_field(buf, length,
|
||||
"Processor");
|
||||
|
||||
if (cpu_proc)
|
||||
{
|
||||
/* CPU processor and architecture mismatch. */
|
||||
if (has_list_item(cpu_proc, "(v6l)"))
|
||||
has_armv7 = 0;
|
||||
free(cpu_proc);
|
||||
}
|
||||
}
|
||||
|
||||
if (has_armv7)
|
||||
g_cpuFeatures |= CPU_ARM_FEATURE_ARMv7;
|
||||
|
||||
/* The LDREX / STREX instructions are available from ARMv6 */
|
||||
if (arch_number >= 6)
|
||||
g_cpuFeatures |= CPU_ARM_FEATURE_LDREX_STREX;
|
||||
|
||||
}
|
||||
|
||||
/* Extract the list of CPU features from 'Features' field */
|
||||
cpu_features = extract_cpuinfo_field(buf, length, "Features");
|
||||
|
||||
if (cpu_features)
|
||||
{
|
||||
if (has_list_item(cpu_features, "vfpv3"))
|
||||
g_cpuFeatures |= CPU_ARM_FEATURE_VFPv3;
|
||||
else if (has_list_item(cpu_features, "vfpv3d16"))
|
||||
g_cpuFeatures |= CPU_ARM_FEATURE_VFPv3;
|
||||
|
||||
/* Note: Certain kernels only report NEON but not VFPv3
|
||||
* in their features list. However, ARM mandates
|
||||
* that if NEON is implemented, so must be VFPv3
|
||||
* so always set the flag.
|
||||
*/
|
||||
if (has_list_item(cpu_features, "neon"))
|
||||
g_cpuFeatures |= CPU_ARM_FEATURE_NEON | CPU_ARM_FEATURE_VFPv3;
|
||||
}
|
||||
|
||||
if (cpu_features)
|
||||
free(cpu_features);
|
||||
if (cpu_arch)
|
||||
free(cpu_arch);
|
||||
if (buf)
|
||||
free(buf);
|
||||
cpu_features = NULL;
|
||||
cpu_arch = NULL;
|
||||
buf = NULL;
|
||||
}
|
||||
cpu_inited_once = true;
|
||||
}
|
||||
|
||||
cpu_flags = g_cpuFeatures;
|
||||
|
||||
if (cpu_flags & CPU_ARM_FEATURE_NEON)
|
||||
{
|
||||
cpu |= RETRO_SIMD_NEON;
|
||||
#ifdef __ARM_NEON__
|
||||
arm_enable_runfast_mode();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (cpu_flags & CPU_ARM_FEATURE_VFPv3)
|
||||
cpu |= RETRO_SIMD_VFPV3;
|
||||
|
||||
#elif defined(__ARM_NEON__)
|
||||
cpu |= RETRO_SIMD_NEON;
|
||||
arm_enable_runfast_mode();
|
||||
#elif defined(__ALTIVEC__)
|
||||
cpu |= RETRO_SIMD_VMX;
|
||||
#elif defined(XBOX360)
|
||||
cpu |= RETRO_SIMD_VMX128;
|
||||
#elif defined(PSP)
|
||||
cpu |= RETRO_SIMD_VFPU;
|
||||
#elif defined(GEKKO)
|
||||
cpu |= RETRO_SIMD_PS;
|
||||
#endif
|
||||
|
||||
if (cpu & RETRO_SIMD_MMX) strlcat(buf, " MMX", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_MMXEXT) strlcat(buf, " MMXEXT", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_SSE) strlcat(buf, " SSE", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_SSE2) strlcat(buf, " SSE2", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_SSE3) strlcat(buf, " SSE3", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_SSSE3) strlcat(buf, " SSSE3", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_SSE4) strlcat(buf, " SSE4", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_SSE42) strlcat(buf, " SSE4.2", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_AES) strlcat(buf, " AES", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_AVX) strlcat(buf, " AVX", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_AVX2) strlcat(buf, " AVX2", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_NEON) strlcat(buf, " NEON", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_VFPV3) strlcat(buf, " VFPv3", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_VFPV4) strlcat(buf, " VFPv4", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_VMX) strlcat(buf, " VMX", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_VMX128) strlcat(buf, " VMX128", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_VFPU) strlcat(buf, " VFPU", sizeof(buf));
|
||||
if (cpu & RETRO_SIMD_PS) strlcat(buf, " PS", sizeof(buf));
|
||||
|
||||
return cpu;
|
||||
}
|
|
@ -158,7 +158,7 @@ const char *retro_dirent_get_name(struct RDIR *rdir)
|
|||
* Returns: true if directory listing entry is
|
||||
* a directory, false if not.
|
||||
*/
|
||||
bool retro_dirent_is_dir(struct RDIR *rdir)
|
||||
bool retro_dirent_is_dir(struct RDIR *rdir, const char *path)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
const WIN32_FIND_DATA *entry = (const WIN32_FIND_DATA*)&rdir->entry;
|
||||
|
@ -174,18 +174,15 @@ bool retro_dirent_is_dir(struct RDIR *rdir)
|
|||
CellFsDirent *entry = (CellFsDirent*)&rdir->entry;
|
||||
return (entry->d_type == CELL_FS_TYPE_DIRECTORY);
|
||||
#elif defined(DT_DIR)
|
||||
const char *path = NULL;
|
||||
const struct dirent *entry = (const struct dirent*)rdir->entry;
|
||||
if (entry->d_type == DT_DIR)
|
||||
return true;
|
||||
/* This can happen on certain file systems. */
|
||||
path = retro_dirent_get_name(rdir);
|
||||
if (entry->d_type == DT_UNKNOWN || entry->d_type == DT_LNK)
|
||||
return path_is_directory(path);
|
||||
return false;
|
||||
#else
|
||||
/* dirent struct doesn't have d_type, do it the slow way ... */
|
||||
const char *path = retro_dirent_get_name(rdir);
|
||||
return path_is_directory(path);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,3 +1,25 @@
|
|||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rjpeg.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Modified version of stb_image's JPEG sources.
|
||||
*/
|
||||
|
||||
|
@ -11,6 +33,7 @@
|
|||
#include <retro_inline.h>
|
||||
#include <boolean.h>
|
||||
#include <formats/image.h>
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -88,51 +111,19 @@ typedef struct
|
|||
#include <emmintrin.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#if _MSC_VER >= 1400 /* not VC6 */
|
||||
#include <intrin.h> /* __cpuid */
|
||||
static int rjpeg__cpuid3(void)
|
||||
{
|
||||
int info[4];
|
||||
__cpuid(info,1);
|
||||
return info[3];
|
||||
}
|
||||
#else
|
||||
static int rjpeg__cpuid3(void)
|
||||
{
|
||||
int res;
|
||||
__asm {
|
||||
mov eax,1
|
||||
cpuid
|
||||
mov res,edx
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define RJPEG_SIMD_ALIGN(type, name) __declspec(align(16)) type name
|
||||
|
||||
static int rjpeg__sse2_available(void)
|
||||
{
|
||||
int info3 = rjpeg__cpuid3();
|
||||
return ((info3 >> 26) & 1) != 0;
|
||||
}
|
||||
#else /* assume GCC-style if not VC++ */
|
||||
#define RJPEG_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
|
||||
|
||||
static int rjpeg__sse2_available(void)
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 /* GCC 4.8 or later */
|
||||
/* GCC 4.8+ has a nice way to do this */
|
||||
return __builtin_cpu_supports("sse2");
|
||||
#else
|
||||
/* portable way to do this, preferably without using GCC inline ASM?
|
||||
* just bail for now. */
|
||||
#define RJPEG_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
|
||||
#endif
|
||||
|
||||
static int rjpeg__sse2_available(void)
|
||||
{
|
||||
uint64_t mask = cpu_features_get();
|
||||
if (mask & RETRO_SIMD_SSE2)
|
||||
return 1;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* ARM NEON */
|
||||
#if defined(RJPEG_NO_SIMD) && defined(RJPEG_NEON)
|
||||
|
@ -2453,7 +2444,9 @@ bool rjpeg_image_load(uint8_t *_buf, void *data, size_t size,
|
|||
unsigned a_shift, unsigned r_shift,
|
||||
unsigned g_shift, unsigned b_shift)
|
||||
{
|
||||
int x, y, comp;
|
||||
int comp;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
struct texture_image *out_img = (struct texture_image*)data;
|
||||
|
||||
out_img->pixels = (uint32_t*)rjpeg_load_from_memory(_buf, size, &x, &y, &comp, 4);
|
||||
|
|
10
libretro-common/glsym/glsym_es3.c
Normal file
10
libretro-common/glsym/glsym_es3.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "glsym.h"
|
||||
#include <stddef.h>
|
||||
#define SYM(x) { "gl" #x, &(gl##x) }
|
||||
const struct rglgen_sym_map rglgen_symbol_map[] = {
|
||||
|
||||
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
|
72
libretro-common/include/features/features_cpu.h
Normal file
72
libretro-common/include/features/features_cpu.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (features_cpu.h).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRETRO_SDK_CPU_INFO_H
|
||||
#define _LIBRETRO_SDK_CPU_INFO_H
|
||||
|
||||
#include <retro_common_api.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <libretro.h>
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
* cpu_features_get_perf_counter:
|
||||
*
|
||||
* Gets performance counter.
|
||||
*
|
||||
* Returns: performance counter.
|
||||
**/
|
||||
retro_perf_tick_t cpu_features_get_perf_counter(void);
|
||||
|
||||
/**
|
||||
* cpu_features_get_time_usec:
|
||||
*
|
||||
* Gets time in microseconds. *
|
||||
* Returns: time in microseconds.
|
||||
**/
|
||||
retro_time_t cpu_features_get_time_usec(void);
|
||||
|
||||
/**
|
||||
* cpu_features_get:
|
||||
*
|
||||
* Gets CPU features..
|
||||
*
|
||||
* Returns: bitmask of all CPU features available.
|
||||
**/
|
||||
uint64_t cpu_features_get(void);
|
||||
|
||||
/**
|
||||
* cpu_features_get_core_amount:
|
||||
*
|
||||
* Gets the amount of available CPU cores.
|
||||
*
|
||||
* Returns: amount of CPU cores available.
|
||||
**/
|
||||
unsigned cpu_features_get_core_amount(void);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2015 - Daniel De Matteis
|
||||
* Copyright (C) 2011-2016 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (jsonsax.h).
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rjpeg.h).
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2010-2015 The RetroArch team
|
||||
/* Copyright (C) 2010-2016 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (rxml.h).
|
||||
|
|
35
libretro-common/include/glsym/glsym_es3.h
Normal file
35
libretro-common/include/glsym/glsym_es3.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef RGLGEN_DECL_H__
|
||||
#define RGLGEN_DECL_H__
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifdef GL_APIENTRY
|
||||
typedef void (GL_APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);
|
||||
#else
|
||||
#ifndef APIENTRY
|
||||
#define APIENTRY
|
||||
#endif
|
||||
#ifndef APIENTRYP
|
||||
#define APIENTRYP APIENTRY *
|
||||
#endif
|
||||
typedef void (APIENTRY *RGLGENGLDEBUGPROCARB)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);
|
||||
typedef void (APIENTRY *RGLGENGLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum, GLsizei, const GLchar*, GLvoid*);
|
||||
#endif
|
||||
#ifndef GL_OES_EGL_image
|
||||
typedef void *GLeglImageOES;
|
||||
#endif
|
||||
#if !defined(GL_OES_fixed_point) && !defined(HAVE_OPENGLES2)
|
||||
typedef GLint GLfixed;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct rglgen_sym_map { const char *sym; void *ptr; };
|
||||
extern const struct rglgen_sym_map rglgen_symbol_map[];
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -23,7 +23,7 @@
|
|||
#ifndef LIBRETRO_VULKAN_H__
|
||||
#define LIBRETRO_VULKAN_H__
|
||||
|
||||
#include "libretro.h"
|
||||
#include <libretro.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#define RETRO_HW_RENDER_INTERFACE_VULKAN_VERSION 2
|
|
@ -49,7 +49,7 @@ const char *retro_dirent_get_name(struct RDIR *rdir);
|
|||
* Returns: true if directory listing entry is
|
||||
* a directory, false if not.
|
||||
*/
|
||||
bool retro_dirent_is_dir(struct RDIR *rdir);
|
||||
bool retro_dirent_is_dir(struct RDIR *rdir, const char *path);
|
||||
|
||||
void retro_closedir(struct RDIR *rdir);
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ struct string_list *dir_list_new(const char *dir,
|
|||
const char *file_ext = path_get_extension(name);
|
||||
|
||||
fill_pathname_join(file_path, dir, name, sizeof(file_path));
|
||||
is_dir = retro_dirent_is_dir(entry);
|
||||
is_dir = retro_dirent_is_dir(entry, file_path);
|
||||
|
||||
ret = parse_dir_entry(name, file_path, is_dir,
|
||||
include_dirs, include_compressed, list, ext_list, file_ext);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <retro_miscellaneous.h>
|
||||
#include <string/stdstring.h>
|
||||
|
||||
#include "../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
#include "core_option_manager.h"
|
||||
|
||||
|
|
|
@ -772,7 +772,7 @@ static int generic_action_ok(const char *path,
|
|||
flush_type = MENU_SETTINGS;
|
||||
menu_display_set_msg_force(true);
|
||||
|
||||
if (rarch_ctl(RARCH_CTL_REPLACE_CONFIG, action_path))
|
||||
if (retroarch_replace_config(action_path))
|
||||
{
|
||||
bool pending_push = false;
|
||||
menu_navigation_ctl(MENU_NAVIGATION_CTL_CLEAR, &pending_push);
|
||||
|
@ -1259,6 +1259,7 @@ static int action_ok_save_state(const char *path,
|
|||
}
|
||||
|
||||
#ifdef HAVE_NETWORKING
|
||||
#ifdef HAVE_ZLIB
|
||||
static void cb_decompressed(void *task_data, void *user_data, const char *err)
|
||||
{
|
||||
decompress_task_data_t *dec = (decompress_task_data_t*)task_data;
|
||||
|
@ -1289,6 +1290,7 @@ static void cb_decompressed(void *task_data, void *user_data, const char *err)
|
|||
free(dec);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* expects http_transfer_t*, menu_file_transfer_t* */
|
||||
static void cb_generic_download(void *task_data,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <compat/strl.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#include "menu_generic.h"
|
||||
|
||||
|
@ -28,7 +29,6 @@
|
|||
#include "../menu_entries.h"
|
||||
|
||||
#include "../../configuration.h"
|
||||
#include "../../performance.h"
|
||||
#include "../../performance_counters.h"
|
||||
#include "../../input/input_autodetect.h"
|
||||
#include "../../input/input_config.h"
|
||||
|
|
|
@ -352,7 +352,9 @@ const char *menu_hash_to_str_it(uint32_t hash)
|
|||
case MENU_LABEL_VALUE_PAUSE_NONACTIVE:
|
||||
return "Non caricare in background";
|
||||
case MENU_LABEL_VALUE_UI_COMPANION_START_ON_BOOT:
|
||||
return "Avvia UI Companion all'avvio";
|
||||
return "Abilita UI Companion all'avvio";
|
||||
case MENU_LABEL_VALUE_UI_COMPANION_ENABLE:
|
||||
return "Abilita UI Companion";
|
||||
case MENU_LABEL_VALUE_UI_MENUBAR_ENABLE:
|
||||
return "Barra dei menù";
|
||||
case MENU_LABEL_VALUE_ARCHIVE_MODE:
|
||||
|
@ -587,8 +589,10 @@ const char *menu_hash_to_str_it(uint32_t hash)
|
|||
return "Settaggi";
|
||||
case MENU_LABEL_VALUE_QUIT_RETROARCH:
|
||||
return "Esci da RetroArch";
|
||||
case MENU_LABEL_VALUE_SHUTDOWN:
|
||||
case MENU_LABEL_VALUE_SHUTDOWN:
|
||||
return "Spegni";
|
||||
case MENU_LABEL_VALUE_REBOOT:
|
||||
return "Riavvia";
|
||||
case MENU_LABEL_VALUE_HELP:
|
||||
return "Aiuto";
|
||||
case MENU_LABEL_VALUE_SAVE_NEW_CONFIG:
|
||||
|
@ -924,7 +928,7 @@ const char *menu_hash_to_str_it(uint32_t hash)
|
|||
case MENU_LABEL_VALUE_DIRECTORY_SETTINGS:
|
||||
return "Directory";
|
||||
case MENU_LABEL_VALUE_RECORDING_SETTINGS:
|
||||
return "Registrando";
|
||||
return "Registrazione";
|
||||
case MENU_LABEL_VALUE_NO_INFORMATION_AVAILABLE:
|
||||
return "Nessuna informazione disponibile.";
|
||||
case MENU_LABEL_VALUE_INPUT_USER_BINDS:
|
||||
|
@ -967,6 +971,12 @@ const char *menu_hash_to_str_it(uint32_t hash)
|
|||
return "Cerca:";
|
||||
case MENU_LABEL_VALUE_USE_BUILTIN_IMAGE_VIEWER:
|
||||
return "Usa visualizzatore di immagini interno";
|
||||
case MENU_LABEL_VALUE_ENABLE:
|
||||
return "Attivare";
|
||||
case MENU_LABEL_VALUE_START_CORE:
|
||||
return "Avvia Core";
|
||||
case MENU_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR:
|
||||
return "Tipo di ritardo";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -16,13 +16,14 @@
|
|||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
#include <encodings/utf.h>
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#include "menu_animation.h"
|
||||
#include "../configuration.h"
|
||||
#include "../performance.h"
|
||||
#include "../performance_counters.h"
|
||||
|
||||
#define IDEAL_DELTA_TIME (1.0 / 60.0 * 1000000.0)
|
||||
|
|
|
@ -619,7 +619,7 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info)
|
|||
strlcpy(tmp, menu_hash_to_str(MENU_LABEL_VALUE_SYSTEM_INFO_GIT_VERSION),
|
||||
sizeof(tmp));
|
||||
strlcat(tmp, ": ", sizeof(tmp));
|
||||
strlcat(tmp, rarch_git_version, sizeof(tmp));
|
||||
strlcat(tmp, retroarch_git_version, sizeof(tmp));
|
||||
menu_entries_add(info->list, tmp, "",
|
||||
MENU_SETTINGS_CORE_INFO_NONE, 0, 0);
|
||||
#endif
|
||||
|
|
|
@ -761,7 +761,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
|
|||
if (!latch)
|
||||
return false;
|
||||
|
||||
if (menu_driver_ctx->toggle)
|
||||
if (menu_driver_ctx && menu_driver_ctx->toggle)
|
||||
menu_driver_ctx->toggle(menu_userdata, *latch);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#include "menu_driver.h"
|
||||
#include "menu_input.h"
|
||||
#include "menu_animation.h"
|
||||
|
@ -39,7 +41,6 @@
|
|||
|
||||
#include "../general.h"
|
||||
#include "../managers/cheat_manager.h"
|
||||
#include "../performance.h"
|
||||
#include "../performance_counters.h"
|
||||
#include "../core.h"
|
||||
#include "../input/input_joypad_driver.h"
|
||||
|
|
|
@ -3638,7 +3638,7 @@ static bool setting_append_list(
|
|||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group);
|
||||
menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_QUIT_RETROARCH);
|
||||
menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_QUIT);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LAKKA)
|
||||
|
@ -4594,7 +4594,7 @@ static bool setting_append_list(
|
|||
&subgroup_info,
|
||||
parent_group);
|
||||
|
||||
#if defined(HAVE_THREADS) && !defined(RARCH_CONSOLE)
|
||||
#if defined(HAVE_THREADS)
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->video.threaded,
|
||||
|
@ -5454,7 +5454,6 @@ static bool setting_append_list(
|
|||
&subgroup_info,
|
||||
parent_group);
|
||||
|
||||
#ifndef RARCH_CONSOLE
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->video.font_enable,
|
||||
|
@ -5468,7 +5467,6 @@ static bool setting_append_list(
|
|||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler);
|
||||
#endif
|
||||
|
||||
CONFIG_PATH(
|
||||
list, list_info,
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <net/net_http.h>
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#include "../performance.h"
|
||||
#include "../performance_counters.h"
|
||||
#include "net_http_special.h"
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#ifndef __NET_HTTP_SPECIAL_H
|
||||
#define __NET_HTTP_SPECIAL_H
|
||||
|
||||
#include "../libretro.h"
|
||||
#include <libretro.h>
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -589,7 +589,7 @@ int16_t input_state_net(unsigned port, unsigned device,
|
|||
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
/* Custom inet_ntop. Win32 doesn't seem to support this ... */
|
||||
void np_log_connection(const struct sockaddr_storage *their_addr,
|
||||
void netplay_log_connection(const struct sockaddr_storage *their_addr,
|
||||
unsigned slot, const char *nick)
|
||||
{
|
||||
union
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#include <boolean.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include "../libretro.h"
|
||||
#include "../core.h"
|
||||
|
||||
typedef struct netplay netplay_t;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include <net/net_socket.h>
|
||||
#include "../content.h"
|
||||
|
||||
bool np_get_nickname(netplay_t *netplay, int fd)
|
||||
bool netplay_get_nickname(netplay_t *netplay, int fd)
|
||||
{
|
||||
uint8_t nick_size;
|
||||
|
||||
|
@ -42,7 +42,7 @@ bool np_get_nickname(netplay_t *netplay, int fd)
|
|||
|
||||
return true;
|
||||
}
|
||||
bool np_send_nickname(netplay_t *netplay, int fd)
|
||||
bool netplay_send_nickname(netplay_t *netplay, int fd)
|
||||
{
|
||||
uint8_t nick_size = strlen(netplay->nick);
|
||||
|
||||
|
@ -61,7 +61,7 @@ bool np_send_nickname(netplay_t *netplay, int fd)
|
|||
return true;
|
||||
}
|
||||
|
||||
uint32_t *np_bsv_header_generate(size_t *size, uint32_t magic)
|
||||
uint32_t *netplay_bsv_header_generate(size_t *size, uint32_t magic)
|
||||
{
|
||||
retro_ctx_serialize_info_t serial_info;
|
||||
retro_ctx_size_info_t info;
|
||||
|
@ -100,7 +100,7 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool np_bsv_parse_header(const uint32_t *header, uint32_t magic)
|
||||
bool netplay_bsv_parse_header(const uint32_t *header, uint32_t magic)
|
||||
{
|
||||
retro_ctx_size_info_t info;
|
||||
uint32_t *content_crc_ptr;
|
||||
|
@ -146,7 +146,7 @@ bool np_bsv_parse_header(const uint32_t *header, uint32_t magic)
|
|||
}
|
||||
|
||||
/**
|
||||
* np_impl_magic:
|
||||
* netplay_impl_magic:
|
||||
*
|
||||
* Not really a hash, but should be enough to differentiate
|
||||
* implementations from each other.
|
||||
|
@ -155,7 +155,7 @@ bool np_bsv_parse_header(const uint32_t *header, uint32_t magic)
|
|||
* The alternative would have been checking serialization sizes, but it
|
||||
* was troublesome for cross platform compat.
|
||||
**/
|
||||
uint32_t np_impl_magic(void)
|
||||
uint32_t netplay_impl_magic(void)
|
||||
{
|
||||
size_t i, len;
|
||||
retro_ctx_api_info_t api_info;
|
||||
|
@ -193,7 +193,7 @@ uint32_t np_impl_magic(void)
|
|||
return res;
|
||||
}
|
||||
|
||||
bool np_send_info(netplay_t *netplay)
|
||||
bool netplay_send_info(netplay_t *netplay)
|
||||
{
|
||||
unsigned sram_size;
|
||||
retro_ctx_memory_info_t mem_info;
|
||||
|
@ -208,13 +208,13 @@ bool np_send_info(netplay_t *netplay)
|
|||
content_get_crc(&content_crc_ptr);
|
||||
|
||||
header[0] = htonl(*content_crc_ptr);
|
||||
header[1] = htonl(np_impl_magic());
|
||||
header[1] = htonl(netplay_impl_magic());
|
||||
header[2] = htonl(mem_info.size);
|
||||
|
||||
if (!socket_send_all_blocking(netplay->fd, header, sizeof(header), false))
|
||||
return false;
|
||||
|
||||
if (!np_send_nickname(netplay, netplay->fd))
|
||||
if (!netplay_send_nickname(netplay, netplay->fd))
|
||||
{
|
||||
RARCH_ERR("Failed to send nick to host.\n");
|
||||
return false;
|
||||
|
@ -230,7 +230,7 @@ bool np_send_info(netplay_t *netplay)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!np_get_nickname(netplay, netplay->fd))
|
||||
if (!netplay_get_nickname(netplay, netplay->fd))
|
||||
{
|
||||
RARCH_ERR("Failed to receive nick from host.\n");
|
||||
return false;
|
||||
|
@ -243,7 +243,7 @@ bool np_send_info(netplay_t *netplay)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool np_get_info(netplay_t *netplay)
|
||||
bool netplay_get_info(netplay_t *netplay)
|
||||
{
|
||||
unsigned sram_size;
|
||||
uint32_t header[3];
|
||||
|
@ -265,7 +265,7 @@ bool np_get_info(netplay_t *netplay)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (np_impl_magic() != ntohl(header[1]))
|
||||
if (netplay_impl_magic() != ntohl(header[1]))
|
||||
{
|
||||
RARCH_ERR("Implementations differ, make sure you're using exact same "
|
||||
"libretro implementations and RetroArch version.\n");
|
||||
|
@ -282,7 +282,7 @@ bool np_get_info(netplay_t *netplay)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!np_get_nickname(netplay, netplay->fd))
|
||||
if (!netplay_get_nickname(netplay, netplay->fd))
|
||||
{
|
||||
RARCH_ERR("Failed to get nickname from client.\n");
|
||||
return false;
|
||||
|
@ -298,27 +298,27 @@ bool np_get_info(netplay_t *netplay)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!np_send_nickname(netplay, netplay->fd))
|
||||
if (!netplay_send_nickname(netplay, netplay->fd))
|
||||
{
|
||||
RARCH_ERR("Failed to send nickname to client.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
np_log_connection(&netplay->other_addr, 0, netplay->other_nick);
|
||||
netplay_log_connection(&netplay->other_addr, 0, netplay->other_nick);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool np_is_server(netplay_t* netplay)
|
||||
bool netplay_is_server(netplay_t* netplay)
|
||||
{
|
||||
if (!netplay)
|
||||
return false;
|
||||
return netplay->is_server;
|
||||
}
|
||||
|
||||
bool np_is_spectate(netplay_t* netplay)
|
||||
bool netplay_is_spectate(netplay_t* netplay)
|
||||
{
|
||||
if (!netplay)
|
||||
return false;
|
||||
|
|
|
@ -137,14 +137,14 @@ static bool netplay_net_init_buffers(netplay_t *netplay)
|
|||
|
||||
static bool netplay_net_info_cb(netplay_t* netplay, unsigned frames)
|
||||
{
|
||||
if (np_is_server(netplay))
|
||||
if (netplay_is_server(netplay))
|
||||
{
|
||||
if (!np_send_info(netplay))
|
||||
if (!netplay_send_info(netplay))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!np_get_info(netplay))
|
||||
if (!netplay_get_info(netplay))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#ifndef __RARCH_NETPLAY_PRIVATE_H
|
||||
#define __RARCH_NETPLAY_PRIVATE_H
|
||||
|
||||
#include "netplay.h"
|
||||
|
||||
#include <net/net_compat.h>
|
||||
|
@ -138,17 +139,18 @@ extern void *netplay_data;
|
|||
|
||||
struct netplay_callbacks* netplay_get_cbs_net(void);
|
||||
struct netplay_callbacks* netplay_get_cbs_spectate(void);
|
||||
void np_log_connection(const struct sockaddr_storage *their_addr,
|
||||
void netplay_log_connection(const struct sockaddr_storage *their_addr,
|
||||
unsigned slot, const char *nick);
|
||||
|
||||
bool np_get_nickname(netplay_t *netplay, int fd);
|
||||
bool np_send_nickname(netplay_t *netplay, int fd);
|
||||
bool np_send_info(netplay_t *netplay);
|
||||
uint32_t *np_bsv_header_generate(size_t *size, uint32_t magic);
|
||||
bool np_bsv_parse_header(const uint32_t *header, uint32_t magic);
|
||||
uint32_t np_impl_magic(void);
|
||||
bool np_send_info(netplay_t *netplay);
|
||||
bool np_get_info(netplay_t *netplay);
|
||||
bool np_is_server(netplay_t* netplay);
|
||||
bool np_is_spectate(netplay_t* netplay);
|
||||
bool netplay_get_nickname(netplay_t *netplay, int fd);
|
||||
bool netplay_send_nickname(netplay_t *netplay, int fd);
|
||||
bool netplay_send_info(netplay_t *netplay);
|
||||
uint32_t *netplay_bsv_header_generate(size_t *size, uint32_t magic);
|
||||
bool netplay_bsv_parse_header(const uint32_t *header, uint32_t magic);
|
||||
uint32_t netplay_impl_magic(void);
|
||||
bool netplay_send_info(netplay_t *netplay);
|
||||
bool netplay_get_info(netplay_t *netplay);
|
||||
bool netplay_is_server(netplay_t* netplay);
|
||||
bool netplay_is_spectate(netplay_t* netplay);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -41,7 +41,7 @@ static void netplay_spectate_pre_frame(netplay_t *netplay)
|
|||
fd_set fds;
|
||||
struct timeval tmp_tv = {0};
|
||||
|
||||
if (!np_is_server(netplay))
|
||||
if (!netplay_is_server(netplay))
|
||||
return;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
|
@ -78,22 +78,22 @@ static void netplay_spectate_pre_frame(netplay_t *netplay)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!np_get_nickname(netplay, new_fd))
|
||||
if (!netplay_get_nickname(netplay, new_fd))
|
||||
{
|
||||
RARCH_ERR("Failed to get nickname from client.\n");
|
||||
socket_close(new_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!np_send_nickname(netplay, new_fd))
|
||||
if (!netplay_send_nickname(netplay, new_fd))
|
||||
{
|
||||
RARCH_ERR("Failed to send nickname to client.\n");
|
||||
socket_close(new_fd);
|
||||
return;
|
||||
}
|
||||
|
||||
header = np_bsv_header_generate(&header_size,
|
||||
np_impl_magic());
|
||||
header = netplay_bsv_header_generate(&header_size,
|
||||
netplay_impl_magic());
|
||||
|
||||
if (!header)
|
||||
{
|
||||
|
@ -118,7 +118,7 @@ static void netplay_spectate_pre_frame(netplay_t *netplay)
|
|||
netplay->spectate.fds[idx] = new_fd;
|
||||
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
np_log_connection(&their_addr, idx, netplay->other_nick);
|
||||
netplay_log_connection(&their_addr, idx, netplay->other_nick);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ static void netplay_spectate_post_frame(netplay_t *netplay)
|
|||
{
|
||||
unsigned i;
|
||||
|
||||
if (!np_is_server(netplay))
|
||||
if (!netplay_is_server(netplay))
|
||||
return;
|
||||
|
||||
for (i = 0; i < MAX_SPECTATORS; i++)
|
||||
|
@ -165,9 +165,9 @@ static void netplay_spectate_post_frame(netplay_t *netplay)
|
|||
static bool netplay_spectate_info_cb(netplay_t *netplay, unsigned frames)
|
||||
{
|
||||
unsigned i;
|
||||
if(np_is_server(netplay))
|
||||
if(netplay_is_server(netplay))
|
||||
{
|
||||
if(!np_get_info(netplay))
|
||||
if(!netplay_get_info(netplay))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
566
performance.c
566
performance.c
|
@ -1,566 +0,0 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2016 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "libretro.h"
|
||||
#include "performance.h"
|
||||
#include "general.h"
|
||||
#include "compat/strl.h"
|
||||
#include "verbosity.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define PERF_LOG_FMT "[PERF]: Avg (%s): %I64u ticks, %I64u runs.\n"
|
||||
#else
|
||||
#define PERF_LOG_FMT "[PERF]: Avg (%s): %llu ticks, %llu runs.\n"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#if defined(__CELLOS_LV2__)
|
||||
#ifndef _PPU_INTRINSICS_H
|
||||
#include <ppu_intrinsics.h>
|
||||
#endif
|
||||
#elif defined(_XBOX360)
|
||||
#include <PPCIntrinsics.h>
|
||||
#elif defined(_POSIX_MONOTONIC_CLOCK) || defined(ANDROID) || defined(__QNX__)
|
||||
/* POSIX_MONOTONIC_CLOCK is not being defined in Android headers despite support being present. */
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if defined(__QNX__) && !defined(CLOCK_MONOTONIC)
|
||||
#define CLOCK_MONOTONIC 2
|
||||
#endif
|
||||
|
||||
#if defined(PSP)
|
||||
#include <sys/time.h>
|
||||
#include <psprtc.h>
|
||||
#endif
|
||||
|
||||
#if defined(VITA)
|
||||
#include <psp2/kernel/processmgr.h>
|
||||
#include <psp2/rtc.h>
|
||||
#endif
|
||||
|
||||
#if defined(__PSL1GHT__)
|
||||
#include <sys/time.h>
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
#include <sys/sys_time.h>
|
||||
#endif
|
||||
|
||||
#ifdef GEKKO
|
||||
#include <ogc/lwp_watchdog.h>
|
||||
#endif
|
||||
|
||||
/* iOS/OSX specific. Lacks clock_gettime(), so implement it. */
|
||||
#ifdef __MACH__
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef CLOCK_MONOTONIC
|
||||
#define CLOCK_MONOTONIC 0
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_REALTIME
|
||||
#define CLOCK_REALTIME 0
|
||||
#endif
|
||||
|
||||
static int clock_gettime(int clk_ik, struct timespec *t)
|
||||
{
|
||||
struct timeval now;
|
||||
int rv = gettimeofday(&now, NULL);
|
||||
if (rv)
|
||||
return rv;
|
||||
t->tv_sec = now.tv_sec;
|
||||
t->tv_nsec = now.tv_usec * 1000;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EMSCRIPTEN
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
|
||||
#if defined(BSD) || defined(__APPLE__)
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
#include "frontend/drivers/platform_linux.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cpu_features_get_perf_counter:
|
||||
*
|
||||
* Gets performance counter.
|
||||
*
|
||||
* Returns: performance counter.
|
||||
**/
|
||||
retro_perf_tick_t cpu_features_get_perf_counter(void)
|
||||
{
|
||||
retro_perf_tick_t time_ticks = 0;
|
||||
#if defined(__linux__) || defined(__QNX__) || defined(__MACH__)
|
||||
struct timespec tv;
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tv) == 0)
|
||||
time_ticks = (retro_perf_tick_t)tv.tv_sec * 1000000000 +
|
||||
(retro_perf_tick_t)tv.tv_nsec;
|
||||
|
||||
#elif defined(__GNUC__) && defined(__i386__) || defined(__i486__) || defined(__i686__)
|
||||
__asm__ volatile ("rdtsc" : "=A" (time_ticks));
|
||||
#elif defined(__GNUC__) && defined(__x86_64__)
|
||||
unsigned a, d;
|
||||
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
|
||||
time_ticks = (retro_perf_tick_t)a | ((retro_perf_tick_t)d << 32);
|
||||
#elif defined(__ARM_ARCH_6__)
|
||||
__asm__ volatile( "mrc p15, 0, %0, c9, c13, 0" : "=r"(time_ticks) );
|
||||
#elif defined(__CELLOS_LV2__) || defined(_XBOX360) || defined(__powerpc__) || defined(__ppc__) || defined(__POWERPC__)
|
||||
time_ticks = __mftb();
|
||||
#elif defined(GEKKO)
|
||||
time_ticks = gettime();
|
||||
#elif defined(PSP) || defined(VITA)
|
||||
sceRtcGetCurrentTick(&time_ticks);
|
||||
#elif defined(_3DS)
|
||||
time_ticks = svcGetSystemTick();
|
||||
#elif defined(__mips__)
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv,NULL);
|
||||
time_ticks = (1000000 * tv.tv_sec + tv.tv_usec);
|
||||
#elif defined(_WIN32)
|
||||
long tv_sec, tv_usec;
|
||||
static const unsigned __int64 epoch = 11644473600000000Ui64;
|
||||
FILETIME file_time;
|
||||
SYSTEMTIME system_time;
|
||||
ULARGE_INTEGER ularge;
|
||||
|
||||
GetSystemTime(&system_time);
|
||||
SystemTimeToFileTime(&system_time, &file_time);
|
||||
ularge.LowPart = file_time.dwLowDateTime;
|
||||
ularge.HighPart = file_time.dwHighDateTime;
|
||||
|
||||
tv_sec = (long)((ularge.QuadPart - epoch) / 10000000L);
|
||||
tv_usec = (long)(system_time.wMilliseconds * 1000);
|
||||
|
||||
time_ticks = (1000000 * tv_sec + tv_usec);
|
||||
#endif
|
||||
|
||||
return time_ticks;
|
||||
}
|
||||
|
||||
/**
|
||||
* cpu_features_get_time_usec:
|
||||
*
|
||||
* Gets time in microseconds.
|
||||
*
|
||||
* Returns: time in microseconds.
|
||||
**/
|
||||
retro_time_t cpu_features_get_time_usec(void)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
static LARGE_INTEGER freq;
|
||||
LARGE_INTEGER count;
|
||||
|
||||
/* Frequency is guaranteed to not change. */
|
||||
if (!freq.QuadPart && !QueryPerformanceFrequency(&freq))
|
||||
return 0;
|
||||
|
||||
if (!QueryPerformanceCounter(&count))
|
||||
return 0;
|
||||
return count.QuadPart * 1000000 / freq.QuadPart;
|
||||
#elif defined(__CELLOS_LV2__)
|
||||
return sys_time_get_system_time();
|
||||
#elif defined(GEKKO)
|
||||
return ticks_to_microsecs(gettime());
|
||||
#elif defined(_POSIX_MONOTONIC_CLOCK) || defined(__QNX__) || defined(ANDROID) || defined(__MACH__)
|
||||
struct timespec tv = {0};
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &tv) < 0)
|
||||
return 0;
|
||||
return tv.tv_sec * INT64_C(1000000) + (tv.tv_nsec + 500) / 1000;
|
||||
#elif defined(EMSCRIPTEN)
|
||||
return emscripten_get_now() * 1000;
|
||||
#elif defined(__mips__)
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv,NULL);
|
||||
return (1000000 * tv.tv_sec + tv.tv_usec);
|
||||
#elif defined(_3DS)
|
||||
return osGetTime() * 1000;
|
||||
#elif defined(VITA)
|
||||
return sceKernelGetProcessTimeWide();
|
||||
#else
|
||||
#error "Your platform does not have a timer function implemented in cpu_features_get_time_usec(). Cannot continue."
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__i486__) || defined(__i686__)
|
||||
#define CPU_X86
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_XBOX)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#if defined(CPU_X86) && !defined(__MACH__)
|
||||
void x86_cpuid(int func, int flags[4])
|
||||
{
|
||||
/* On Android, we compile RetroArch with PIC, and we
|
||||
* are not allowed to clobber the ebx register. */
|
||||
#ifdef __x86_64__
|
||||
#define REG_b "rbx"
|
||||
#define REG_S "rsi"
|
||||
#else
|
||||
#define REG_b "ebx"
|
||||
#define REG_S "esi"
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__asm__ volatile (
|
||||
"mov %%" REG_b ", %%" REG_S "\n"
|
||||
"cpuid\n"
|
||||
"xchg %%" REG_b ", %%" REG_S "\n"
|
||||
: "=a"(flags[0]), "=S"(flags[1]), "=c"(flags[2]), "=d"(flags[3])
|
||||
: "a"(func));
|
||||
#elif defined(_MSC_VER)
|
||||
__cpuid(flags, func);
|
||||
#else
|
||||
printf("Unknown compiler. Cannot check CPUID with inline assembly.\n");
|
||||
memset(flags, 0, 4 * sizeof(int));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Only runs on i686 and above. Needs to be conditionally run. */
|
||||
static uint64_t xgetbv_x86(uint32_t idx)
|
||||
{
|
||||
#if defined(__GNUC__)
|
||||
uint32_t eax, edx;
|
||||
__asm__ volatile (
|
||||
/* Older GCC versions (Apple's GCC for example) do
|
||||
* not understand xgetbv instruction.
|
||||
* Stamp out the machine code directly.
|
||||
*/
|
||||
".byte 0x0f, 0x01, 0xd0\n"
|
||||
: "=a"(eax), "=d"(edx) : "c"(idx));
|
||||
return ((uint64_t)edx << 32) | eax;
|
||||
#elif _MSC_FULL_VER >= 160040219
|
||||
/* Intrinsic only works on 2010 SP1 and above. */
|
||||
return _xgetbv(idx);
|
||||
#else
|
||||
printf("Unknown compiler. Cannot check xgetbv bits.\n");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_NEON__)
|
||||
static void arm_enable_runfast_mode(void)
|
||||
{
|
||||
/* RunFast mode. Enables flush-to-zero and some
|
||||
* floating point optimizations. */
|
||||
static const unsigned x = 0x04086060;
|
||||
static const unsigned y = 0x03000000;
|
||||
int r;
|
||||
__asm__ volatile(
|
||||
"fmrx %0, fpscr \n\t" /* r0 = FPSCR */
|
||||
"and %0, %0, %1 \n\t" /* r0 = r0 & 0x04086060 */
|
||||
"orr %0, %0, %2 \n\t" /* r0 = r0 | 0x03000000 */
|
||||
"fmxr fpscr, %0 \n\t" /* FPSCR = r0 */
|
||||
: "=r"(r)
|
||||
: "r"(x), "r"(y)
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cpu_features_get_core_amount:
|
||||
*
|
||||
* Gets the amount of available CPU cores.
|
||||
*
|
||||
* Returns: amount of CPU cores available.
|
||||
**/
|
||||
unsigned cpu_features_get_core_amount(void)
|
||||
{
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
/* Win32 */
|
||||
SYSTEM_INFO sysinfo;
|
||||
GetSystemInfo(&sysinfo);
|
||||
return sysinfo.dwNumberOfProcessors;
|
||||
#elif defined(GEKKO)
|
||||
return 1;
|
||||
#elif defined(PSP)
|
||||
return 1;
|
||||
#elif defined(VITA)
|
||||
return 4;
|
||||
#elif defined(_3DS)
|
||||
return 1;
|
||||
#elif defined(_SC_NPROCESSORS_ONLN)
|
||||
/* Linux, most UNIX-likes. */
|
||||
long ret = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
if (ret <= 0)
|
||||
return (unsigned)1;
|
||||
return ret;
|
||||
#elif defined(BSD) || defined(__APPLE__)
|
||||
/* BSD */
|
||||
/* Copypasta from stackoverflow, dunno if it works. */
|
||||
int num_cpu = 0;
|
||||
int mib[4];
|
||||
size_t len = sizeof(num_cpu);
|
||||
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_AVAILCPU;
|
||||
sysctl(mib, 2, &num_cpu, &len, NULL, 0);
|
||||
if (num_cpu < 1)
|
||||
{
|
||||
mib[1] = HW_NCPU;
|
||||
sysctl(mib, 2, &num_cpu, &len, NULL, 0);
|
||||
if (num_cpu < 1)
|
||||
num_cpu = 1;
|
||||
}
|
||||
return num_cpu;
|
||||
#elif defined(__linux__)
|
||||
return linux_get_cpu_count();
|
||||
#elif defined(_XBOX360)
|
||||
return 3;
|
||||
#else
|
||||
/* No idea, assume single core. */
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* According to http://en.wikipedia.org/wiki/CPUID */
|
||||
#define VENDOR_INTEL_b 0x756e6547
|
||||
#define VENDOR_INTEL_c 0x6c65746e
|
||||
#define VENDOR_INTEL_d 0x49656e69
|
||||
|
||||
/**
|
||||
* cpu_features_get:
|
||||
*
|
||||
* Gets CPU features..
|
||||
*
|
||||
* Returns: bitmask of all CPU features available.
|
||||
**/
|
||||
uint64_t cpu_features_get(void)
|
||||
{
|
||||
int flags[4];
|
||||
int vendor_shuffle[3];
|
||||
char vendor[13] = {0};
|
||||
size_t len = 0;
|
||||
uint64_t cpu_flags = 0;
|
||||
uint64_t cpu = 0;
|
||||
unsigned max_flag = 0;
|
||||
#if defined(CPU_X86) && !defined(__MACH__)
|
||||
int vendor_is_intel = 0;
|
||||
const int avx_flags = (1 << 27) | (1 << 28);
|
||||
#endif
|
||||
|
||||
char buf[sizeof(" MMX MMXEXT SSE SSE2 SSE3 SSSE3 SS4 SSE4.2 AES AVX AVX2 NEON VMX VMX128 VFPU PS")];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
(void)len;
|
||||
(void)cpu_flags;
|
||||
(void)flags;
|
||||
(void)max_flag;
|
||||
(void)vendor;
|
||||
(void)vendor_shuffle;
|
||||
|
||||
#if defined(__MACH__)
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.mmx", NULL, &len, NULL, 0) == 0)
|
||||
{
|
||||
cpu |= CPU_FEATURE_MMX;
|
||||
cpu |= CPU_FEATURE_MMXEXT;
|
||||
}
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= CPU_FEATURE_SSE;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse2", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= CPU_FEATURE_SSE2;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse3", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= CPU_FEATURE_SSE3;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.supplementalsse3", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= CPU_FEATURE_SSSE3;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse4_1", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= CPU_FEATURE_SSE4;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.sse4_2", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= CPU_FEATURE_SSE42;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.aes", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= CPU_FEATURE_AES;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.avx1_0", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= CPU_FEATURE_AVX;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.avx2_0", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= CPU_FEATURE_AVX2;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.altivec", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= CPU_FEATURE_VMX;
|
||||
|
||||
len = sizeof(size_t);
|
||||
if (sysctlbyname("hw.optional.neon", NULL, &len, NULL, 0) == 0)
|
||||
cpu |= CPU_FEATURE_NEON;
|
||||
|
||||
#elif defined(CPU_X86)
|
||||
(void)avx_flags;
|
||||
|
||||
x86_cpuid(0, flags);
|
||||
vendor_shuffle[0] = flags[1];
|
||||
vendor_shuffle[1] = flags[3];
|
||||
vendor_shuffle[2] = flags[2];
|
||||
memcpy(vendor, vendor_shuffle, sizeof(vendor_shuffle));
|
||||
|
||||
printf("[CPUID]: Vendor: %s\n", vendor);
|
||||
|
||||
vendor_is_intel = (
|
||||
flags[1] == VENDOR_INTEL_b &&
|
||||
flags[2] == VENDOR_INTEL_c &&
|
||||
flags[3] == VENDOR_INTEL_d);
|
||||
|
||||
max_flag = flags[0];
|
||||
if (max_flag < 1) /* Does CPUID not support func = 1? (unlikely ...) */
|
||||
return 0;
|
||||
|
||||
x86_cpuid(1, flags);
|
||||
|
||||
if (flags[3] & (1 << 23))
|
||||
cpu |= CPU_FEATURE_MMX;
|
||||
|
||||
if (flags[3] & (1 << 25))
|
||||
{
|
||||
/* SSE also implies MMXEXT (according to FFmpeg source). */
|
||||
cpu |= CPU_FEATURE_SSE;
|
||||
cpu |= CPU_FEATURE_MMXEXT;
|
||||
}
|
||||
|
||||
|
||||
if (flags[3] & (1 << 26))
|
||||
cpu |= CPU_FEATURE_SSE2;
|
||||
|
||||
if (flags[2] & (1 << 0))
|
||||
cpu |= CPU_FEATURE_SSE3;
|
||||
|
||||
if (flags[2] & (1 << 9))
|
||||
cpu |= CPU_FEATURE_SSSE3;
|
||||
|
||||
if (flags[2] & (1 << 19))
|
||||
cpu |= CPU_FEATURE_SSE4;
|
||||
|
||||
if (flags[2] & (1 << 20))
|
||||
cpu |= CPU_FEATURE_SSE42;
|
||||
|
||||
if ((flags[2] & (1 << 23)))
|
||||
cpu |= CPU_FEATURE_POPCNT;
|
||||
|
||||
if (vendor_is_intel && (flags[2] & (1 << 22)))
|
||||
cpu |= CPU_FEATURE_MOVBE;
|
||||
|
||||
if (flags[2] & (1 << 25))
|
||||
cpu |= CPU_FEATURE_AES;
|
||||
|
||||
|
||||
/* Must only perform xgetbv check if we have
|
||||
* AVX CPU support (guaranteed to have at least i686). */
|
||||
if (((flags[2] & avx_flags) == avx_flags)
|
||||
&& ((xgetbv_x86(0) & 0x6) == 0x6))
|
||||
cpu |= CPU_FEATURE_AVX;
|
||||
|
||||
if (max_flag >= 7)
|
||||
{
|
||||
x86_cpuid(7, flags);
|
||||
if (flags[1] & (1 << 5))
|
||||
cpu |= CPU_FEATURE_AVX2;
|
||||
}
|
||||
|
||||
x86_cpuid(0x80000000, flags);
|
||||
max_flag = flags[0];
|
||||
if (max_flag >= 0x80000001u)
|
||||
{
|
||||
x86_cpuid(0x80000001, flags);
|
||||
if (flags[3] & (1 << 23))
|
||||
cpu |= CPU_FEATURE_MMX;
|
||||
if (flags[3] & (1 << 22))
|
||||
cpu |= CPU_FEATURE_MMXEXT;
|
||||
}
|
||||
#elif defined(__linux__)
|
||||
cpu_flags = linux_get_cpu_features();
|
||||
|
||||
if (cpu_flags & CPU_ARM_FEATURE_NEON)
|
||||
{
|
||||
cpu |= CPU_FEATURE_NEON;
|
||||
#ifdef __ARM_NEON__
|
||||
arm_enable_runfast_mode();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (cpu_flags & CPU_ARM_FEATURE_VFPv3)
|
||||
cpu |= CPU_FEATURE_VFPV3;
|
||||
|
||||
#elif defined(__ARM_NEON__)
|
||||
cpu |= CPU_FEATURE_NEON;
|
||||
arm_enable_runfast_mode();
|
||||
#elif defined(__ALTIVEC__)
|
||||
cpu |= CPU_FEATURE_VMX;
|
||||
#elif defined(XBOX360)
|
||||
cpu |= CPU_FEATURE_VMX128;
|
||||
#elif defined(PSP)
|
||||
cpu |= CPU_FEATURE_VFPU;
|
||||
#elif defined(GEKKO)
|
||||
cpu |= CPU_FEATURE_PS;
|
||||
#endif
|
||||
|
||||
if (cpu & CPU_FEATURE_MMX) strlcat(buf, " MMX", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_MMXEXT) strlcat(buf, " MMXEXT", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_SSE) strlcat(buf, " SSE", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_SSE2) strlcat(buf, " SSE2", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_SSE3) strlcat(buf, " SSE3", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_SSSE3) strlcat(buf, " SSSE3", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_SSE4) strlcat(buf, " SSE4", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_SSE42) strlcat(buf, " SSE4.2", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_AES) strlcat(buf, " AES", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_AVX) strlcat(buf, " AVX", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_AVX2) strlcat(buf, " AVX2", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_NEON) strlcat(buf, " NEON", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_VFPV3) strlcat(buf, " VFPv3", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_VFPV4) strlcat(buf, " VFPv4", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_VMX) strlcat(buf, " VMX", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_VMX128) strlcat(buf, " VMX128", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_VFPU) strlcat(buf, " VFPU", sizeof(buf));
|
||||
if (cpu & CPU_FEATURE_PS) strlcat(buf, " PS", sizeof(buf));
|
||||
|
||||
return cpu;
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
||||
* Copyright (C) 2011-2016 - Daniel De Matteis
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRETRO_SDK_CPU_INFO_H
|
||||
#define _LIBRETRO_SDK_CPU_INFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef RARCH_INTERNAL
|
||||
#include "libretro.h"
|
||||
#else
|
||||
typedef uint64_t retro_perf_tick_t;
|
||||
typedef uint64_t retro_time_t;
|
||||
#endif
|
||||
|
||||
/* ID values for CPU features */
|
||||
#define CPU_FEATURE_SSE (1 << 0)
|
||||
#define CPU_FEATURE_SSE2 (1 << 1)
|
||||
#define CPU_FEATURE_VMX (1 << 2)
|
||||
#define CPU_FEATURE_VMX128 (1 << 3)
|
||||
#define CPU_FEATURE_AVX (1 << 4)
|
||||
#define CPU_FEATURE_NEON (1 << 5)
|
||||
#define CPU_FEATURE_SSE3 (1 << 6)
|
||||
#define CPU_FEATURE_SSSE3 (1 << 7)
|
||||
#define CPU_FEATURE_MMX (1 << 8)
|
||||
#define CPU_FEATURE_MMXEXT (1 << 9)
|
||||
#define CPU_FEATURE_SSE4 (1 << 10)
|
||||
#define CPU_FEATURE_SSE42 (1 << 11)
|
||||
#define CPU_FEATURE_AVX2 (1 << 12)
|
||||
#define CPU_FEATURE_VFPU (1 << 13)
|
||||
#define CPU_FEATURE_PS (1 << 14)
|
||||
#define CPU_FEATURE_AES (1 << 15)
|
||||
#define CPU_FEATURE_VFPV3 (1 << 16)
|
||||
#define CPU_FEATURE_VFPV4 (1 << 17)
|
||||
#define CPU_FEATURE_POPCNT (1 << 18)
|
||||
#define CPU_FEATURE_MOVBE (1 << 19)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* cpu_features_get_perf_counter:
|
||||
*
|
||||
* Gets performance counter.
|
||||
*
|
||||
* Returns: performance counter.
|
||||
**/
|
||||
retro_perf_tick_t cpu_features_get_perf_counter(void);
|
||||
|
||||
/**
|
||||
* cpu_features_get_time_usec:
|
||||
*
|
||||
* Gets time in microseconds. *
|
||||
* Returns: time in microseconds.
|
||||
**/
|
||||
retro_time_t cpu_features_get_time_usec(void);
|
||||
|
||||
/**
|
||||
* cpu_features_get:
|
||||
*
|
||||
* Gets CPU features..
|
||||
*
|
||||
* Returns: bitmask of all CPU features available.
|
||||
**/
|
||||
uint64_t cpu_features_get(void);
|
||||
|
||||
/**
|
||||
* cpu_features_get_core_amount:
|
||||
*
|
||||
* Gets the amount of available CPU cores.
|
||||
*
|
||||
* Returns: amount of CPU cores available.
|
||||
**/
|
||||
unsigned cpu_features_get_core_amount(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -17,7 +17,14 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "performance.h"
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <features/features_cpu.h>
|
||||
|
||||
#include "performance_counters.h"
|
||||
|
||||
#include "general.h"
|
||||
|
@ -30,10 +37,6 @@
|
|||
#define PERF_LOG_FMT "[PERF]: Avg (%s): %llu ticks, %llu runs.\n"
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32) && !defined(RARCH_CONSOLE)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
static struct retro_perf_counter *perf_counters_rarch[MAX_COUNTERS];
|
||||
static struct retro_perf_counter *perf_counters_libretro[MAX_COUNTERS];
|
||||
static unsigned perf_ptr_rarch;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue