feature: file structure refactor #10

Merged
odweta merged 3 commits from feat/file-structure-refactor into dev 2026-10-06 12:12:13 +02:00
18 changed files with 247 additions and 218 deletions
+3
View File
@@ -1,2 +1,5 @@
.clangd
*.sublime-*
build/
src/engine/CMakeFiles
examples/CMakeFiles
+12
View File
@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.20)
project(dangerzone LANGUAGES C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
find_package(PkgConfig REQUIRED)
pkg_check_modules(SDL3 REQUIRED IMPORTED_TARGET sdl3)
add_subdirectory(src/engine)
add_subdirectory(src/examples)
-41
View File
@@ -1,41 +0,0 @@
CC := gcc
LIBS := `pkg-config --libs sdl3`
INC := `pkg-config --cflags sdl3` -I./include
SRC := src/engine/engine.c \
src/engine/engine_init.c \
src/engine/render.c \
src/engine/text.c
OUT := build/main
SNAKE_SRC := src/examples/snake.c $(SRC)
SNAKE := build/snake
2048_SRC := src/examples/2048.c $(SRC)
2048 := build/2048
build:
$(CC) -o $(OUT) -O3 -DNDEBUG src/main.c $(SRC) $(INC) $(LIBS)
run:
$(OUT)
build-snake:
$(CC) -o $(SNAKE) -O3 -DNDEBUG $(SNAKE_SRC) $(INC) $(LIBS)
run-snake:
$(SNAKE)
clean-snake:
rm $(SNAKE)
build-2048:
$(CC) -o $(2048) -O3 -DNDEBUG $(2048_SRC) $(INC) $(LIBS)
run-2048:
$(2048)
clean-2048:
rm $(2048)
clean:
rm $(OUT)
.PHONY: build run
+31
View File
@@ -0,0 +1,31 @@
#pragma once
#include <SDL3/SDL.h>
#include <stdbool.h>
#include <stdint.h>
typedef struct {
SDL_Event event;
bool is_running;
bool framebuffer_dirty;
SDL_Rect dirty_rect;
uint16_t width, height;
uint32_t *framebuffer;
} game_state_t;
extern game_state_t *game_state;
bool
engine_init(
uint32_t window_width,
uint32_t window_height,
const char window_name[],
void (*engine_poll_events)(void),
void (*engine_update_framebuffer)(void)
);
void
engine_start();
void
engine_stop();
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
void
put_pixel(
unsigned int x,
unsigned int y,
uint32_t color
);
void
clear_framebuffer(
uint32_t color
);
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <stdint.h>
void
put_rect(
uint32_t x,
uint32_t y,
uint32_t w,
uint32_t h,
uint32_t color
);
void
clear_rect(int x, int y, int w, int h, uint32_t color);
void
mark_dirty_rect(int x, int y, int w, int h);
+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include <stdint.h>
void
put_char(
char c,
uint32_t x,
uint32_t y,
uint32_t size,
uint32_t fg_color,
uint32_t bg_color
);
void
put_string(
const char *text,
uint32_t x,
uint32_t y,
uint32_t size,
uint32_t spacing,
uint32_t line_spacing,
uint32_t fg_color,
uint32_t bg_color
);
-123
View File
@@ -1,123 +0,0 @@
#pragma once
#include <SDL3/SDL.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define WINDOW_NAME_MAX_LENGTH 128
#define TARGET_FRAME 1.0 / 60.0
#define FONT_ROWS 7
#define FONT_COLS 5
typedef struct {
char window_name[WINDOW_NAME_MAX_LENGTH];
uint16_t width, height;
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
} engine_sdl_state_t;
typedef struct {
/**
* this function runs inside of the SDL_PollEvent loop
* useful for user input, quitting the program and so on
*/
void (*engine_poll_events)(void);
/**
* meant as the "area" for manupulating the framebuffer;
* after this is executed, the contents of
* game_state->framebuffer get drawn
*/
void (*engine_update_framebuffer)(void);
engine_sdl_state_t *sdl_state;
} engine_internal_state_t;
typedef struct {
SDL_Event event;
bool is_running;
bool framebuffer_dirty;
SDL_Rect dirty_rect;
uint16_t width, height;
uint32_t *framebuffer;
} game_state_t;
extern engine_internal_state_t *internal_state;
extern game_state_t *game_state;
engine_sdl_state_t*
engine_sdl_init(
uint32_t window_width,
uint32_t window_height,
const char window_name[]
);
void
engine_sdl_destroy(
engine_sdl_state_t *state
);
bool
engine_init(
uint32_t window_width,
uint32_t window_height,
const char window_name[],
void (*engine_poll_events)(void),
void (*engine_update_framebuffer)(void)
);
void
engine_start();
void
engine_stop();
void
put_pixel(
unsigned int x,
unsigned int y,
uint32_t color
);
void
put_rect(
uint32_t x,
uint32_t y,
uint32_t w,
uint32_t h,
uint32_t color
);
void
clear_framebuffer(
uint32_t color
);
void
clear_rect(int x, int y, int w, int h, uint32_t color);
void
mark_dirty_rect(int x, int y, int w, int h);
void
put_char(
char c,
uint32_t x,
uint32_t y,
uint32_t size,
uint32_t fg_color,
uint32_t bg_color
);
void
put_string(
const char *text,
uint32_t x,
uint32_t y,
uint32_t size,
uint32_t spacing,
uint32_t line_spacing,
uint32_t fg_color,
uint32_t bg_color
);
+19
View File
@@ -0,0 +1,19 @@
file(GLOB_RECURSE ENGINE_SOURCES CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/*.c"
)
add_library(dangerzone_engine STATIC
${ENGINE_SOURCES}
)
target_include_directories(dangerzone_engine
PUBLIC
${PROJECT_SOURCE_DIR}/include
PRIVATE
${PROJECT_SOURCE_DIR}/src
)
target_link_libraries(dangerzone_engine
PUBLIC
PkgConfig::SDL3
)
+3 -1
View File
@@ -1,4 +1,6 @@
#include "engine.h"
#include <dangerzone/engine.h>
#include "internal/engine_internal.h"
engine_internal_state_t *internal_state = NULL;
game_state_t *game_state = NULL;
+4 -5
View File
@@ -1,8 +1,7 @@
#include "engine.h"
#include "error.h"
#include <SDL3/SDL_render.h>
#include <SDL3/SDL_video.h>
#include <stdint.h>
#include <dangerzone/engine.h>
#include "internal/engine_internal.h"
#include "internal/util/error.h"
bool
engine_sdl_init_state(
+48
View File
@@ -0,0 +1,48 @@
#include <dangerzone/engine.h>
#include <dangerzone/render/misc.h>
#include <dangerzone/render/rect.h>
#include "internal/util/error.h"
#include <stdint.h>
// alter a pixel at an imaginary x & y coordinates
void
put_pixel(
unsigned int x,
unsigned int y,
uint32_t color
) {
uint16_t w = game_state->width;
uint16_t h = game_state->height;
if (x < 0 || x >= w || y < 0 || y >= h) {
eprintf(
"CRITICAL: attempted buffer overflow in put_pixel\n"
"at x = %d, y = %d", x, y
);
} else {
game_state->framebuffer[game_state->width * y + x]
= color;
mark_dirty_rect(x, y, 1, 1);
}
}
// fill the entire framebuffer with a given color
void
clear_framebuffer(
uint32_t color
) {
for (size_t i = 0;
i < (size_t)game_state->width * game_state->height;
++i) {
game_state->framebuffer[i] = color;
}
mark_dirty_rect(
0,
0,
game_state->width,
game_state->height
);
}
@@ -1,30 +1,9 @@
#include "engine.h"
#include "error.h"
#include <dangerzone/engine.h>
#include <dangerzone/render/misc.h>
#include <dangerzone/render/rect.h>
#include <stdint.h>
// alter a pixel at an imaginary x & y coordinates
void
put_pixel(
unsigned int x,
unsigned int y,
uint32_t color
) {
uint16_t w = game_state->width;
uint16_t h = game_state->height;
if (x < 0 || x >= w || y < 0 || y >= h) {
eprintf(
"CRITICAL: attempted buffer overflow in put_pixel\n"
"at x = %d, y = %d", x, y
);
} else {
game_state->framebuffer[game_state->width * y + x]
= color;
mark_dirty_rect(x, y, 1, 1);
}
}
/**
* draws a rectangle with its left-top corner at (x,y) with
* a width of 'w' and height of 'h' filled with color 'color'
@@ -45,25 +24,6 @@ put_rect(
mark_dirty_rect(x, y, w, h);
}
// fill the entire framebuffer with a given color
void
clear_framebuffer(
uint32_t color
) {
for (size_t i = 0;
i < (size_t)game_state->width * game_state->height;
++i) {
game_state->framebuffer[i] = color;
}
mark_dirty_rect(
0,
0,
game_state->width,
game_state->height
);
}
void
clear_rect(int x, int y, int w, int h, uint32_t color)
{
@@ -1,7 +1,10 @@
// rendering characters in the framebuffer
#include "engine.h"
#include <stdint.h>
#include <dangerzone/engine.h>
#include <dangerzone/render/rect.h>
#include <dangerzone/render/text.h>
#include "internal/engine_internal.h"
/*
* each character has 8 rows
+8
View File
@@ -0,0 +1,8 @@
#add_executable(snake snake.c)
#target_link_libraries(snake PRIVATE dangerzone_engine)
#add_executable(game_2048 2048.c)
#target_link_libraries(game_2048 PRIVATE dangerzone_engine)
add_executable(game_window window.c)
target_link_libraries(game_window PRIVATE dangerzone_engine)
+3 -1
View File
@@ -1,4 +1,6 @@
#include "engine.h"
#include <dangerzone/engine.h>
#include <dangerzone/render/misc.h>
#include <dangerzone/render/text.h>
// polling events every frame
void
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include <SDL3/SDL.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define WINDOW_NAME_MAX_LENGTH 128
#define FONT_ROWS 7
#define FONT_COLS 5
typedef struct {
char window_name[WINDOW_NAME_MAX_LENGTH];
uint16_t width, height;
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Texture *texture;
} engine_sdl_state_t;
typedef struct {
/**
* this function runs inside of the SDL_PollEvent loop
* useful for user input, quitting the program and so on
*/
void (*engine_poll_events)(void);
/**
* meant as the "area" for manupulating the framebuffer;
* after this is executed, the contents of
* game_state->framebuffer get drawn
*/
void (*engine_update_framebuffer)(void);
engine_sdl_state_t *sdl_state;
} engine_internal_state_t;
extern engine_internal_state_t *internal_state;
engine_sdl_state_t*
engine_sdl_init(
uint32_t window_width,
uint32_t window_height,
const char window_name[]
);
void
engine_sdl_destroy(
engine_sdl_state_t *state
);