diff --git a/desmume/src/libretro-common/features/features_cpu.c b/desmume/src/libretro-common/features/features_cpu.c index 9fa5617bf..b6286cca7 100644 --- a/desmume/src/libretro-common/features/features_cpu.c +++ b/desmume/src/libretro-common/features/features_cpu.c @@ -73,6 +73,16 @@ #include #endif +#ifdef WIIU +#include +#include "wiiu/system/wiiu.h" +#endif + +#if defined(_3DS) +#include <3ds/svc.h> +#include <3ds/os.h> +#endif + /* iOS/OSX specific. Lacks clock_gettime(), so implement it. */ #ifdef __MACH__ #include @@ -85,9 +95,8 @@ #define CLOCK_REALTIME 0 #endif -#if (__MAC_OS_X_VERSION_MAX_ALLOWED < 101200) && (__IPHONE_OS_VERSION_MAX_ALLOWED < 100000) -// this function is part of macOS 10.12 and iOS 10 now -static int clock_gettime(int clk_ik, struct timespec *t) +/* this function is part of iOS 10 now */ +static int ra_clock_gettime(int clk_ik, struct timespec *t) { struct timeval now; int rv = gettimeofday(&now, NULL); @@ -98,8 +107,13 @@ static int clock_gettime(int clk_ik, struct timespec *t) return 0; } #endif + +#if defined(__MACH__) && (__MAC_OS_X_VERSION_MAX_ALLOWED < 101200) && (__IPHONE_OS_VERSION_MAX_ALLOWED < 100000) +#else +#define ra_clock_gettime clock_gettime #endif + #ifdef EMSCRIPTEN #include #endif @@ -136,8 +150,8 @@ retro_perf_tick_t cpu_features_get_perf_counter(void) tv_usec = (long)(system_time.wMilliseconds * 1000); time_ticks = (1000000 * tv_sec + tv_usec); #elif defined(__linux__) || defined(__QNX__) || defined(__MACH__) - struct timespec tv; - if (clock_gettime(CLOCK_MONOTONIC, &tv) == 0) + struct timespec tv = {0}; + if (ra_clock_gettime(CLOCK_MONOTONIC, &tv) == 0) time_ticks = (retro_perf_tick_t)tv.tv_sec * 1000000000 + (retro_perf_tick_t)tv.tv_nsec; @@ -153,10 +167,14 @@ retro_perf_tick_t cpu_features_get_perf_counter(void) time_ticks = __mftb(); #elif defined(GEKKO) time_ticks = gettime(); -#elif defined(PSP) || defined(VITA) - sceRtcGetCurrentTick(&time_ticks); +#elif defined(PSP) + sceRtcGetCurrentTick((uint64_t*)&time_ticks); +#elif defined(VITA) + sceRtcGetCurrentTick((SceRtcTick*)&time_ticks); #elif defined(_3DS) time_ticks = svcGetSystemTick(); +#elif defined(WIIU) + time_ticks = OSGetSystemTime(); #elif defined(__mips__) struct timeval tv; gettimeofday(&tv,NULL); @@ -192,7 +210,7 @@ retro_time_t cpu_features_get_time_usec(void) 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) + if (ra_clock_gettime(CLOCK_MONOTONIC, &tv) < 0) return 0; return tv.tv_sec * INT64_C(1000000) + (tv.tv_nsec + 500) / 1000; #elif defined(EMSCRIPTEN) @@ -205,6 +223,8 @@ retro_time_t cpu_features_get_time_usec(void) return osGetTime() * 1000; #elif defined(VITA) return sceKernelGetProcessTimeWide(); +#elif defined(WIIU) + return ticks_to_us(OSGetSystemTime()); #else #error "Your platform does not have a timer function implemented in cpu_features_get_time_usec(). Cannot continue." #endif @@ -271,7 +291,7 @@ static uint64_t xgetbv_x86(uint32_t idx) } #endif -#if defined(__ARM_NEON__) +#if defined(__ARM_NEON__) static void arm_enable_runfast_mode(void) { /* RunFast mode. Enables flush-to-zero and some @@ -448,6 +468,8 @@ unsigned cpu_features_get_core_amount(void) return 4; #elif defined(_3DS) return 1; +#elif defined(WIIU) + return 3; #elif defined(_SC_NPROCESSORS_ONLN) /* Linux, most UNIX-likes. */ long ret = sysconf(_SC_NPROCESSORS_ONLN); @@ -513,7 +535,7 @@ uint64_t cpu_features_get(void) { int flags[4]; int vendor_shuffle[3]; - char vendor[13] = {0}; + char vendor[13]; size_t len = 0; uint64_t cpu_flags = 0; uint64_t cpu = 0; @@ -542,6 +564,12 @@ uint64_t cpu_features_get(void) cpu |= RETRO_SIMD_MMXEXT; } + len = sizeof(size_t); + if (sysctlbyname("hw.optional.floatingpoint", NULL, &len, NULL, 0) == 0) + { + cpu |= RETRO_SIMD_CMOV; + } + len = sizeof(size_t); if (sysctlbyname("hw.optional.sse", NULL, &len, NULL, 0) == 0) cpu |= RETRO_SIMD_SSE; @@ -593,6 +621,8 @@ uint64_t cpu_features_get(void) vendor_shuffle[0] = flags[1]; vendor_shuffle[1] = flags[3]; vendor_shuffle[2] = flags[2]; + + vendor[0] = '\0'; memcpy(vendor, vendor_shuffle, sizeof(vendor_shuffle)); /* printf("[CPUID]: Vendor: %s\n", vendor); */ @@ -608,6 +638,9 @@ uint64_t cpu_features_get(void) x86_cpuid(1, flags); + if (flags[3] & (1 << 15)) + cpu |= RETRO_SIMD_CMOV; + if (flags[3] & (1 << 23)) cpu |= RETRO_SIMD_MMX; @@ -682,6 +715,15 @@ uint64_t cpu_features_get(void) if (check_arm_cpu_feature("vfpv4")) cpu |= RETRO_SIMD_VFPV4; + if (check_arm_cpu_feature("asimd")) + { + cpu |= RETRO_SIMD_ASIMD; +#ifdef __ARM_NEON__ + cpu |= RETRO_SIMD_NEON; + arm_enable_runfast_mode(); +#endif + } + #if 0 check_arm_cpu_feature("swp"); check_arm_cpu_feature("half"); @@ -726,6 +768,7 @@ uint64_t cpu_features_get(void) 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)); + if (cpu & RETRO_SIMD_ASIMD) strlcat(buf, " ASIMD", sizeof(buf)); return cpu; } diff --git a/desmume/src/libretro-common/include/features/features_cpu.h b/desmume/src/libretro-common/include/features/features_cpu.h index eed29d0e5..8a0a046de 100644 --- a/desmume/src/libretro-common/include/features/features_cpu.h +++ b/desmume/src/libretro-common/include/features/features_cpu.h @@ -43,15 +43,17 @@ retro_perf_tick_t cpu_features_get_perf_counter(void); /** * cpu_features_get_time_usec: * - * Gets time in microseconds. * - * Returns: time in microseconds. + * Gets time in microseconds, from an undefined epoch. + * The epoch may change between computers or across reboots. + * + * Returns: time in microseconds **/ retro_time_t cpu_features_get_time_usec(void); /** * cpu_features_get: * - * Gets CPU features.. + * Gets CPU features. * * Returns: bitmask of all CPU features available. **/ diff --git a/desmume/src/libretro-common/include/libretro.h b/desmume/src/libretro-common/include/libretro.h index e6809262a..020752d70 100644 --- a/desmume/src/libretro-common/include/libretro.h +++ b/desmume/src/libretro-common/include/libretro.h @@ -244,6 +244,7 @@ enum retro_language RETRO_LANGUAGE_CHINESE_SIMPLIFIED = 11, RETRO_LANGUAGE_ESPERANTO = 12, RETRO_LANGUAGE_POLISH = 13, + RETRO_LANGUAGE_VIETNAMESE = 14, RETRO_LANGUAGE_LAST, /* Ensure sizeof(enum) == sizeof(int) */ @@ -976,6 +977,37 @@ struct retro_hw_render_context_negotiation_interface * so it will be used after SET_HW_RENDER, but before the context_reset callback. */ +/* Serialized state is incomplete in some way. Set if serialization is + * usable in typical end-user cases but should not be relied upon to + * implement frame-sensitive frontend features such as netplay or + * rerecording. */ +#define RETRO_SERIALIZATION_QUIRK_INCOMPLETE (1 << 0) +/* The core must spend some time initializing before serialization is + * supported. retro_serialize() will initially fail; retro_unserialize() + * and retro_serialize_size() may or may not work correctly either. */ +#define RETRO_SERIALIZATION_QUIRK_MUST_INITIALIZE (1 << 1) +/* Serialization size may change within a session. */ +#define RETRO_SERIALIZATION_QUIRK_CORE_VARIABLE_SIZE (1 << 2) +/* Set by the frontend to acknowledge that it supports variable-sized + * states. */ +#define RETRO_SERIALIZATION_QUIRK_FRONT_VARIABLE_SIZE (1 << 3) +/* Serialized state can only be loaded during the same session. */ +#define RETRO_SERIALIZATION_QUIRK_SINGLE_SESSION (1 << 4) +/* Serialized state cannot be loaded on an architecture with a different + * endianness from the one it was saved on. */ +#define RETRO_SERIALIZATION_QUIRK_ENDIAN_DEPENDENT (1 << 5) +/* Serialized state cannot be loaded on a different platform from the one it + * was saved on for reasons other than endianness, such as word size + * dependence */ +#define RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT (1 << 6) + +#define RETRO_ENVIRONMENT_SET_SERIALIZATION_QUIRKS 44 + /* uint64_t * -- + * Sets quirk flags associated with serialization. The frontend will zero any flags it doesn't + * recognize or support. Should be set in either retro_init or retro_load_game, but not both. + */ + + #define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */ #define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */ #define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */ @@ -1284,6 +1316,8 @@ struct retro_log_callback #define RETRO_SIMD_VFPV4 (1 << 17) #define RETRO_SIMD_POPCNT (1 << 18) #define RETRO_SIMD_MOVBE (1 << 19) +#define RETRO_SIMD_CMOV (1 << 20) +#define RETRO_SIMD_ASIMD (1 << 21) typedef uint64_t retro_perf_tick_t; typedef int64_t retro_time_t; @@ -1657,7 +1691,8 @@ struct retro_hw_render_callback * be providing preallocated framebuffers. */ retro_hw_get_current_framebuffer_t get_current_framebuffer; - /* Set by frontend. */ + /* Set by frontend. + * Can return all relevant functions, including glClear on Windows. */ retro_hw_get_proc_address_t get_proc_address; /* Set if render buffers should have depth component attached.