commit fbada81

uint  ·  2026-06-09 21:56:32 +0000 UTC
parent 53f2133
Add fps targetting
5 files changed,  +44, -3
M TODO
M maus.c
M maus.h
M TODO
+0, -1
1@@ -2,7 +2,6 @@ Maus:
2 [?] Cursor warping
3 [?] Input text buffer
4 [?] Double buffering
5-[?] Clock, DT
6 [?] Custom cursor
7 
8 MausFont:
M maus.c
+34, -1
 1@@ -1,12 +1,17 @@
 2+#if !defined(BACKEND_WIN)
 3+#define _POSIX_C_SOURCE 199309L
 4+#else /* windows */
 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 
14 static void vlog(FILE* fd, const char* fmt, va_list ap);
15 
16-/* log message to output `fd` */
17 static void vlog(FILE* fd, const char* fmt, va_list ap)
18 {
19 	fprintf(fd, "maus: ");
20@@ -23,6 +28,13 @@ void maus_die(const char* fmt, ...)
21 	exit(EXIT_FAILURE);
22 }
23 
24+uint64_t maus_get_time_ns(void)
25+{ /* TODO unix only right now */
26+	struct timespec ts;
27+	clock_gettime(CLOCK_MONOTONIC, &ts);
28+	return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
29+}
30+
31 void maus_log(FILE* fd, const char* fmt, ...)
32 {
33 	va_list ap;
34@@ -32,3 +44,24 @@ void maus_log(FILE* fd, const char* fmt, ...)
35 	va_end(ap);
36 }
37 
38+void maus_target_fps(Maus* mw, uint32_t fps)
39+{
40+	if (fps == 0)
41+		return;
42+
43+	uint64_t ns_frame = 1000000000ULL / fps; /* max ns a frame can take */
44+	uint64_t cur_time = maus_get_time_ns();
45+	uint64_t elapsed = cur_time - mw->frame_time_last;
46+
47+	/* if early finish, sleep for the remaining time balance */
48+	if (elapsed < ns_frame) {
49+		uint64_t sleep = ns_frame - elapsed;
50+		struct timespec ts;
51+		ts.tv_sec = sleep / 1000000000ULL;
52+		ts.tv_nsec = sleep % 1000000000ULL;
53+		nanosleep(&ts, NULL);
54+	}
55+
56+	mw->frame_time_last = maus_get_time_ns();
57+}
58+
M maus.h
+7, -0
 1@@ -94,6 +94,7 @@ typedef struct {
 2 
 3 typedef struct {
 4 	MausBackend    backend;
 5+	uint64_t       frame_time_last;
 6 	char*          clipboard;
 7 
 8 	uint32_t*      fb;
 9@@ -135,6 +136,9 @@ void maus_die(const char* fmt, ...);
10 /* paint framebuffer with color: `col` */
11 void maus_fb_clear(Maus* mw, MausColor col);
12 
13+/* get time since arbitrary start point (ns) */
14+uint64_t maus_get_time_ns(void);
15+
16 /* initialise and fills the Maus. returns NULL on fail */
17 Maus* maus_init(const char* title, int x, int y, int width, int height);
18 
19@@ -158,6 +162,9 @@ void maus_present(Maus* mw);
20    on resize success, else false */
21 bool maus_resize(Maus* mw, uint32_t width, uint32_t height);
22 
23+/* cap framerate to targetted fps */
24+void maus_target_fps(Maus* mw, uint32_t fps);
25+
26 /* change behavior of mouse based on state passed */
27 void maus_cur_set_mode(Maus* mw, MausCursorState state);
28 
+1, -0
1@@ -545,6 +545,7 @@ Maus* maus_init(const char* title, int x, int y, int width, int height)
2 	be->display = d;
3 	be->root = DefaultRootWindow(d);
4 	be->win = None;
5+	mw->frame_time_last = maus_get_time_ns();
6 	mw->title = title;
7 	mw->width = width;
8 	mw->height = height;
+2, -1
 1@@ -96,9 +96,10 @@ int main(void)
 2 		}
 3 
 4 		char buf[512] = {0};
 5-		snprintf(buf, 512, "maus' basic-window has been running for %lld ticks!", ticks++);
 6+		snprintf(buf, 512, "maus' basic-window has been running for %lld ticks!", ticks);
 7 		maus_clipboard_set_text(mw, buf);
 8 		maus_present(mw);
 9+		maus_target_fps(mw, 1+ticks++);
10 	}
11 
12 	// rainbow