Codebase cleanup

This commit is contained in:
2025-06-03 10:44:48 +02:00
parent 23a5ba5abe
commit b7072568b4
15 changed files with 331 additions and 200 deletions
+3 -2
View File
@@ -1,5 +1,6 @@
SRC=src/main.c src/program.c src/resources.c src/camera.c \
src/chunk/chunk.c src/chunk/mesh.c src/flags.c src/texture.c src/chunk/manager.c
SRC=src/main.c src/program.c src/resources.c src/camera.c src/chunk/chunk.c \
src/chunk/mesh.c src/flags.c src/texture.c src/chunk/manager.c \
src/event/manager.c src/event/handlers.c src/state.c src/graphics.c
OBJ=$(SRC:.c=.o)
CFLAGS=-Werror -Wextra -Wall `pkg-config --cflags sdl3 sdl3-image cglm gl glib-2.0`
+1 -1
View File
@@ -6,7 +6,7 @@
#include "../util.h"
#define CHUNK_DIM 16
#define CHUNK_DIM 32
#define CHUNK_SIZE (CHUNK_DIM*CHUNK_DIM)
#define INDEX(x, z) (CHUNK_DIM * (z) + (x))
+2 -2
View File
@@ -1,7 +1,7 @@
#include "manager.h"
/* TODO: switch from string keys to struct keys or some other
stuff. */
/* TODO: perhaps render the chunks in a circle, not a square, around
the player? */
ChunkManager chunk_manager;
+1 -1
View File
@@ -7,7 +7,7 @@
#include "chunk.h"
#include "mesh.h"
#define RENDER_DISTANCE 3
#define RENDER_DISTANCE 8
typedef struct ChunkManager
{
+76
View File
@@ -0,0 +1,76 @@
#include "handlers.h"
extern GameState game_state;
extern GameFlags game_flags;
void
handlers_init ()
{
EventManager_add_SDL_handler (handler_lookaround);
EventManager_add_SDL_handler (handler_movement);
}
void
handler_lookaround (SDL_Event *event)
{
if (event->type == SDL_EVENT_MOUSE_MOTION && game_flags.can_free_look)
{
game_state.camera.rotation[0] -= event->motion.xrel / 100.f;
game_state.camera.rotation[1] -= event->motion.yrel / 100.f;
game_state.camera.rotation[1] =
CLAMP (game_state.camera.rotation[1], -M_PI / 2 + 0.025, M_PI / 2 - 0.025);
}
}
void
handler_movement (SDL_Event *event)
{
if (event->type == SDL_EVENT_KEY_DOWN)
{
switch (event->key.key)
{
case SDLK_W:
game_flags.moving_forward = 1;
break;
case SDLK_A:
game_flags.moving_left = 1;
break;
case SDLK_S:
game_flags.moving_backward = 1;
break;
case SDLK_D:
game_flags.moving_right = 1;
break;
case SDLK_F1:
game_flags.wireframe_enabled = !game_flags.wireframe_enabled;
break;
case SDLK_F2:
int active_program;
glGetIntegerv (GL_CURRENT_PROGRAM, &active_program);
program_print (active_program);
break;
case SDLK_F3:
Camera_print (&game_state.camera);
break;
}
}
if (event->type == SDL_EVENT_KEY_UP)
{
switch (event->key.key)
{
case SDLK_W:
game_flags.moving_forward = 0;
break;
case SDLK_A:
game_flags.moving_left = 0;
break;
case SDLK_S:
game_flags.moving_backward = 0;
break;
case SDLK_D:
game_flags.moving_right = 0;
break;
}
}
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include <SDL3/SDL.h>
#include <SDL3/SDL_opengles2.h>
#include "manager.h"
#include "../camera.h"
#include "../flags.h"
#include "../program.h"
#include "../state.h"
void handlers_init ();
void handler_lookaround (SDL_Event *event);
void handler_movement (SDL_Event *event);
+24
View File
@@ -0,0 +1,24 @@
#include "manager.h"
EventManager event_manager;
void
EventManager_add_SDL_handler (SDLHandler h)
{
event_manager.sdl_handlers = g_slist_append (event_manager.sdl_handlers, h);
}
void
em_handle_sdl_internal (gpointer data, gpointer userdata)
{
SDLHandler handler = data;
SDL_Event *event = userdata;
handler (event);
}
void
EventManager_handle_SDL_Event (SDL_Event *event)
{
g_slist_foreach (event_manager.sdl_handlers, em_handle_sdl_internal, event);
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <stdbool.h>
#include <SDL3/SDL.h>
#include <glib-2.0/glib.h>
#include "../util.h"
typedef struct EventManager
{
GSList *sdl_handlers;
} EventManager;
typedef void (*SDLHandler) (SDL_Event *event);
void EventManager_add_SDL_handler (SDLHandler handler);
void EventManager_handle_SDL_Event (SDL_Event *event);
+84
View File
@@ -0,0 +1,84 @@
#include "graphics.h"
GraphicsContext gfx;
extern ChunkManager chunk_manager;
extern GameState game_state;
extern Resources resources;
void
GraphicsContext_init ()
{
if (!SDL_Init (SDL_INIT_VIDEO))
{
FATAL ("Couldn't initialize SDL: %s", SDL_GetError ());
}
gfx.window = SDL_CreateWindow (GAME_NAME, 640, 480, SDL_WINDOW_OPENGL);
if (!gfx.window)
{
FATAL ("Couldn't create window: %s", SDL_GetError ());
}
/* We use OpenGL ES 2.0. It should support everything, and it's more
than enough for the game. */
SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
gfx.gl_context = SDL_GL_CreateContext (gfx.window);
if (!gfx.gl_context)
{
FATAL ("Couldn't create OpenGL context: %s", SDL_GetError ());
}
SDL_GL_MakeCurrent (gfx.window, gfx.gl_context);
SDL_SetWindowRelativeMouseMode (gfx.window, true);
INFO ("Renderer: %s", glGetString (GL_RENDERER));
INFO ("OpenGL version: %s", glGetString (GL_VERSION));
INFO ("GLSL version: %s", glGetString (GL_SHADING_LANGUAGE_VERSION));
INFO ("Max vertex attributes: %d", GL_MAX_VERTEX_ATTRIBS);
glViewport(0, 0, 640, 480);
glClearColor (0, 0.3, 0.8, 1);
glEnable (GL_CULL_FACE);
glEnable (GL_DEPTH_TEST);
}
void
GraphicsContext_render ()
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
program_use (resources.programs[1]);
mat4 projection, view;
Camera_get_projection (&game_state.camera, 640.0 / 480.0, projection);
Camera_get_view (&game_state.camera, view);
program_set_mat4 (resources.programs[1], "projection", projection);
program_set_mat4 (resources.programs[1], "view", view);
for (size_t i = 0; i < resources.textures_len; ++i)
{
glActiveTexture (GL_TEXTURE0 + i);
glBindTexture (GL_TEXTURE_2D, resources.textures[i]);
}
ChunkManager_render (game_state.camera.position[0], game_state.camera.position[2], resources.programs[1]);
glBindTexture (GL_TEXTURE_2D, 0);
SDL_GL_SwapWindow (gfx.window);
}
void
GraphicsContext_free ()
{
SDL_GL_DestroyContext (gfx.gl_context);
SDL_DestroyWindow (gfx.window);
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include <SDL3/SDL.h>
#include <SDL3/SDL_opengles2.h>
#include "util.h"
#include "chunk/manager.h"
#include "state.h"
#include "resources.h"
typedef struct GraphicsContext
{
SDL_Window *window;
SDL_GLContext gl_context;
} GraphicsContext;
void GraphicsContext_init ();
void GraphicsContext_render ();
void GraphicsContext_free ();
+18 -193
View File
@@ -1,236 +1,62 @@
#define SDL_MAIN_USE_CALLBACKS 1
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <stdio.h>
#include "event/manager.h"
#include "event/handlers.h"
#include "chunk/manager.h"
#include "state.h"
#include "flags.h"
#include "camera.h"
#include "resources.h"
/* TODO: switch back to cglm.h, since it's faster or something */
static SDL_Window *window = NULL;
static SDL_GLContext context = NULL;
#include "graphics.h"
extern GameState game_state;
extern GameFlags game_flags;
extern EventManager event_manager;
extern GraphicsContext gfx;
extern Resources resources;
extern ChunkManager chunk_manager;
static Camera camera;
SDL_AppResult
SDL_AppInit (void **appstate, int argc, char **argv)
{
(void) appstate; (void) argc; (void) argv;
UNUSED (appstate, argc, argv);
SDL_SetAppMetadata (GAME_NAME, GAME_VERSION, "eur.chopininteractive.wschod-game");
if (!SDL_Init (SDL_INIT_VIDEO))
{
FATAL ("Couldn't initialize SDL: %s", SDL_GetError ());
}
window = SDL_CreateWindow (GAME_NAME, 640, 480, SDL_WINDOW_OPENGL);
if (!window)
{
FATAL ("Couldn't create window: %s", SDL_GetError ());
}
/* We use OpenGL ES 2.0. It should support everything, and it's more
than enough for the game. */
SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
context = SDL_GL_CreateContext (window);
if (!context)
{
FATAL ("Couldn't create OpenGL context: %s", SDL_GetError ());
}
SDL_GL_MakeCurrent (window, context);
SDL_SetWindowRelativeMouseMode (window, true);
INFO ("Renderer: %s", glGetString (GL_RENDERER));
INFO ("OpenGL version: %s", glGetString (GL_VERSION));
INFO ("GLSL version: %s", glGetString (GL_SHADING_LANGUAGE_VERSION));
INFO ("Max vertex attributes: %d", GL_MAX_VERTEX_ATTRIBS);
glViewport(0, 0, 640, 480);
glClearColor (0, 0.3, 0.8, 1);
glEnable (GL_CULL_FACE);
glEnable (GL_DEPTH_TEST);
/* Initialize and load resources. */
GraphicsContext_init ();
handlers_init ();
Resources_init ();
ChunkManager_init ();
program_use (resources.programs[1]);
int arr[5] = { 0, 1, 2, 3, 4 };
program_set_int_array (resources.programs[1], "materials", 5, arr);
/* Set up game state. */
game_state.last_time = SDL_GetTicks ();
GameState_init (SDL_GetTicks ());
/* Set some basic game flags for testing. */
game_flags.can_free_look = 1;
game_flags.wireframe_enabled = 0;
/* Initialize the default camera. */
camera = Camera_default ();
return SDL_APP_CONTINUE;
}
SDL_AppResult
SDL_AppEvent (void *appstate, SDL_Event *event)
{
(void) appstate;
UNUSED (appstate);
if (event->type == SDL_EVENT_QUIT)
{
return SDL_APP_SUCCESS;
}
if (event->type == SDL_EVENT_MOUSE_MOTION && game_flags.can_free_look)
{
camera.rotation[0] -= event->motion.xrel / 100.f;
camera.rotation[1] -= event->motion.yrel / 100.f;
camera.rotation[1] =
CLAMP (camera.rotation[1], -M_PI / 2 + 0.025, M_PI / 2 - 0.025);
}
if (event->type == SDL_EVENT_KEY_DOWN)
{
switch (event->key.key)
{
case SDLK_W:
game_flags.moving_forward = 1;
break;
case SDLK_A:
game_flags.moving_left = 1;
break;
case SDLK_S:
game_flags.moving_backward = 1;
break;
case SDLK_D:
game_flags.moving_right = 1;
break;
case SDLK_F1:
game_flags.wireframe_enabled = !game_flags.wireframe_enabled;
break;
case SDLK_F2:
int active_program;
glGetIntegerv (GL_CURRENT_PROGRAM, &active_program);
program_print (active_program);
break;
case SDLK_F3:
Camera_print (&camera);
break;
}
}
if (event->type == SDL_EVENT_KEY_UP)
{
switch (event->key.key)
{
case SDLK_W:
game_flags.moving_forward = 0;
break;
case SDLK_A:
game_flags.moving_left = 0;
break;
case SDLK_S:
game_flags.moving_backward = 0;
break;
case SDLK_D:
game_flags.moving_right = 0;
break;
}
}
EventManager_handle_SDL_Event (event);
return SDL_APP_CONTINUE;
}
SDL_AppResult
SDL_AppIterate (void *appstate)
{
(void) appstate;
UNUSED (appstate);
/* Caluclate stuff per frame. */
int now = SDL_GetTicks ();
game_state.delta_time = (now - game_state.last_time) / 1000.0;
game_state.last_time = now;
if (game_flags.moving_forward)
{
vec3 dir, change, new_pos;
Camera_get_direction (&camera, dir);
glm_vec3_scale (dir, game_state.delta_time * 5, change);
glm_vec3_add (camera.position, change, new_pos);
glm_vec3_copy (new_pos, camera.position);
}
if (game_flags.moving_backward)
{
vec3 dir, change, new_pos;
Camera_get_direction (&camera, dir);
glm_vec3_scale (dir, game_state.delta_time * 5, change);
glm_vec3_sub (camera.position, change, new_pos);
glm_vec3_copy (new_pos, camera.position);
}
if (game_flags.moving_right)
{
vec3 right, change, new_pos;
Camera_get_right (&camera, right);
glm_vec3_scale (right, game_state.delta_time * 5, change);
glm_vec3_add (camera.position, change, new_pos);
glm_vec3_copy (new_pos, camera.position);
}
if (game_flags.moving_left)
{
vec3 right, change, new_pos;
Camera_get_right (&camera, right);
glm_vec3_scale (right, game_state.delta_time * 5, change);
glm_vec3_sub (camera.position, change, new_pos);
glm_vec3_copy (new_pos, camera.position);
}
ChunkManager_update (camera.position[0], camera.position[2]);
/* Render stuff. */
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
program_use (resources.programs[1]);
mat4 projection, view;
Camera_get_projection (&camera, 640.0 / 480.0, projection);
Camera_get_view (&camera, view);
program_set_mat4 (resources.programs[1], "projection", projection);
program_set_mat4 (resources.programs[1], "view", view);
for (size_t i = 0; i < resources.textures_len; ++i)
{
glActiveTexture (GL_TEXTURE0 + i);
glBindTexture (GL_TEXTURE_2D, resources.textures[i]);
}
ChunkManager_render (camera.position[0], camera.position[2], resources.programs[1]);
glBindTexture (GL_TEXTURE_2D, 0);
SDL_GL_SwapWindow (window);
ChunkManager_update (game_state.camera.position[0], game_state.camera.position[2]);
GameState_tick (SDL_GetTicks ());
GraphicsContext_render ();
return SDL_APP_CONTINUE;
}
@@ -238,8 +64,7 @@ SDL_AppIterate (void *appstate)
void
SDL_AppQuit (void *appstate, SDL_AppResult result)
{
(void) appstate; (void) result;
UNUSED (appstate, result);
Resources_free ();
SDL_GL_DestroyContext (context);
SDL_DestroyWindow (window);
GraphicsContext_free ();
}
+3
View File
@@ -75,6 +75,9 @@ Resources_init ()
Resources_load_program ("res/shaders/default.vert", "res/shaders/default.frag");
Resources_load_program ("res/shaders/chunk.vert", "res/shaders/chunk.frag");
program_use (resources.programs[1]);
program_set_int_array (resources.programs[1], "materials", 5, (int[5]) { 0, 1, 2, 3, 4 });
resources.textures_len = 0;
resources.textures = malloc (sizeof (unsigned int));
Resources_load_texture ("res/textures/dirt.png");
+56
View File
@@ -0,0 +1,56 @@
#include "state.h"
GameState game_state;
extern GameFlags game_flags;
void
GameState_init (int ticks)
{
game_state.last_time = ticks;
game_state.camera = Camera_default ();
}
void
GameState_tick (int ticks)
{
/* Caluclate stuff per frame. */
game_state.delta_time = (ticks - game_state.last_time) / 1000.0;
game_state.last_time = ticks;
if (game_flags.moving_forward)
{
vec3 dir, change, new_pos;
Camera_get_direction (&game_state.camera, dir);
glm_vec3_scale (dir, game_state.delta_time * 5, change);
glm_vec3_add (game_state.camera.position, change, new_pos);
glm_vec3_copy (new_pos, game_state.camera.position);
}
if (game_flags.moving_backward)
{
vec3 dir, change, new_pos;
Camera_get_direction (&game_state.camera, dir);
glm_vec3_scale (dir, game_state.delta_time * 5, change);
glm_vec3_sub (game_state.camera.position, change, new_pos);
glm_vec3_copy (new_pos, game_state.camera.position);
}
if (game_flags.moving_right)
{
vec3 right, change, new_pos;
Camera_get_right (&game_state.camera, right);
glm_vec3_scale (right, game_state.delta_time * 5, change);
glm_vec3_add (game_state.camera.position, change, new_pos);
glm_vec3_copy (new_pos, game_state.camera.position);
}
if (game_flags.moving_left)
{
vec3 right, change, new_pos;
Camera_get_right (&game_state.camera, right);
glm_vec3_scale (right, game_state.delta_time * 5, change);
glm_vec3_sub (game_state.camera.position, change, new_pos);
glm_vec3_copy (new_pos, game_state.camera.position);
}
}
+7 -1
View File
@@ -1,9 +1,15 @@
#pragma once
#include "camera.h"
#include "flags.h"
typedef struct GameState
{
int last_time;
float delta_time;
Camera camera;
} GameState;
GameState game_state;
void GameState_init ();
void GameState_tick ();
+5
View File
@@ -16,3 +16,8 @@
#define FATAL(fmt, args...) (fprintf (stderr, COLOR_RED "[!] %s:%d:%s(): " COLOR_RESET fmt "\n", __FILE__, __LINE__, __func__, ##args), exit (-1))
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
#define UNUSED(...) (UNUSED_1 (__VA_ARGS__, 0))
#define UNUSED_1(arg, ...) (void) arg, UNUSED_2 (__VA_ARGS__, 0)
#define UNUSED_2(arg, ...) (void) arg, UNUSED_3 (__VA_ARGS__, 0)
#define UNUSED_3(arg, ...) (void) arg