Merge branch 'port' of https://github.com/fgsfdsfgs/perfect_dark into port-debugger

This commit is contained in:
fgsfds committed 2024-03-09 17:40:37 +01:00
commit 242a89a622
9 files changed
+91 -53

No files matched your search

+2 -53
View File
@@ -9,24 +9,6 @@
#include "gfx_window_manager_api.h"
#include "gfx_screen_config.h"
// define a way to yield the cpu when in a busy wait
#ifdef PLATFORM_WIN32
// winapi provides a yield macro
#include <windows.h>
#define DO_YIELD() YieldProcessor()
#elif defined(PLATFORM_X86) || defined(PLATFORM_X86_64)
// this should work even if the code is not built with SSE enabled, at least on gcc and clang,
// but if it doesn't we'll have to use __builtin_ia32_pause() or something
#include <immintrin.h>
#define DO_YIELD() _mm_pause()
#elif defined(PLATFORM_ARM)
// same as YieldProcessor() on ARM Windows
#define DO_YIELD() __asm__ volatile("dmb ishst\n\tyield":::"memory")
#else
// fuck it
#define DO_YIELD() do { } while (0)
#endif
static SDL_Window* wnd;
static SDL_GLContext ctx;
static SDL_Renderer* renderer;
@@ -44,28 +26,9 @@ static int target_fps = 120; // above 60 since vsync is enabled by default
static uint64_t previous_time;
static uint64_t qpc_freq;
#ifdef PLATFORM_WIN32
// on win32 we use waitable timers instead of nanosleep
typedef HANDLE WINAPI (*CREATEWAITABLETIMEREXAFN)(LPSECURITY_ATTRIBUTES, LPCSTR, DWORD, DWORD);
static HANDLE timer;
static CREATEWAITABLETIMEREXAFN pfnCreateWaitableTimerExA;
#endif
#define FRAME_INTERVAL_US_NUMERATOR 1000000
#define FRAME_INTERVAL_US_DENOMINATOR (target_fps)
static inline void do_sleep(const int64_t left) {
#ifdef PLATFORM_WIN32
static LARGE_INTEGER li;
li.QuadPart = -left;
SetWaitableTimer(timer, &li, 0, nullptr, nullptr, false);
WaitForSingleObject(timer, INFINITE);
#else
const timespec spec = { 0, left * 100 };
nanosleep(&spec, nullptr);
#endif
}
static void set_fullscreen(bool on, bool call_callback) {
if (fullscreen_state == on) {
return;
@@ -181,20 +144,6 @@ static void gfx_sdl_init(const char* game_name, const char* gfx_api_name, bool s
qpc_freq = SDL_GetPerformanceFrequency();
#ifdef PLATFORM_WIN32
// this function is only present on Vista+, so try to import it from kernel32 by hand
pfnCreateWaitableTimerExA = (CREATEWAITABLETIMEREXAFN)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateWaitableTimerExA");
if (pfnCreateWaitableTimerExA) {
// function exists, try to create a hires timer
timer = pfnCreateWaitableTimerExA(nullptr, nullptr, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
}
if (!timer) {
// no function or hires timers not supported, fallback to lower resolution timer
sysLogPrintf(LOG_WARNING, "SDL: hires waitable timers not available");
timer = CreateWaitableTimerA(nullptr, false, nullptr);
}
#endif
set_maximize_window(start_maximized);
set_fullscreen(start_in_fullscreen, false);
}
@@ -272,11 +221,11 @@ static inline void sync_framerate_with_timer(void) {
// We want to exit a bit early, so we can busy-wait the rest to never miss the deadline
left -= 15000UL;
if (left > 0) {
do_sleep(left);
sysSleep(left);
}
do {
DO_YIELD();
sysCpuRelax();
t = qpc_to_100ns(SDL_GetPerformanceCounter());
} while ((int64_t)t < next);
+1
View File
@@ -16,5 +16,6 @@ s32 configSave(const char *fname);
// registers a variable in the config file
// this should be done before configInit() is called, preferably in a module constructor
void configRegisterInt(const char *key, s32 *var, s32 min, s32 max);
void configRegisterUInt(const char* key, u32* var, u32 min, u32 max);
void configRegisterFloat(const char *key, f32 *var, f32 min, f32 max);
void configRegisterString(const char *key, char *var, u32 maxstr);
+6
View File
@@ -34,6 +34,12 @@ void *sysMemAlloc(const u32 size);
void *sysMemZeroAlloc(const u32 size);
void sysMemFree(void *ptr);
// hns is specified in 100ns units
void sysSleep(const s64 hns);
// yield CPU if supported (e.g. during a busy loop)
void sysCpuRelax(void);
void crashInit(void);
void crashShutdown(void);
+2
View File
@@ -36,6 +36,7 @@ u32 g_VmNumPageReplaces = 0;
u8 g_VmShowStats = 0;
s32 g_TickRateDiv = 1;
s32 g_TickExtraSleep = true;
s32 g_SkipIntro = false;
@@ -161,6 +162,7 @@ PD_CONSTRUCTOR static void gameConfigInit(void)
configRegisterInt("Game.CenterHUD", &g_HudCenter, 0, 2);
configRegisterFloat("Game.ScreenShakeIntensity", &g_ViShakeIntensityMult, 0.f, 10.f);
configRegisterInt("Game.TickRateDivisor", &g_TickRateDiv, 0, 10);
configRegisterInt("Game.ExtraSleep", &g_TickExtraSleep, 0, 1);
configRegisterInt("Game.SkipIntro", &g_SkipIntro, 0, 1);
configRegisterInt("Game.DisableMpDeathMusic", &g_MusicDisableMpDeath, 0, 1);
configRegisterInt("Game.GEMuzzleFlashes", &g_BgunGeMuzzleFlashes, 0, 1);
+4
View File
@@ -73,6 +73,7 @@
#include "data.h"
#include "types.h"
#include "debugger.h"
#include "system.h"
extern u8 *g_MempHeap;
extern u32 g_MempHeapSize;
@@ -500,6 +501,9 @@ void mainLoop(void)
mainTick();
schedEndFrame(&g_Sched);
}
if (g_TickExtraSleep) {
sysSleep(EXTRA_SLEEP_TIME);
}
}
lvStop();
+64
View File
@@ -10,6 +10,38 @@
#include "platform.h"
#include "system.h"
#ifdef PLATFORM_WIN32
#include <windows.h>
// on win32 we use waitable timers instead of nanosleep
typedef HANDLE WINAPI (*CREATEWAITABLETIMEREXAFN)(LPSECURITY_ATTRIBUTES, LPCSTR, DWORD, DWORD);
static HANDLE timer;
static CREATEWAITABLETIMEREXAFN pfnCreateWaitableTimerExA;
// winapi also provides a yield macro
#define DO_YIELD() YieldProcessor()
#else
#include <unistd.h>
// figure out how to yield
#if defined(PLATFORM_X86) || defined(PLATFORM_X86_64)
// this should work even if the code is not built with SSE enabled, at least on gcc and clang,
// but if it doesn't we'll have to use __builtin_ia32_pause() or something
#include <immintrin.h>
#define DO_YIELD() _mm_pause()
#elif defined(PLATFORM_ARM)
// same as YieldProcessor() on ARM Windows
#define DO_YIELD() __asm__ volatile("dmb ishst\n\tyield":::"memory")
#else
// fuck it
#define DO_YIELD() do { } while (0)
#endif
#endif
#define LOG_FNAME "pd.log"
#define CRASHLOG_FNAME "pd.crash.log"
#define USEC_IN_SEC 1000000ULL
@@ -60,6 +92,20 @@ void sysInit(void)
const time_t curtime = time(NULL);
strftime(timestr, sizeof(timestr), "%d %b %Y %H:%M:%S", localtime(&curtime));
sysLogPrintf(LOG_NOTE, "startup date: %s", timestr);
#ifdef PLATFORM_WIN32
// this function is only present on Vista+, so try to import it from kernel32 by hand
pfnCreateWaitableTimerExA = (CREATEWAITABLETIMEREXAFN)GetProcAddress(GetModuleHandleA("kernel32.dll"), "CreateWaitableTimerExA");
if (pfnCreateWaitableTimerExA) {
// function exists, try to create a hires timer
timer = pfnCreateWaitableTimerExA(NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
}
if (!timer) {
// no function or hires timers not supported, fallback to lower resolution timer
sysLogPrintf(LOG_WARNING, "SYS: hires waitable timers not available");
timer = CreateWaitableTimerA(NULL, FALSE, NULL);
}
#endif
}
s32 sysArgCheck(const char *arg)
@@ -238,3 +284,21 @@ void sysMemFree(void *ptr)
{
free(ptr);
}
void sysSleep(const s64 hns)
{
#ifdef PLATFORM_WIN32
static LARGE_INTEGER li;
li.QuadPart = -hns;
SetWaitableTimer(timer, &li, 0, NULL, NULL, FALSE);
WaitForSingleObject(timer, INFINITE);
#else
const timespec spec = { 0, hns * 100 };
nanosleep(&spec, NULL);
#endif
}
void sysCpuRelax(void)
{
DO_YIELD();
}
+9
View File
@@ -4,6 +4,9 @@
#include "bss.h"
#include "data.h"
#include "types.h"
#ifndef PLATFORM_N64
#include "system.h"
#endif
void frametimeInit(void)
{
@@ -41,6 +44,12 @@ void frametimeCalculate(void)
diffframe60 = (g_Vars.lostframetime60t + diffframet + CYCLES_PER_FRAME / 2) / CYCLES_PER_FRAME;
diffframe240 = (g_Vars.lostframetime240t + diffframet + CYCLES_PER_FRAME / 2 / 4) / (CYCLES_PER_FRAME / 4);
#ifndef PLATFORM_N64
if (g_TickExtraSleep) {
sysSleep(EXTRA_SLEEP_TIME);
}
#endif
} while (g_Vars.mininc60 && diffframe60 < g_Vars.mininc60);
g_Vars.lostframetime60t = g_Vars.lostframetime60t + diffframet - diffframe60 * CYCLES_PER_FRAME;
+2
View File
@@ -4723,6 +4723,8 @@ enum weaponnum {
#define CROSSHAIR_HEALTH_ON_GREEN 1
#define CROSSHAIR_HEALTH_ON_WHITE 2
#define EXTRA_SLEEP_TIME 1000LL // 100us
#endif
#endif
+1
View File
@@ -547,6 +547,7 @@ extern s32 g_BlurFb;
extern s32 g_BlurFbCapTimer;
extern bool g_BlurFbDirty;
extern s32 g_TickRateDiv;
extern s32 g_TickExtraSleep;
extern s32 g_MusicDisableMpDeath;
extern s32 g_BgunGeMuzzleFlashes;
extern s32 g_FileAutoSelect;