commit fbada81
uint
·
2026-06-09 21:56:32 +0000 UTC
parent 53f2133
Add fps targetting
5 files changed,
+44,
-3
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