Sleep a bit more precise

This commit is contained in:
Edgaru089 2024-03-07 09:55:36 +08:00
parent bbca75539e
commit 4ec2805a5d
2 changed files with 34 additions and 9 deletions

41
types.c
View File

@ -1,6 +1,10 @@
#include "types.h" #include "types.h"
#include <math.h> #include <math.h>
#include <stdio.h>
#ifdef WIN32_LEAN_AND_MEAN
#undef WIN32_LEAN_AND_MEAN
#endif
#include <windows.h> #include <windows.h>
#include <timeapi.h> #include <timeapi.h>
@ -61,6 +65,12 @@ bool box2_Intersects(const Box2 x, const Box2 y, Box2 *out_intersection) {
} }
} }
Vec2 box2_Center(Box2 box) {
return vec2(
box.lefttop.x + box.size.x / 2.0,
box.lefttop.y + box.size.y / 2.0);
}
Box2 box2_Offset(Box2 box, Vec2 offset) { Box2 box2_Offset(Box2 box, Vec2 offset) {
box.lefttop = vec2_Add(box.lefttop, offset); box.lefttop = vec2_Add(box.lefttop, offset);
return box; return box;
@ -78,16 +88,29 @@ Box2 box2_OffsetY(Box2 box, double offsetY) {
static double freqInverse = 0.0; static double freqInverse = 0.0;
// https://stackoverflow.com/a/31411628
// "How to make thread sleep less than a millisecond on Windows"
typedef NTSTATUS(__stdcall *NtDelayExecution_Type)(BOOL Alertable, PLARGE_INTEGER DelayInterval);
typedef NTSTATUS(__stdcall *ZwSetTimerResolution_Type)(IN ULONG RequestedResolution, IN BOOLEAN Set, OUT PULONG ActualResolution);
static NtDelayExecution_Type NtDelayExecution;
static ZwSetTimerResolution_Type ZwSetTimerResolution;
void duration_Sleep(const Duration t) { void duration_Sleep(const Duration t) {
if (t.microseconds <= 0) if (!NtDelayExecution) {
return; NtDelayExecution = (NtDelayExecution_Type)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDelayExecution");
// https://learn.microsoft.com/zh-cn/windows/win32/api/timeapi/nf-timeapi-timebeginperiod ZwSetTimerResolution = (ZwSetTimerResolution_Type)GetProcAddress(GetModuleHandle("ntdll.dll"), "ZwSetTimerResolution");
// timeBeginPeriod() and friends
TIMECAPS tc; // Only run this once
timeGetDevCaps(&tc, sizeof(TIMECAPS)); ULONG actualResolution;
timeBeginPeriod(tc.wPeriodMin); ZwSetTimerResolution(1, true, &actualResolution);
Sleep((DWORD)(round(duration_Milliseconds(t)))); // Only millisecond precision. Sad fprintf(stderr, "[duration_Sleep] ActualResolution was %u\n", actualResolution);
timeEndPeriod(tc.wPeriodMin); }
LARGE_INTEGER interval;
interval.QuadPart = t.microseconds * -10;
NtDelayExecution(false, &interval);
} }
TimePoint time_Now() { TimePoint time_Now() {

View File

@ -42,6 +42,8 @@ typedef struct {
// Intersection test. // Intersection test.
bool box2_Intersects(const Box2 x, const Box2 y, Box2 *out_intersection); bool box2_Intersects(const Box2 x, const Box2 y, Box2 *out_intersection);
Vec2 box2_Center(Box2 box);
Box2 box2_Offset(Box2 box, Vec2 offset); Box2 box2_Offset(Box2 box, Vec2 offset);
Box2 box2_OffsetX(Box2 box, double offsetX); Box2 box2_OffsetX(Box2 box, double offsetX);
Box2 box2_OffsetY(Box2 box, double offsetY); Box2 box2_OffsetY(Box2 box, double offsetY);