master uint/maus / 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_sleep(uint32_t ms)
 68{
 69#if !defined(_WIN32)
 70	struct timespec ts;
 71
 72	ts.tv_sec = ms / 1000;
 73	ts.tv_nsec = (ms % 1000) * 1000000;
 74	nanosleep(&ts, NULL);
 75#else
 76	Sleep((DWORD)ms);
 77#endif
 78}
 79
 80void maus_target_fps(Maus* mw, uint32_t fps)
 81{
 82	uint64_t ns_frame;
 83	uint64_t cur_time;
 84	uint64_t elapsed;
 85	uint64_t sleep;
 86
 87	if (fps == 0)
 88		return;
 89
 90	ns_frame = 1000000000 / fps; /* max ns a frame can take */
 91	cur_time = maus_get_time_ns();
 92	elapsed = cur_time - mw->frame_time_last;
 93
 94	/* if early finish, sleep for the remaining time balance */
 95	if (elapsed < ns_frame) {
 96		sleep = ns_frame - elapsed;
 97		maus_sleep((uint32_t)((sleep + 999999) / 1000000));
 98	}
 99
100	mw->frame_time_last = maus_get_time_ns();
101}
102