Optimizations, changes
This commit is contained in:
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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 ();
|
||||
@@ -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 ();
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 ();
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 ();
|
||||
Reference in New Issue
Block a user