Optimizations, changes

This commit is contained in:
2025-07-21 22:55:29 +02:00
parent ded6cfd686
commit 57ec875662
20 changed files with 263 additions and 269 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
#: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) (stateman-switch-state "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"))
+16 -14
View File
@@ -4,34 +4,36 @@ vec3 camera_position;
vec3 camera_rotation;
void
camera_get_direction (vec3 dest)
Camera_get_direction (Camera *camera, vec3 dest)
{
dest[0] = sinf (camera_rotation[0]) * cosf (camera_rotation[1]);
dest[1] = sinf (camera_rotation[1]);
dest[2] = cosf (camera_rotation[0]) * cosf (camera_rotation[1]);
glm_vec3_normalize (dest);
dest[0] = sinf (camera->rotation[0]) * cosf (camera->rotation[1]);
dest[1] = sinf (camera->rotation[1]);
dest[2] = cosf (camera->rotation[0]) * cosf (camera->rotation[1]);
glm_vec3_normalize (dest);
}
void
camera_get_right (vec3 dest)
Camera_get_right (Camera *camera, vec3 dest)
{
vec3 dir;
camera_get_direction (dir);
Camera_get_direction (camera, dir);
glm_vec3_cross (dir, GLM_YUP, dest);
glm_vec3_normalize (dest);
glm_vec3_normalize (dest);
}
void
camera_get_view (mat4 dest)
Camera_get_view (Camera *camera, mat4 dest)
{
vec3 dir, center;
camera_get_direction (dir);
glm_vec3_add (camera_position, dir, center);
glm_lookat (camera_position, center, GLM_YUP, dest);
Camera_get_direction (camera, dir);
glm_vec3_add (camera->position, dir, center);
glm_lookat (camera->position, center, GLM_YUP, dest);
}
void
camera_get_projection (float aspect, mat4 dest)
Camera_get_projection (Camera *camera, float aspect, mat4 dest)
{
glm_perspective (glm_rad (70), aspect, 0.01, 7000.0, dest);
(void) camera;
glm_perspective (glm_rad (70), aspect, 0.01, 7000.0, dest);
}
+10
View File
@@ -2,6 +2,16 @@
#include <cglm/cglm.h>
typedef struct Camera
{
vec3 position, rotation;
} Camera;
void Camera_get_direction (Camera *camera, vec3 dest);
void Camera_get_right (Camera *camera, vec3 dest);
void Camera_get_view (Camera *camera, mat4 dest);
void Camera_get_projection (Camera *camera, float aspect, mat4 dest);
void camera_get_direction (vec3 dest);
void camera_get_right (vec3 dest);
void camera_get_view (mat4 dest);
+14 -36
View File
@@ -6,8 +6,6 @@
/* TODO: Instead of having a huge far plane, render the clouds
seperately somehow. */
extern vec3 camera_position;
Entity *player_entity, *sky_entity;
/* The GArray is the fastest of all sequence types. Should work fine
@@ -20,6 +18,11 @@ static unsigned int last_program = 0;
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.. */
static int render_distance = 2;
static gboolean wireframe_enabled = FALSE;
void
character_on_tick (Entity *entity)
{
@@ -107,21 +110,13 @@ entman_tick ()
}
gboolean
entman_render_entity (Entity *entity, void *userdata)
entman_render_entity (Entity *entity, vec3 camera_position, mat4 view, vec4 frustum_planes[6])
{
struct {
mat4 *view;
#ifdef FRUSTUM_CULL
vec4 *frustum_planes[6];
#endif
} *vp = userdata;
if (!entity->visible)
{
return FALSE;
}
int render_distance = gvar_get ("render_distance");
/* Why an int, why int division? It's simply much faster than
floating point operations. No need to have super accurate cull
distance anyway, and might as well save a lot when rendering entities. */
@@ -142,7 +137,7 @@ entman_render_entity (Entity *entity, void *userdata)
vec3 aabb[2];
entity_compute_aabb (entity, aabb[0], aabb[1]);
if (!glm_aabb_frustum (aabb, *vp->frustum_planes))
if (!glm_aabb_frustum (aabb, frustum_planes))
{
return FALSE;
}
@@ -170,7 +165,7 @@ entman_render_entity (Entity *entity, void *userdata)
{
case RENDER_BILLBOARD:
mat4 inv_view;
glm_mat4_copy (*vp->view, inv_view);
glm_mat4_copy (view, inv_view);
glm_mat4_inv (inv_view, inv_view);
vec3 right = { inv_view[0][0], inv_view[1][0], inv_view[2][0] };
@@ -232,39 +227,22 @@ entman_render_entity (Entity *entity, void *userdata)
last_type = entity->mesh_type;
}
SimpleMesh_render (&to_render, FLAG_GET ("wireframe_enabled"));
SimpleMesh_render (&to_render, wireframe_enabled);
return TRUE;
}
void
entman_render (mat4 *view, vec4 planes[6])
entman_render (vec3 camera_position, mat4 view, vec4 planes[6])
{
#if !FRUSTUM_CULL
UNUSED (planes);
#endif
last_program = -1;
last_texture = -1;
last_type = -1;
struct {
mat4 *view;
#if FRUSTUM_CULL
vec4 *frustum_planes;
#endif
} data = {
view
#if FRUSTUM_CULL
,planes
#endif
};
int frame_entities = 0;
render_distance = gvar_get ("render_distance");
wireframe_enabled = gvar_get ("wireframe_enabled");
for (guint i = 0; i < entities->len; ++i)
{
Entity *e = g_array_index (entities, Entity*, i);
frame_entities += entman_render_entity (e, &data) ? 1 : 0;
frame_entities += entman_render_entity (e, camera_position, view, planes) ? 1 : 0;
}
gvar_set ("frame_entities", frame_entities);
+1 -1
View File
@@ -27,6 +27,6 @@ typedef struct SpawnRequest
void entman_init ();
void entman_tick ();
void entman_render ();
void entman_render (vec3 camera_position, mat4 view, vec4 planes[6]);
void entman_add_entity (Entity *entity);
void entman_add_spawn_request (char *template_name, vec3 position, vec3 rotation, vec3 scale);
+1 -1
View File
@@ -81,5 +81,5 @@ graphics_cb_window_resize (SDL_Event *event, void *data)
gvar_set ("window_width", sdl_window_w);
gvar_set ("window_height", sdl_window_h);
/* Since other subsystems might want to use the event. */
return FALSE;
return TRUE;
}
+9 -9
View File
@@ -9,7 +9,7 @@
#include "graphics.h"
#include "gvar.h"
#include "pakman.h"
#include "states/stateman.h"
#include "stage/stageman.h"
SDL_AppResult
SDL_AppInit (void **appstate, int argc, char **argv)
@@ -21,12 +21,12 @@ SDL_AppInit (void **appstate, int argc, char **argv)
things. */
scm_init_guile ();
gvar_guile_register ();
stateman_guile_register ();
stageman_guile_register ();
widget_guile_register ();
entity_guile_register ();
pakman_guile_register ();
/* The basics; game variables, graphics, the state manager, and the
/* The basics; game variables, graphics, the stage manager, and the
pak manager. */
gvar_init ();
graphics_init ();
@@ -34,7 +34,7 @@ SDL_AppInit (void **appstate, int argc, char **argv)
/* The base pack is always required, as it contains all the data
needed for the functioning of the UI and graphics. */
pakman_load_pak ("res/");
stateman_init ();
stageman_init ();
/* I don't know. This probably needs to be moved somewhere. */
@@ -45,7 +45,7 @@ SDL_AppInit (void **appstate, int argc, char **argv)
entman_init ();
chunkman_init ();
stateman_switch_state ("main_menu");
stageman_switch_stage ("main_menu");
return SDL_APP_CONTINUE;
}
@@ -60,7 +60,7 @@ SDL_AppEvent (void *appstate, SDL_Event *event)
return SDL_APP_SUCCESS;
}
stateman_on_SDL_Event (event);
stageman_on_SDL_Event (event);
return SDL_APP_CONTINUE;
}
@@ -70,10 +70,10 @@ SDL_AppIterate (void *appstate)
{
UNUSED (appstate);
stateman_update ();
stageman_update ();
graphics_prerender ();
stateman_render ();
stageman_render ();
graphics_postrender ();
return SDL_APP_CONTINUE;
@@ -84,5 +84,5 @@ SDL_AppQuit (void *appstate, SDL_AppResult result)
{
UNUSED (appstate, result);
graphics_free ();
stateman_free ();
stageman_free ();
}
@@ -1,21 +1,22 @@
#include "state_common.h"
#include "stage_common.h"
GameState *
GameState_new ()
GameStage *
GameStage_new ()
{
GameState *g = g_new0 (GameState, 1);
GameStage *g = g_new0 (GameStage, 1);
g->ui_context = UIContext_new ();
g->ui_context->tooltip = PMUID ("tooltip");
g->camera = g_new0 (Camera, 1);
return g;
}
void
GameState_register_UIContext_handlers (GameState *self)
GameStage_register_UIContext_handlers (GameStage *self)
{
/* UGH... I fucking hate this whole structure of the game I did
here. It should be really extensible and whatnot, but jesus
christ, it's so complex... */
#define GAEH GameState_add_event_handler
#define GAEH GameStage_add_event_handler
GAEH (self, 1, SDL_EVENT_WINDOW_RESIZED, NULL, NULL, UIContext_window_resize,self->ui_context);
GAEH (self, 1, SDL_EVENT_KEY_DOWN, evt_pred_flag, "ui_has_focus", UIContext_key_down, self->ui_context);
@@ -30,7 +31,7 @@ GameState_register_UIContext_handlers (GameState *self)
}
void
GameState_add_event_handler (GameState *self, int priority, unsigned int on_event,
GameStage_add_event_handler (GameStage *self, int priority, unsigned int on_event,
gboolean (*predicate) (SDL_Event *sdl_event, void *userdata),
void *predicate_data,
gboolean (*callback) (SDL_Event *sdl_event, void *userdata),
@@ -54,7 +55,7 @@ GameState_add_event_handler (GameState *self, int priority, unsigned int on_even
}
void
GameState_handle_SDL_Event (GameState *self, SDL_Event *event)
GameStage_handle_SDL_Event (GameStage *self, SDL_Event *event)
{
for (GList *l = self->event_handlers; l != NULL; l = l->next)
{
@@ -7,6 +7,7 @@
#include "../util.h"
#include "../gvar.h"
#include "../camera.h"
typedef struct {
unsigned int on_event;
@@ -16,28 +17,31 @@ typedef struct {
gboolean (*callback) (SDL_Event *sdl_event, void *userdata);
} EventHandler;
typedef struct GameState
typedef struct GameStage
{
UIContext *ui_context;
UIContext *ui_context; /* Could be NULL... */
Camera *camera; /* Doesn't have to be defined. */
GList *event_handlers;
void *userdata;
void (*on_enter) (struct GameStage *);
void (*on_exit) (struct GameStage *);
void (*on_update) (struct GameStage *);
void (*on_render) (struct GameStage *);
} GameStage;
void (*on_enter) (struct GameState *);
void (*on_exit) (struct GameState *);
void (*on_update) (struct GameState *);
void (*on_render) (struct GameState *);
} GameState;
GameStage *GameStage_new ();
GameState *GameState_new ();
void GameStage_register_UIContext_handlers (GameStage *self);
void GameState_register_UIContext_handlers (GameState *self);
void GameState_add_event_handler (GameState *self, int priority, unsigned int on_event,
void GameStage_add_event_handler (GameStage *self, int priority, unsigned int on_event,
gboolean (*predicate) (SDL_Event *sdl_event, void *userdata),
void *predicate_data,
gboolean (*callback) (SDL_Event *sdl_event, void *userdata),
void *callback_data);
void GameState_handle_SDL_Event (GameState *self, SDL_Event *event);
void GameStage_handle_SDL_Event (GameStage *self, SDL_Event *event);
gboolean evt_pred_key (SDL_Event *event, void *data);
gboolean evt_pred_flag (SDL_Event *event, void *data);
@@ -1,6 +1,5 @@
#include "state_game.h"
#include "stage_game.h"
extern vec3 camera_position, camera_rotation;
extern SDL_Window *sdl_window;
extern Entity *player_entity, *sky_entity;
@@ -12,21 +11,21 @@ _on_enter ()
}
static void
_on_update ()
_on_update (GameStage *self)
{
chunkman_tick (camera_position);
chunkman_tick (self->camera->position);
entman_tick ();
/* We pin the camera to the player position, with eye level 20
centimeters below the height. */
glm_vec3_copy (player_entity->position, camera_position);
camera_position[1] += player_entity->scale[1] - 0.2;
player_entity->rotation[1] = camera_rotation[1];
glm_vec3_copy (player_entity->position, self->camera->position);
self->camera->position[1] += player_entity->scale[1] - 0.2;
player_entity->rotation[1] = self->camera->rotation[1];
/* The sky needs to be in the center of the world all the time,
otherwise, as we explore the world, we might reach the end of the
sky. */
sky_entity->position[0] = camera_position[0];
sky_entity->position[2] = camera_position[2];
sky_entity->position[0] = self->camera->position[0];
sky_entity->position[2] = self->camera->position[2];
int speed = 5;
float delta_time = gvar_get ("delta_time");
@@ -39,7 +38,7 @@ _on_update ()
if (FLAG_GET ("moving_forward"))
{
vec3 dir, change, new_pos;
camera_get_direction (dir);
Camera_get_direction (self->camera, dir);
glm_vec3_scale (dir, delta_time * speed, change);
glm_vec3_add (player_entity->position, change, new_pos);
glm_vec3_copy (new_pos, player_entity->position);
@@ -48,7 +47,7 @@ _on_update ()
if (FLAG_GET ("moving_backward"))
{
vec3 dir, change, new_pos;
camera_get_direction (dir);
Camera_get_direction (self->camera, dir);
glm_vec3_scale (dir, delta_time * speed, change);
glm_vec3_sub (player_entity->position, change, new_pos);
glm_vec3_copy (new_pos, player_entity->position);
@@ -57,7 +56,7 @@ _on_update ()
if (FLAG_GET ("moving_right"))
{
vec3 right, change, new_pos;
camera_get_right (right);
Camera_get_right (self->camera, right);
glm_vec3_scale (right, delta_time * speed, change);
glm_vec3_add (player_entity->position, change, new_pos);
glm_vec3_copy (new_pos, player_entity->position);
@@ -66,7 +65,7 @@ _on_update ()
if (FLAG_GET ("moving_left"))
{
vec3 right, change, new_pos;
camera_get_right (right);
Camera_get_right (self->camera, right);
glm_vec3_scale (right, delta_time * speed, change);
glm_vec3_sub (player_entity->position, change, new_pos);
glm_vec3_copy (new_pos, player_entity->position);
@@ -91,11 +90,11 @@ _on_update ()
}
static void
_on_render ()
_on_render (GameStage *self)
{
mat4 projection, view;
camera_get_projection (gvar_get ("window_width") / gvar_get ("window_height"), projection);
camera_get_view (view);
Camera_get_projection (self->camera, gvar_get ("window_width") / gvar_get ("window_height"), projection);
Camera_get_view (self->camera, view);
pakman_all_paks_set_mat4 ("projection", projection);
pakman_all_paks_set_mat4 ("view", view);
@@ -108,11 +107,11 @@ _on_render ()
glm_frustum_planes (view_proj, planes);
#endif
chunkman_render (camera_position, planes);
entman_render (view, planes);
chunkman_render (self->camera->position, planes);
entman_render (self->camera->position, view, planes);
}
/* Some helper callbacks for the game gamestate. */
/* Some helper callbacks for the game gamestage. */
gboolean
_switch_ui_focus (SDL_Event *event, void *data)
@@ -132,29 +131,30 @@ _switch_ui_focus (SDL_Event *event, void *data)
gboolean
_freelook_camera (SDL_Event *event, void *userdata)
{
UNUSED (userdata);
camera_rotation[0] -= event->motion.xrel / 100.f;
camera_rotation[1] -= event->motion.yrel / 100.f;
camera_rotation[1] =
glm_clamp (camera_rotation[1], -M_PI / 2 + 0.025, M_PI / 2 - 0.025);
Camera *cam = userdata;
cam->rotation[0] -= event->motion.xrel / 100.f;
cam->rotation[1] -= event->motion.yrel / 100.f;
cam->rotation[1] =
glm_clamp (cam->rotation[1], -M_PI / 2 + 0.025, M_PI / 2 - 0.025);
return TRUE;
}
GameState *
state_game_new ()
GameStage *
stage_game_new ()
{
GameState *self = GameState_new ();
GameStage *self = GameStage_new ();
self->on_enter = _on_enter;
self->on_update = _on_update;
self->on_render = _on_render;
#define KEY(k) GINT_TO_POINTER(k)
#define GAEH GameState_add_event_handler
#define GAEH GameStage_add_event_handler
GAEH (self, 0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_TAB), _switch_ui_focus, self->ui_context);
GAEH (self, 0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_TAB), _switch_ui_focus, self->ui_context);
GAEH (self, 0, SDL_EVENT_MOUSE_MOTION, NULL, NULL, _freelook_camera, NULL);
GAEH (self, 0, SDL_EVENT_MOUSE_MOTION, NULL, NULL, _freelook_camera, self->camera);
GAEH (self, 0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_W), evt_cb_flag_on, "moving_forward");
GAEH (self, 0, SDL_EVENT_KEY_UP, evt_pred_key, KEY (SDLK_W), evt_cb_flag_off, "moving_forward");
@@ -171,12 +171,11 @@ state_game_new ()
GAEH (self, 0, SDL_EVENT_KEY_DOWN, evt_pred_key, KEY (SDLK_LSHIFT), evt_cb_flag_on, "flying_fast");
GAEH (self, 0, SDL_EVENT_KEY_UP, evt_pred_key, KEY (SDLK_LSHIFT), evt_cb_flag_off, "flying_fast");
#undef GAEH
#undef KEY
/* If your GameState uses the UI, always call this. */
GameState_register_UIContext_handlers (self);
/* If your GameStage uses the UI, always call this. */
GameStage_register_UIContext_handlers (self);
self->ui_context->root = PMUID ("debug_window");
return self;
@@ -1,9 +1,9 @@
#pragma once
#include "state_common.h"
#include "stage_common.h"
#include "../graphics.h"
#include "../gvar.h"
#include "../camera.h"
GameState *state_game_new ();
GameStage *stage_game_new ();
@@ -1,4 +1,4 @@
#include "state_global.h"
#include "stage_global.h"
/* The required callbacks. */
@@ -6,7 +6,7 @@ static void
_on_enter ()
{
gvar_set ("last_time", SDL_GetTicks ());
g_print ("Successfuly initialized global state\n");
g_print ("Successfuly initialized global stage\n");
}
static void _on_exit () { return; }
@@ -19,12 +19,12 @@ _on_update ()
gvar_set ("last_time", now);
}
GameState *
state_global_new ()
GameStage *
stage_global_new ()
{
GameState *self = GameState_new ();
GameStage *self = GameStage_new ();
#define GAEH GameState_add_event_handler
#define GAEH GameStage_add_event_handler
GAEH (self, 0, SDL_EVENT_WINDOW_RESIZED, NULL, NULL, graphics_cb_window_resize, NULL);
@@ -1,8 +1,8 @@
#pragma once
#include "state_common.h"
#include "stage_common.h"
#include "../graphics.h"
#include "../gvar.h"
GameState *state_global_new ();
GameStage *stage_global_new ();
+21
View File
@@ -0,0 +1,21 @@
#include "stage_main_menu.h"
static void
_on_enter ()
{
gvar_set ("ui_has_focus", TRUE);
}
GameStage *
stage_main_menu_new ()
{
GameStage *g = GameStage_new ();
g->on_enter = _on_enter;
/* If your GameStage uses the UI, always call this. */
GameStage_register_UIContext_handlers (g);
g->ui_context->root = PMUID ("main_menu");
return g;
}
@@ -1,8 +1,8 @@
#pragma once
#include "state_common.h"
#include "stage_common.h"
#include "../graphics.h"
#include "../gvar.h"
GameState *state_main_menu_new ();
GameStage *stage_main_menu_new ();
+102
View File
@@ -0,0 +1,102 @@
#include "stageman.h"
static GHashTable *game_stages;
static GameStage *current_stage;
static GameStage *global_stage;
void
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 ());
global_stage = stage_global_new ();
global_stage->on_enter (global_stage);
}
static SCM
_scm_switch_stage (SCM stage_val)
{
char *stage = scm_to_utf8_string (stage_val);
stageman_switch_stage (stage);
return SCM_UNSPECIFIED;
}
void
stageman_guile_register ()
{
scm_c_define_gsubr ("switch-stage", 1, 0, 0, _scm_switch_stage);
}
void
stageman_add_stage (const char *name, GameStage *stage)
{
g_hash_table_replace (game_stages, g_strdup (name), stage);
}
void
stageman_switch_stage (const char *name)
{
GameStage *next_stage = g_hash_table_lookup (game_stages, name);
if (current_stage && current_stage->on_exit)
{
current_stage->on_exit (current_stage);
}
if (next_stage && next_stage->on_enter)
{
/* When we enter, we also set the UI root to be the current
window size. After that, if callbacks for a given stage are
set up correctly (using
GameStage_register_UIContext_handlers), then it will update
the root size automatically.*/
next_stage->ui_context->root->size[0] = gvar_get ("window_width");
next_stage->ui_context->root->size[1] = gvar_get ("window_height");
next_stage->on_enter (next_stage);
current_stage = next_stage;
}
}
void stageman_update ()
{
global_stage->on_update (global_stage);
if (current_stage && current_stage->on_update)
{
current_stage->on_update (current_stage);
}
if (current_stage && current_stage->ui_context)
{
UIContext_update (current_stage->ui_context);
}
}
void
stageman_on_SDL_Event (SDL_Event *event)
{
GameStage_handle_SDL_Event (global_stage, event);
if (current_stage && current_stage->event_handlers)
{
GameStage_handle_SDL_Event (current_stage, event);
}
}
void
stageman_render ()
{
if (current_stage && current_stage->on_render)
{
current_stage->on_render (current_stage);
}
if (current_stage && current_stage->ui_context)
{
UIContext_render (current_stage->ui_context);
}
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include <glib-2.0/glib.h>
#include "stage_common.h"
#include "stage_global.h"
#include "stage_main_menu.h"
#include "stage_game.h"
void stageman_init ();
void stageman_guile_register ();
static inline void stageman_free () { } /* TODO: implement */
void stageman_add_stage (const char *name, GameStage *stage);
void stageman_switch_stage (const char *name);
void stageman_update ();
void stageman_on_SDL_Event (SDL_Event *event);
void stageman_render ();
-21
View File
@@ -1,21 +0,0 @@
#include "state_main_menu.h"
static void
_on_enter ()
{
gvar_set ("ui_has_focus", TRUE);
}
GameState *
state_main_menu_new ()
{
GameState *g = GameState_new ();
g->on_enter = _on_enter;
/* If your GameState uses the UI, always call this. */
GameState_register_UIContext_handlers (g);
g->ui_context->root = PMUID ("main_menu");
return g;
}
-102
View File
@@ -1,102 +0,0 @@
#include "stateman.h"
static GHashTable *game_states;
static GameState *current_state;
static GameState *global_state;
void
stateman_init ()
{
game_states = g_hash_table_new (g_str_hash, g_str_equal);
stateman_add_state ("main_menu", state_main_menu_new ());
stateman_add_state ("game", state_game_new ());
global_state = state_global_new ();
global_state->on_enter (global_state);
}
static SCM
_scm_switch_state (SCM state_val)
{
char *state = scm_to_utf8_string (state_val);
stateman_switch_state (state);
return SCM_UNSPECIFIED;
}
void
stateman_guile_register ()
{
scm_c_define_gsubr ("stateman-switch-state", 1, 0, 0, _scm_switch_state);
}
void
stateman_add_state (const char *name, GameState *state)
{
g_hash_table_replace (game_states, g_strdup (name), state);
}
void
stateman_switch_state (const char *name)
{
GameState *next_state = g_hash_table_lookup (game_states, name);
if (current_state && current_state->on_exit)
{
current_state->on_exit (current_state);
}
if (next_state && next_state->on_enter)
{
/* When we enter, we also set the UI root to be the current
window size. After that, if callbacks for a given state are
set up correctly (using
GameState_register_UIContext_handlers), then it will update
the root size automatically.*/
next_state->ui_context->root->size[0] = gvar_get ("window_width");
next_state->ui_context->root->size[1] = gvar_get ("window_height");
next_state->on_enter (next_state);
current_state = next_state;
}
}
void stateman_update ()
{
global_state->on_update (global_state);
if (current_state && current_state->on_update)
{
current_state->on_update (current_state);
}
if (current_state && current_state->ui_context)
{
UIContext_update (current_state->ui_context);
}
}
void
stateman_on_SDL_Event (SDL_Event *event)
{
GameState_handle_SDL_Event (global_state, event);
if (current_state && current_state->event_handlers)
{
GameState_handle_SDL_Event (current_state, event);
}
}
void
stateman_render ()
{
if (current_state && current_state->on_render)
{
current_state->on_render (current_state);
}
if (current_state && current_state->ui_context)
{
UIContext_render (current_state->ui_context);
}
}
-19
View File
@@ -1,19 +0,0 @@
#pragma once
#include <glib-2.0/glib.h>
#include "state_common.h"
#include "state_global.h"
#include "state_main_menu.h"
#include "state_game.h"
void stateman_init ();
void stateman_guile_register ();
static inline void stateman_free () { } /* TODO: implement */
void stateman_add_state (const char *name, GameState *state);
void stateman_switch_state (const char *name);
void stateman_update ();
void stateman_on_SDL_Event (SDL_Event *event);
void stateman_render ();