LIBRETRO: use cpu_features_get_time_usec to get current time

This commit is contained in:
Giovanni Cascione 2023-09-01 18:48:25 +02:00
parent da563c7bf4
commit b486ca6881
9 changed files with 376 additions and 34 deletions

View File

@ -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

View File

@ -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

View File

@ -18,6 +18,7 @@
#define BACKENDS_LIBRETRO_OS_H
#include <libretro.h>
#include <features/features_cpu.h>
#include <retro_miscellaneous.h>
#include "audio/mixer_intern.h"

View File

@ -0,0 +1,277 @@
#pragma once
#include <wiiu/types.h>
#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

View File

@ -0,0 +1,49 @@
#pragma once
#include <wiiu/types.h>
#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

View File

@ -0,0 +1,41 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#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))

View File

@ -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() {

View File

@ -18,15 +18,6 @@
#include <unistd.h>
#include <features/features_cpu.h>
#include <sys/time.h>
#if defined(__CELLOS_LV2__)
#include <sys/sys_time.h>
#elif (defined(GEKKO) && !defined(WIIU))
#include <ogc/lwp_watchdog.h>
#else
#include <time.h>
#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) {

View File

@ -16,15 +16,7 @@
*/
#define FORBIDDEN_SYMBOL_EXCEPTION_time
#include <sys/time.h>
#if defined(__CELLOS_LV2__)
#include <sys/sys_time.h>
#elif (defined(GEKKO) && !defined(WIIU))
#include <ogc/lwp_watchdog.h>
#else
#include <time.h>
#endif
#include <features/features_cpu.h>
#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