mirror of
https://github.com/perfect-dark-pc-port/perfect_dark.git
synced 2026-10-24 00:02:43 +02:00
Merge branch 'port' of https://github.com/fgsfdsfgs/perfect_dark into port-debugger
This commit is contained in:
commit
242a89a622
9 files changed
+91
-53
No files matched your search
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user