main uint/cterm / libmaus / source / maus.c
 1#if !defined(BACKEND_WIN)
 2#define _POSIX_C_SOURCE 199309L
 3#else
 4#include <windows.h>
 5#endif
 6
 7#include <stdarg.h>
 8#include <stdio.h>
 9#include <stdlib.h>
10#include <time.h>
11
12#include "maus.h"
13
14static void vlog(FILE* fd, const char* fmt, va_list ap);
15
16static void vlog(FILE* fd, const char* fmt, va_list ap)
17{
18	fprintf(fd, "maus: ");
19	vfprintf(fd, fmt, ap);
20}
21
22void maus_die(const char* fmt, ...)
23{
24	va_list ap;
25
26	va_start(ap, fmt);
27	vlog(stderr, fmt, ap);
28	va_end(ap);
29
30	exit(EXIT_FAILURE);
31}
32
33uint64_t maus_get_time_ns(void)
34{
35#if !defined(_WIN32)
36	struct timespec ts;
37	clock_gettime(CLOCK_MONOTONIC, &ts);
38	return ts.tv_sec * 1000000000 + ts.tv_nsec;
39#else
40	static LARGE_INTEGER frequency = {0};
41	LARGE_INTEGER counter;
42	uint64_t sec;
43	uint64_t rem;
44
45	if (frequency.QuadPart == 0)
46		QueryPerformanceFrequency(&frequency);
47
48	QueryPerformanceCounter(&counter);
49
50	sec = counter.QuadPart / frequency.QuadPart;
51	rem = counter.QuadPart % frequency.QuadPart;
52
53	return (sec * 1000000000) + ((rem * 1000000000) / frequency.QuadPart);
54#endif
55}
56
57void maus_log(FILE* fd, const char* fmt, ...)
58{
59	va_list ap;
60
61	va_start(ap, fmt);
62	vlog(fd, fmt, ap);
63	fputc('\n', fd);
64	va_end(ap);
65}
66
67void maus_target_fps(Maus* mw, uint32_t fps)
68{
69	uint64_t ns_frame;
70	uint64_t cur_time;
71	uint64_t elapsed;
72	uint64_t sleep;
73
74	#if !defined(_WIN32)
75	struct timespec ts;
76	#endif
77
78	if (fps == 0)
79		return;
80
81	ns_frame = 1000000000 / fps; /* max ns a frame can take */
82	cur_time = maus_get_time_ns();
83	elapsed = cur_time - mw->frame_time_last;
84
85	/* if early finish, sleep for the remaining time balance */
86	if (elapsed < ns_frame) {
87		sleep = ns_frame - elapsed;
88	#if !defined(_WIN32)
89		ts.tv_sec = sleep / 1000000000;
90		ts.tv_nsec = sleep % 1000000000;
91		nanosleep(&ts, NULL);
92	#else
93		Sleep((DWORD)((sleep + 999999) / 1000000));
94	#endif
95	}
96
97	mw->frame_time_last = maus_get_time_ns();
98}
99