commit 633a6f36e401faca4226238463843d0b5df69a8e
parent bd001b1da3f21f46f51f06f5093312bad91932d4
Author: averagecoder <averagecoder@noreply.codeberg.org>
Date: Mon, 24 Aug 2026 18:00:48 +0300
feat: add f5 stats
Diffstat:
| M | src/render.c | | | 110 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- |
1 file changed, 84 insertions(+), 26 deletions(-)
diff --git a/src/render.c b/src/render.c
@@ -92,8 +92,13 @@ struct sys_gfx {
int in_chat, chat_len;
char chat_buf[128];
int menu_open;
+ int show_debug;
+ float fps;
+ uint32_t pkts_in, pkts_out;
+ uint32_t pkts_in_sec, pkts_out_sec;
+ float stats_timer;
KeyCode key_w, key_a, key_s, key_d, key_t,
- key_esc, key_up, key_down, key_left, key_right, key_space;
+ key_esc, key_space, key_up, key_down, key_left, key_right;
XIC ic;
XFontSet font_set;
};
@@ -768,6 +773,9 @@ net_send_sync(float px, float py, float pz, float pyaw)
sendto(net_fd, &ps, sizeof(ps), 0,
(struct sockaddr *)&srv_addr, sizeof(srv_addr));
+ if (g_sys) {
+ g_sys->pkts_out++;
+ }
}
static void
@@ -787,24 +795,9 @@ net_send_chat(const char *msg)
sendto(net_fd, &pc, sizeof(pc), 0,
(struct sockaddr *)&srv_addr, sizeof(srv_addr));
-}
-
-static void
-net_send_leave(void)
-{
- struct pkt_header ph;
-
- if (net_fd < 0 || !net_connected) {
- return;
+ if (g_sys) {
+ g_sys->pkts_out++;
}
- ph.magic = NET_MAGIC;
- ph.type = PKT_LEAVE;
- ph.player_id = (uint8_t)my_player_id;
-
- sendto(net_fd, &ph, sizeof(ph), 0,
- (struct sockaddr *)&srv_addr, sizeof(srv_addr));
- close(net_fd);
- net_fd = -1;
}
static void
@@ -823,6 +816,7 @@ net_poll(struct sys_gfx *g)
}
while ((n = recvfrom(net_fd, buf, sizeof(buf), 0, NULL, NULL)) > 0) {
+ g->pkts_in++;
if (n < (ssize_t)sizeof(struct pkt_header)) {
continue;
}
@@ -885,6 +879,24 @@ net_poll(struct sys_gfx *g)
}
static void
+net_send_leave(void)
+{
+ struct pkt_header ph;
+
+ if (net_fd < 0 || !net_connected) {
+ return;
+ }
+ ph.magic = NET_MAGIC;
+ ph.type = PKT_LEAVE;
+ ph.player_id = (uint8_t)my_player_id;
+
+ sendto(net_fd, &ph, sizeof(ph), 0,
+ (struct sockaddr *)&srv_addr, sizeof(srv_addr));
+ close(net_fd);
+ net_fd = -1;
+}
+
+static void
net_interpolate(float dt)
{
float f, dyaw;
@@ -1039,10 +1051,10 @@ gfx_cleanup(struct sys_gfx *g)
}
static void
-gfx_present(struct sys_gfx *g)
+gfx_present(struct sys_gfx *g, float px, float py, float pz)
{
char txt[256];
- int i, y_offset;
+ int i, y_offset, active_count;
if (g->menu_open) {
for (i = 0; i < WIDTH * HEIGHT; i++) {
@@ -1068,6 +1080,41 @@ gfx_present(struct sys_gfx *g)
}
}
+ if (g->show_debug) {
+ active_count = 0;
+ for (i = 0; i < MAX_PLAYERS; i++) {
+ if (net_players[i].active) {
+ active_count++;
+ }
+ }
+
+ XSetForeground(g->dpy, g->gc, 0x00FF00);
+ XSetBackground(g->dpy, g->gc, 0x000000);
+
+ snprintf(txt, sizeof(txt), "FPS: %.1f | PLAYERS: %d/%d | ID: %d",
+ g->fps, active_count, MAX_PLAYERS, my_player_id);
+ if (g->font_set) {
+ Xutf8DrawImageString(g->dpy, g->win, g->font_set, g->gc, 10, 20, txt, strlen(txt));
+ } else {
+ XDrawImageString(g->dpy, g->win, g->gc, 10, 20, txt, strlen(txt));
+ }
+
+ snprintf(txt, sizeof(txt), "POS: X=%.2f Y=%.2f Z=%.2f", px, py, pz);
+ if (g->font_set) {
+ Xutf8DrawImageString(g->dpy, g->win, g->font_set, g->gc, 10, 36, txt, strlen(txt));
+ } else {
+ XDrawImageString(g->dpy, g->win, g->gc, 10, 36, txt, strlen(txt));
+ }
+
+ snprintf(txt, sizeof(txt), "NET: IN=%u pkts/s | OUT=%u pkts/s",
+ g->pkts_in_sec, g->pkts_out_sec);
+ if (g->font_set) {
+ Xutf8DrawImageString(g->dpy, g->win, g->font_set, g->gc, 10, 52, txt, strlen(txt));
+ } else {
+ XDrawImageString(g->dpy, g->win, g->gc, 10, 52, txt, strlen(txt));
+ }
+ }
+
if (g->menu_open) {
snprintf(txt, sizeof(txt), "[ PAUSED - PRESS ESC TO RESUME ]");
XSetForeground(g->dpy, g->gc, 0xFFFFFF);
@@ -2504,15 +2551,16 @@ main(int argc, char *argv[])
struct mat4 view;
struct timespec ts, t_start, t_end;
XEvent sa_event;
+ KeySym sym;
float player_x = 2490.0f, player_y = 13.5f, player_z = -1660.0f;
float player_vy = 0.0f;
float player_yaw = 0.0f;
- int is_grounded = 0;
float cam_x, cam_y, cam_z;
float cam_yaw = -1.57f, cam_pitch = 0.2f, cam_dist = 3.5f;
float move_forward, move_strafe, move_x, move_z, move_len;
float speed, ground_y, dt, net_timer = 0.0f;
int running, tar_fd, m_dx, m_dy, gz, gx, last_mx, last_my, i;
+ int is_grounded = 0;
struct stat st;
size_t ipl_sz = 0, water_sz = 0, tc_sz = 0, col_sz = 0;
const uint8_t *ipl_data, *water_data, *tc_data, *col_data;
@@ -2619,8 +2667,6 @@ main(int argc, char *argv[])
m_dy = 0;
while (XPending(g.dpy)) {
- KeySym sym;
-
XNextEvent(g.dpy, &sa_event);
if (XFilterEvent(&sa_event, None)) {
continue;
@@ -2664,7 +2710,10 @@ main(int argc, char *argv[])
GrabModeAsync, GrabModeAsync, g.win, None, CurrentTime);
}
}
+ } else if (sym == XK_F5) {
+ g.show_debug = !g.show_debug;
}
+
if (g.in_chat) {
char str[32];
Status status;
@@ -2768,6 +2817,16 @@ main(int argc, char *argv[])
net_timer = 0.0f;
}
+ g.stats_timer += dt;
+ if (g.stats_timer >= 1.0f) {
+ g.pkts_in_sec = g.pkts_in;
+ g.pkts_out_sec = g.pkts_out;
+ g.pkts_in = 0;
+ g.pkts_out = 0;
+ g.stats_timer = 0.0f;
+ }
+ g.fps = g.fps * 0.90f + (1.0f / dt) * 0.10f;
+
move_forward = 0.0f;
move_strafe = 0.0f;
@@ -2843,8 +2902,7 @@ main(int argc, char *argv[])
cam_z = player_z - cosf(cam_yaw) * cosf(cam_pitch) * cam_dist;
update_weather(&g);
- mat_projection(&g.proj, 60.0f, (float)WIDTH / HEIGHT, 0.1f,
- g.cur_weather.far_clp);
+ mat_projection(&g.proj, 60.0f, (float)WIDTH / HEIGHT, 0.1f, g.cur_weather.far_clp);
memset(g.zbuffer, 0, WIDTH * HEIGHT * sizeof(float));
mat_view(&view, cam_x, cam_y, cam_z, cam_yaw, cam_pitch);
@@ -2852,7 +2910,7 @@ main(int argc, char *argv[])
player_x, player_y, player_z, player_yaw);
draw_water(&g.proj, &view);
draw_infinite_ocean(&g.proj, &view, cam_x, cam_z, g.game_time_sec);
- gfx_present(&g);
+ gfx_present(&g, player_x, player_y, player_z);
}
net_send_leave();