diff --git a/backends/platform/libretro/Makefile b/backends/platform/libretro/Makefile index 34e0c4bd967..3693e27c208 100644 --- a/backends/platform/libretro/Makefile +++ b/backends/platform/libretro/Makefile @@ -156,7 +156,7 @@ else ifeq ($(platform), wiiu) CXX = $(DEVKITPPC)/bin/powerpc-eabi-g++$(EXE_EXT) AR = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) rcs AR_ALONE = $(DEVKITPPC)/bin/powerpc-eabi-ar$(EXE_EXT) - DEFINES += -DGEKKO -mwup -mcpu=750 -meabi -mhard-float -D__POWERPC__ -D__ppc__ -DRETRO_IS_BIG_ENDIAN=1 -DRETRO_IS_LITTLE_ENDIAN=0 -DWORDS_BIGENDIAN=1 + DEFINES += -mwup -mcpu=750 -meabi -mhard-float -D__POWERPC__ -D__ppc__ -DRETRO_IS_BIG_ENDIAN=1 -DRETRO_IS_LITTLE_ENDIAN=0 -DWORDS_BIGENDIAN=1 DEFINES += -U__INT32_TYPE__ -U __UINT32_TYPE__ -D__INT32_TYPE__=int DEFINES += -DHAVE_STRTOUL -DWIIU CXXFLAGS := -fpermissive diff --git a/backends/platform/libretro/dependencies.mk b/backends/platform/libretro/dependencies.mk index 9951009aec2..f28ea005ddc 100644 --- a/backends/platform/libretro/dependencies.mk +++ b/backends/platform/libretro/dependencies.mk @@ -43,7 +43,9 @@ OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/file/file_path_io.o \ $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/vfs/vfs_implementation.o \ $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/string/stdstring.o \ $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/time/rtime.o \ - $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/streams/file_stream.o + $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/streams/file_stream.o \ + $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/features/features_cpu.o + ifeq ($(USE_LIBCO), 1) OBJS_DEPS += $(DEPS_PATH)/$(DEPS_FOLDER_libretro-common)/libco/libco.o diff --git a/backends/platform/libretro/include/libretro-os.h b/backends/platform/libretro/include/libretro-os.h index 7bca55718f8..5406221472f 100644 --- a/backends/platform/libretro/include/libretro-os.h +++ b/backends/platform/libretro/include/libretro-os.h @@ -18,6 +18,7 @@ #define BACKENDS_LIBRETRO_OS_H #include +#include #include #include "audio/mixer_intern.h" diff --git a/backends/platform/libretro/include/wiiu/os/thread.h b/backends/platform/libretro/include/wiiu/os/thread.h new file mode 100644 index 00000000000..a545185c60a --- /dev/null +++ b/backends/platform/libretro/include/wiiu/os/thread.h @@ -0,0 +1,277 @@ +#pragma once +#include +#include "time.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OSThread OSThread; + +typedef int (*OSThreadEntryPointFn)(int argc, const char **argv); +typedef void (*OSThreadCleanupCallbackFn)(OSThread *thread, void *stack); +typedef void (*OSThreadDeallocatorFn)(OSThread *thread, void *stack); + +enum OS_THREAD_STATE +{ + OS_THREAD_STATE_NONE = 0, + + /*! Thread is ready to run */ + OS_THREAD_STATE_READY = 1 << 0, + + /*! Thread is running */ + OS_THREAD_STATE_RUNNING = 1 << 1, + + /*! Thread is waiting, i.e. on a mutex */ + OS_THREAD_STATE_WAITING = 1 << 2, + + /*! Thread is about to terminate */ + OS_THREAD_STATE_MORIBUND = 1 << 3, +}; +typedef uint8_t OSThreadState; + +enum OS_THREAD_REQUEST +{ + OS_THREAD_REQUEST_NONE = 0, + OS_THREAD_REQUEST_SUSPEND = 1, + OS_THREAD_REQUEST_CANCEL = 2, +}; +typedef uint32_t OSThreadRequest; + +enum OS_THREAD_ATTRIB +{ + /*! Allow the thread to run on CPU0. */ + OS_THREAD_ATTRIB_AFFINITY_CPU0 = 1 << 0, + + /*! Allow the thread to run on CPU1. */ + OS_THREAD_ATTRIB_AFFINITY_CPU1 = 1 << 1, + + /*! Allow the thread to run on CPU2. */ + OS_THREAD_ATTRIB_AFFINITY_CPU2 = 1 << 2, + + /*! Allow the thread to run any CPU. */ + OS_THREAD_ATTRIB_AFFINITY_ANY = ((1 << 0) | (1 << 1) | (1 << 2)), + + /*! Start the thread detached. */ + OS_THREAD_ATTRIB_DETACHED = 1 << 3, + + /*! Enables tracking of stack usage. */ + OS_THREAD_ATTRIB_STACK_USAGE = 1 << 5 +}; +typedef uint8_t OSThreadAttributes; + +#define OS_CONTEXT_TAG 0x4F53436F6E747874ull + +typedef struct OSContext +{ + /*! Should always be set to the value OS_CONTEXT_TAG. */ + uint64_t tag; + + uint32_t gpr[32]; + uint32_t cr; + uint32_t lr; + uint32_t ctr; + uint32_t xer; + uint32_t srr0; + uint32_t srr1; + uint32_t __unknown[0x5]; + uint32_t fpscr; + double fpr[32]; + uint16_t spinLockCount; + uint16_t state; + uint32_t gqr[8]; + uint32_t __unknown0; + double psf[32]; + uint64_t coretime[3]; + uint64_t starttime; + uint32_t error; + uint32_t __unknown1; + uint32_t pmc1; + uint32_t pmc2; + uint32_t pmc3; + uint32_t pmc4; + uint32_t mmcr0; + uint32_t mmcr1; +} OSContext; + +typedef struct OSMutex OSMutex; +typedef struct OSFastMutex OSFastMutex; + +typedef struct OSMutexQueue +{ + OSMutex *head; + OSMutex *tail; + void *parent; + uint32_t __unknown; +} OSMutexQueue; + +typedef struct OSFastMutexQueue +{ + OSFastMutex *head; + OSFastMutex *tail; +} OSFastMutexQueue; + +typedef struct +{ + OSThread *prev; + OSThread *next; +} OSThreadLink; + +typedef struct +{ + OSThread *head; + OSThread *tail; + void *parent; + uint32_t __unknown; +} OSThreadQueue; + +typedef struct +{ + OSThread *head; + OSThread *tail; +} OSThreadSimpleQueue; + +#define OS_THREAD_TAG 0x74487244u +#pragma pack(push, 1) +typedef struct __attribute__ ((aligned (8))) OSThread +{ + OSContext context; + + /*! Should always be set to the value OS_THREAD_TAG. */ + uint32_t tag; + + /*! Bitfield of OS_THREAD_STATE */ + OSThreadState state; + + /*! Bitfield of OS_THREAD_ATTRIB */ + OSThreadAttributes attr; + + /*! Unique thread ID */ + uint16_t id; + + /*! Suspend count (increased by OSSuspendThread). */ + int32_t suspendCounter; + + /*! Actual priority of thread. */ + int32_t priority; + + /*! Base priority of thread, 0 is highest priority, 31 is lowest priority. */ + int32_t basePriority; + + /*! Exit value */ + int32_t exitValue; + + uint32_t unknown0[0x9]; + + /*! Queue the thread is currently waiting on */ + OSThreadQueue *queue; + + /*! Link used for thread queue */ + OSThreadLink link; + + /*! Queue of threads waiting to join this thread */ + OSThreadQueue joinQueue; + + /*! Mutex this thread is waiting to lock */ + OSMutex *mutex; + + /*! Queue of mutexes this thread owns */ + OSMutexQueue mutexQueue; + + /*! Link for global active thread queue */ + OSThreadLink activeLink; + + /*! Stack start (top, highest address) */ + void *stackStart; + + /*! Stack end (bottom, lowest address) */ + void *stackEnd; + + /*! Thread entry point */ + OSThreadEntryPointFn entryPoint; + + uint32_t unknown1[0x77]; + + /*! Thread specific values, accessed with OSSetThreadSpecific and OSGetThreadSpecific. */ + uint32_t specific[0x10]; + + uint32_t unknown2; + + /*! Thread name, accessed with OSSetThreadName and OSGetThreadName. */ + const char *name; + + uint32_t unknown3; + + /*! The stack pointer passed in OSCreateThread. */ + void *userStackPointer; + + /*! Called just before thread is terminated, set with OSSetThreadCleanupCallback */ + OSThreadCleanupCallbackFn cleanupCallback; + + /*! Called just after a thread is terminated, set with OSSetThreadDeallocator */ + OSThreadDeallocatorFn deallocator; + + /*! If TRUE then a thread can be cancelled or suspended, set with OSSetThreadCancelState */ + BOOL cancelState; + + /*! Current thread request, used for cancelleing and suspending the thread. */ + OSThreadRequest requestFlag; + + /*! Pending suspend request count */ + int32_t needSuspend; + + /*! Result of thread suspend */ + int32_t suspendResult; + + /*! Queue of threads waiting for a thread to be suspended. */ + OSThreadQueue suspendQueue; + + uint32_t unknown4[0x2B]; +} OSThread; +#pragma pack(pop) + +void +OSCancelThread(OSThread *thread); +int32_t OSCheckActiveThreads(); +int32_t OSCheckThreadStackUsage(OSThread *thread); +void OSClearThreadStackUsage(OSThread *thread); +void OSContinueThread(OSThread *thread); +BOOL OSCreateThread(OSThread *thread, OSThreadEntryPointFn entry, int32_t argc, char *argv, + void *stack, uint32_t stackSize, int32_t priority, OSThreadAttributes attributes); +void OSDetachThread(OSThread *thread); +void OSExitThread(int32_t result); +void OSGetActiveThreadLink(OSThread *thread, OSThreadLink *link); +OSThread *OSGetCurrentThread(); +OSThread *OSGetDefaultThread(uint32_t coreID); +uint32_t OSGetStackPointer(); +uint32_t OSGetThreadAffinity(OSThread *thread); +const char *OSGetThreadName(OSThread *thread); +int32_t OSGetThreadPriority(OSThread *thread); +uint32_t OSGetThreadSpecific(uint32_t id); +BOOL OSIsThreadSuspended(OSThread *thread); +BOOL OSIsThreadTerminated(OSThread *thread); +BOOL OSJoinThread(OSThread *thread, int *threadResult); +int32_t OSResumeThread(OSThread *thread); +BOOL OSRunThread(OSThread *thread, OSThreadEntryPointFn entry, int argc, const char **argv); +BOOL OSSetThreadAffinity(OSThread *thread, uint32_t affinity); +BOOL OSSetThreadCancelState(BOOL state); +OSThreadCleanupCallbackFn OSSetThreadCleanupCallback(OSThread *thread, + OSThreadCleanupCallbackFn callback); +OSThreadDeallocatorFn OSSetThreadDeallocator(OSThread *thread, OSThreadDeallocatorFn deallocator); +void OSSetThreadName(OSThread *thread, const char *name); +BOOL OSSetThreadPriority(OSThread *thread, int32_t priority); +BOOL OSSetThreadRunQuantum(OSThread *thread, uint32_t quantum); +void OSSetThreadSpecific(uint32_t id, uint32_t value); +BOOL OSSetThreadStackUsage(OSThread *thread); +void OSSleepThread(OSThreadQueue *queue); +void OSSleepTicks(OSTime ticks); +uint32_t OSSuspendThread(OSThread *thread); +void OSTestThreadCancel(); +void OSWakeupThread(OSThreadQueue *queue); +void OSYieldThread(); +void OSInitThreadQueue(OSThreadQueue *queue); +void OSInitThreadQueueEx(OSThreadQueue *queue, void *parent); + +#ifdef __cplusplus +} +#endif diff --git a/backends/platform/libretro/include/wiiu/os/time.h b/backends/platform/libretro/include/wiiu/os/time.h new file mode 100644 index 00000000000..e8ff34254a0 --- /dev/null +++ b/backends/platform/libretro/include/wiiu/os/time.h @@ -0,0 +1,49 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define OSOneSecond ((OSGetSystemInfo()->clockSpeed) / 4) +#define OSMilliseconds(val) ((((uint64_t)(val)) * (uint64_t)(OSOneSecond)) / 1000ull) +#define OSMicroseconds(val) ((((uint64_t)(val)) * (uint64_t)(OSOneSecond)) / 1000000ull) +#define OSNanoseconds(val) ((((uint64_t)(val)) * (uint64_t)(OSOneSecond)) / 1000000000ull) + +#define wiiu_bus_clock (17 * 13 * 5*5*5 * 5*5*5 * 3*3 * 2*2*2) /* 248.625000 Mhz */ +#define wiiu_cpu_clock (17 * 13 * 5*5*5 * 5*5*5 * 5 * 3*3 * 2*2*2) /* 1243.125000 Mhz */ +#define wiiu_timer_clock (17 * 13 * 5*5*5 * 5*5*5 * 3*3 * 2) /* 62.156250 Mhz */ + +#define sec_to_ticks(s) (((17 * 13 * 5*5*5 * 5*5*5 * 3*3 * 2) * (uint64_t)(s))) +#define ms_to_ticks(ms) (((17 * 13 * 5*5*5 * 3*3) * (uint64_t)(ms)) / (2*2)) +#define us_to_ticks(us) (((17 * 13 * 3*3) * (uint64_t)(us)) / (2*2* 2*2*2)) +#define ns_to_ticks(ns) (((17 * 13 * 3*3) * (uint64_t)(ns)) / (2*2* 2*2*2* 2*2*2 *5*5*5)) + +#define ticks_to_sec(ticks) (((uint64_t)(ticks)) / (17 * 13 * 5*5*5 * 5*5*5 * 3*3 * 2)) +#define ticks_to_ms(ticks) (((uint64_t)(ticks) * (2*2)) / (17 * 13 * 5*5*5 * 3*3)) +#define ticks_to_us(ticks) (((uint64_t)(ticks) * (2*2 * 2*2*2)) / (17 * 13 * 3*3)) +#define ticks_to_ns(ticks) (((uint64_t)(ticks) * (2*2 * 2*2*2 * 2*2*2 * 5*5*5)) / (17 * 13 * 3*3)) + +typedef int32_t OSTick; +typedef int64_t OSTime; + +typedef struct +{ + int32_t tm_sec; + int32_t tm_min; + int32_t tm_hour; + int32_t tm_mday; + int32_t tm_mon; + int32_t tm_year; +}OSCalendarTime; + +OSTime OSGetTime(); +OSTime OSGetSystemTime(); +OSTick OSGetTick(); +OSTick OSGetSystemTick(); +OSTime OSCalendarTimeToTicks(OSCalendarTime *calendarTime); +void OSTicksToCalendarTime(OSTime time, OSCalendarTime *calendarTime); + +#ifdef __cplusplus +} +#endif diff --git a/backends/platform/libretro/include/wiiu/types.h b/backends/platform/libretro/include/wiiu/types.h new file mode 100644 index 00000000000..3927c5bb52c --- /dev/null +++ b/backends/platform/libretro/include/wiiu/types.h @@ -0,0 +1,41 @@ +#pragma once +#include +#include + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +typedef int BOOL; + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; + +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; + +typedef volatile u8 vu8; +typedef volatile u16 vu16; +typedef volatile u32 vu32; +typedef volatile u64 vu64; + +typedef volatile s8 vs8; +typedef volatile s16 vs16; +typedef volatile s32 vs32; +typedef volatile s64 vs64; + +typedef float f32; +typedef double f64; + +typedef volatile float vf32; +typedef volatile double vf64; + +#define countof(array) (sizeof(array) / sizeof(*array)) diff --git a/backends/platform/libretro/src/libretro-os-base.cpp b/backends/platform/libretro/src/libretro-os-base.cpp index cf59cdbb352..66072898f49 100644 --- a/backends/platform/libretro/src/libretro-os-base.cpp +++ b/backends/platform/libretro/src/libretro-os-base.cpp @@ -43,7 +43,7 @@ OSystem_libretro::OSystem_libretro() : _mousePaletteEnabled(false), _mouseVisibl s_extraDir = s_systemDir + "/" + SCUMMVM_SYSTEM_SUBDIR + "/" + SCUMMVM_EXTRA_SUBDIR; s_lastDir = s_systemDir; - _startTime = getMillis(); + _startTime = (uint32)(cpu_features_get_time_usec() / 1000); } OSystem_libretro::~OSystem_libretro() { diff --git a/backends/platform/libretro/src/libretro-os-events.cpp b/backends/platform/libretro/src/libretro-os-events.cpp index 170f14d9236..84950cfa862 100644 --- a/backends/platform/libretro/src/libretro-os-events.cpp +++ b/backends/platform/libretro/src/libretro-os-events.cpp @@ -18,15 +18,6 @@ #include #include -#include -#if defined(__CELLOS_LV2__) -#include -#elif (defined(GEKKO) && !defined(WIIU)) -#include -#else -#include -#endif - #include "common/list.h" #include "common/events.h" #include "backends/platform/libretro/include/libretro-os.h" @@ -52,18 +43,7 @@ uint8 OSystem_libretro::getThreadSwitchCaller(){ } uint32 OSystem_libretro::getMillis(bool skipRecord) { -#if (defined(GEKKO) && !defined(WIIU)) - return (ticks_to_microsecs(gettime()) / 1000.0) - _startTime; -#elif defined(WIIU) - return ((cpu_features_get_time_usec()) / 1000) - _startTime; -#elif defined(__CELLOS_LV2__) - return (sys_time_get_system_time() / 1000.0) - _startTime; -#else - struct timeval t; - gettimeofday(&t, 0); - - return ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - _startTime; -#endif + return (uint32)(cpu_features_get_time_usec() / 1000) - _startTime; } void OSystem_libretro::delayMillis(uint msecs) { diff --git a/backends/platform/libretro/src/libretro-os-utils.cpp b/backends/platform/libretro/src/libretro-os-utils.cpp index ec9e945cc91..0bb44b02464 100644 --- a/backends/platform/libretro/src/libretro-os-utils.cpp +++ b/backends/platform/libretro/src/libretro-os-utils.cpp @@ -16,15 +16,7 @@ */ #define FORBIDDEN_SYMBOL_EXCEPTION_time -#include -#if defined(__CELLOS_LV2__) -#include -#elif (defined(GEKKO) && !defined(WIIU)) -#include -#else -#include -#endif - +#include #include "common/tokenizer.h" #include "common/config-manager.h" #include "base/commandLine.h" @@ -32,7 +24,7 @@ #include "backends/platform/libretro/include/libretro-defs.h" void OSystem_libretro::getTimeAndDate(TimeDate &t, bool skipRecord) const { - time_t curTime = time(NULL); + uint32 curTime = (uint32) (cpu_features_get_time_usec() / 1000000); #define YEAR0 1900 #define EPOCH_YR 1970