This commit is contained in:
2025-07-22 20:21:38 +02:00
parent 57ec875662
commit d09cd20cdc
15 changed files with 158 additions and 75 deletions
+19 -17
View File
@@ -1,23 +1,25 @@
;; The function is evaulated and returns a pointer, the game eats it
;; and adds it to the UI root. Boom.
(widget-new
'window
#:style style-window
#:text "Debug window"
#:w 350
#:layout-padding 8
#:vertical #f
#:horizontal #t
;; The rest is children.
'plain
(widget-new
'flowbox
#:style style-container
'window
#:style style-window
#:text "Debug window"
#:w 350
#:layout-padding 8
#:layout-spacing 8
#:vertical #f
#:horizontal #t
(widget-label-gvar 'float "Delta time: ~,2f" "delta_time" #:style style-default #:layout-weight 1 #:h 20 #:text-alignment 'center)
(widget-label-gvar 'int "~d chunks" "frame_chunks" #:style style-default #:layout-weight 0.5 #:h 20)
(widget-label-gvar 'int "~d entities" "frame_entities" #:style style-default #:layout-weight 0.5 #:h 20)
(widget-checkbox "Flight" "flight_enabled" #:layout-weight 0.5 #:h 20)
(widget-checkbox "Wireframe" "wireframe_enabled" #:layout-weight 0.5 #:h 20)
(widget-spinner 'int "Render distance: ~d" "render_distance" #:layout-weight 1 #:h 20)))
;; The rest is children.
(widget-new
'flowbox
#:style style-container
#:layout-padding 8
#:layout-spacing 8
#:horizontal #t
(widget-label-gvar 'float "Delta time: ~,2f" "delta_time" #:style style-default #:layout-weight 1 #:h 20 #:text-alignment 'center)
(widget-label-gvar 'int "~d chunks" "frame_chunks" #:style style-default #:layout-weight 0.5 #:h 20)
(widget-label-gvar 'int "~d entities" "frame_entities" #:style style-default #:layout-weight 0.5 #:h 20)
(widget-checkbox "Flight" "flight_enabled" #:layout-weight 0.5 #:h 20)
(widget-checkbox "Wireframe" "wireframe_enabled" #:layout-weight 0.5 #:h 20)
(widget-spinner 'int "Render distance: ~d" "render_distance" #:layout-weight 1 #:h 20))))
+12 -9
View File
@@ -1,11 +1,14 @@
(widget-new
'flowbox
#:style style-container
#:layout-padding 8
#:layout-spacing 8
#:horizontal #t
(widget-new 'label #:style style-button #:layout-weight 1 #:h 20 #:text-alignment 'center #:text "New game"
#:on-click (lambda (w e) (switch-stage "game")))
(widget-new 'label #:style style-button #:layout-weight 1 #:h 20 #:text-alignment 'center #:text "Options")
(widget-new 'label #:style style-button #:layout-weight 1 #:h 20 #:text-alignment 'center #:text "Quit game"))
'plain
(widget-new
'flowbox
#:style style-container
#:w 300
#:layout-padding 8
#:layout-spacing 8
#:horizontal #t
(widget-new 'label #:style style-button #:layout-weight 1 #:h 20 #:text-alignment 'center #:text "New game"
#:on-click (lambda (w e) (switch-stage "ingame")))
(widget-new 'label #:style style-button #:layout-weight 1 #:h 20 #:text-alignment 'center #:text "Options")
(widget-new 'label #:style style-button #:layout-weight 1 #:h 20 #:text-alignment 'center #:text "Quit game")))
+8 -9
View File
@@ -5,6 +5,9 @@ static GHashTable *chunk_meshes;
static gboolean bound = false;
static Profiler profiler;
static const int frame_budget_us = 500;
guint
chunkman_ivec2_hash (gconstpointer key)
{
@@ -105,9 +108,7 @@ chunkman_tick (vec3 position)
int cx, cz;
chunkman_world_to_chunk (position[0], position[2], &cx, &cz);
uint64_t start = SDL_GetPerformanceCounter ();
uint64_t freq = SDL_GetPerformanceFrequency ();
double elapsed_us = 0;
Profiler_begin (&profiler);
int render_distance = gvar_get ("render_distance");
@@ -115,10 +116,9 @@ chunkman_tick (vec3 position)
{
for (int x = cx - render_distance - 1; x <= cx + render_distance + 1; ++x)
{
uint64_t now = SDL_GetPerformanceCounter ();
elapsed_us = (double) (now - start) * 1000000.0 / (double) freq;
double elapsed = Profiler_sample (&profiler);
if (elapsed_us > CHUNK_FRAME_BUDGET_US)
if (elapsed > frame_budget_us)
{
return;
}
@@ -134,10 +134,9 @@ chunkman_tick (vec3 position)
{
for (int x = cx - render_distance; x <= cx + render_distance; ++x)
{
uint64_t now = SDL_GetPerformanceCounter ();
elapsed_us = (double) (now - start) * 1000000.0 / (double) freq;
double elapsed = Profiler_sample (&profiler);
if (elapsed_us > CHUNK_FRAME_BUDGET_US)
if (elapsed > frame_budget_us)
{
return;
}
+1
View File
@@ -10,6 +10,7 @@
#include "../graphics.h"
#include "../gvar.h"
#include "../pakman.h"
#include "../profiler.h"
#define TERRAIN_HEIGHT 8.0
+11 -8
View File
@@ -19,10 +19,14 @@ static unsigned int last_type = 0;
static unsigned int last_texture = 0;
/* These are defined as statics so we don't get those values from gvar
every frame.. */
for every entity... */
static int render_distance = 2;
static gboolean wireframe_enabled = FALSE;
static Profiler profiler = { 0 };
static const int frame_budget_us = 500;
void
character_on_tick (Entity *entity)
{
@@ -63,7 +67,9 @@ void
spawn_queue_process_one ()
{
if (g_queue_is_empty(spawn_requests))
return;
{
return;
}
SpawnRequest *req = g_queue_pop_head (spawn_requests);
@@ -80,16 +86,13 @@ spawn_queue_process_one ()
void
entman_tick ()
{
uint64_t start = SDL_GetPerformanceCounter ();
uint64_t freq = SDL_GetPerformanceFrequency ();
double elapsed_us = 0;
Profiler_begin (&profiler);
while (!g_queue_is_empty (spawn_requests))
{
uint64_t now = SDL_GetPerformanceCounter();
elapsed_us = (double) (now - start) * 1000000.0 / (double) freq;
double elapsed = Profiler_sample (&profiler);
if (elapsed_us > ENTITY_FRAME_BUDGET_US)
if (elapsed > frame_budget_us)
{
break;
}
+1
View File
@@ -14,6 +14,7 @@
#include "../graphics.h"
#include "../gvar.h"
#include "../pakman.h"
#include "../profiler.h"
#define ENTADD(entity) (entman_add_entity (entity))
+2 -12
View File
@@ -2,24 +2,14 @@
#include <SDL3/SDL.h>
#include <SDL3/SDL_opengles2.h>
#include <SDL3_image/SDL_image.h>
#include "chunk/chunkman.h"
#include "entity/entman.h"
#include <cglm/cglm.h>
#include "util.h"
#include "gvar.h"
#include "pakman.h"
#define FRUSTUM_CULL 1
#define CHUNK_FRAME_BUDGET_US 500
#define ENTITY_FRAME_BUDGET_US 500
#define RENDER_FRAME_BUDGET_US 16666 /* 60 FPS */
#define RENDER_AVG_FREQ_S 10
#define RENDER_DISTANCE_MIN 2
#define RENDER_DISTANCE_MAX 12
void graphics_init ();
void graphics_prerender ();
void graphics_postrender ();
+47
View File
@@ -0,0 +1,47 @@
#include "profiler.h"
void
Profiler_begin (Profiler *p)
{
p->start_time = SDL_GetPerformanceCounter ();
}
double
Profiler_sample (Profiler *p)
{
uint64_t now = SDL_GetPerformanceCounter ();
uint64_t freq = SDL_GetPerformanceFrequency ();
double elapsed_us = (double) (now - p->start_time) * 1000000.0 / (double) freq;
p->total_us += elapsed_us;
p->sample_count += 1;
return elapsed_us;
}
void
Profiler_reset (Profiler *p)
{
p->total_us = 0.0;
p->sample_count = 0;
p->last_check_time = SDL_GetPerformanceCounter();
}
double
Profiler_average (Profiler *p)
{
if (p->sample_count == 0)
{
return 0;
}
return p->total_us / (double) p->sample_count;
}
gboolean
Profiler_should_check (Profiler *p, int seconds)
{
uint64_t now = SDL_GetPerformanceCounter ();
uint64_t freq = SDL_GetPerformanceFrequency ();
return (now - p->last_check_time) >= (uint64_t) (freq * seconds);
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <SDL3/SDL.h>
#include <glib-2.0/glib.h>
typedef struct Profiler
{
uint64_t start_time, last_check_time;
double total_us;
int sample_count;
} Profiler;
void Profiler_begin (Profiler *p);
double Profiler_sample (Profiler *p);
void Profiler_reset (Profiler *p);
double Profiler_average (Profiler *p);
gboolean Profiler_should_check (Profiler *p, int seconds);
-9
View File
@@ -1,9 +0,0 @@
#pragma once
#include "stage_common.h"
#include "../graphics.h"
#include "../gvar.h"
#include "../camera.h"
GameStage *stage_game_new ();
-6
View File
@@ -1,16 +1,11 @@
#include "stage_global.h"
/* The required callbacks. */
static void
_on_enter ()
{
gvar_set ("last_time", SDL_GetTicks ());
g_print ("Successfuly initialized global stage\n");
}
static void _on_exit () { return; }
static void
_on_update ()
{
@@ -31,7 +26,6 @@ stage_global_new ()
#undef GAEH
self->on_enter = _on_enter;
self->on_exit = _on_exit;
self->on_update = _on_update;
return self;
@@ -1,9 +1,15 @@
#include "stage_game.h"
#include "stage_ingame.h"
extern SDL_Window *sdl_window;
extern Entity *player_entity, *sky_entity;
static Profiler profiler = { 0 };
static const int profiler_check_freq_s = 10;
static const int render_frame_budget_us = 16666;
static const int render_distance_min = 2;
static const int render_distance_max = 12;
static void
_on_enter ()
{
@@ -92,6 +98,8 @@ _on_update (GameStage *self)
static void
_on_render (GameStage *self)
{
Profiler_begin (&profiler);
mat4 projection, view;
Camera_get_projection (self->camera, gvar_get ("window_width") / gvar_get ("window_height"), projection);
Camera_get_view (self->camera, view);
@@ -109,6 +117,19 @@ _on_render (GameStage *self)
chunkman_render (self->camera->position, planes);
entman_render (self->camera->position, view, planes);
Profiler_sample (&profiler);
if (Profiler_should_check (&profiler, profiler_check_freq_s))
{
int render_distance = gvar_get ("render_distance");
render_distance += Profiler_average (&profiler) < render_frame_budget_us ? 1 : -1;
render_distance = glm_clamp (render_distance, render_distance_min, render_distance_max);
gvar_set ("render_distance", render_distance);
Profiler_reset (&profiler);
}
}
/* Some helper callbacks for the game gamestage. */
@@ -141,7 +162,7 @@ _freelook_camera (SDL_Event *event, void *userdata)
}
GameStage *
stage_game_new ()
stage_ingame_new ()
{
GameStage *self = GameStage_new ();
+13
View File
@@ -0,0 +1,13 @@
#pragma once
#include "stage_common.h"
#include "../gvar.h"
#include "../camera.h"
#include "../profiler.h"
#include "../graphics.h"
#include "../entity/entman.h"
#include "../chunk/chunkman.h"
GameStage *stage_ingame_new ();
+1 -1
View File
@@ -11,7 +11,7 @@ stageman_init ()
game_stages = g_hash_table_new (g_str_hash, g_str_equal);
stageman_add_stage ("main_menu", stage_main_menu_new ());
stageman_add_stage ("game", stage_game_new ());
stageman_add_stage ("ingame", stage_ingame_new ());
global_stage = stage_global_new ();
global_stage->on_enter (global_stage);
+1 -1
View File
@@ -6,7 +6,7 @@
#include "stage_global.h"
#include "stage_main_menu.h"
#include "stage_game.h"
#include "stage_ingame.h"
void stageman_init ();
void stageman_guile_register ();