From 73bf92e706e1ebb774e99fa06ee92632e6caa2b9 Mon Sep 17 00:00:00 2001 From: wanp Date: Mon, 23 Sep 2024 14:43:16 -0300 Subject: [PATCH] typedef & PascalCase for ALL structs and enums --- apps/testgame/game.c | 8 +- apps/testgame/player.c | 58 ++++---- apps/testgame/player.h | 26 ++-- apps/testgame/scenes/ingame.c | 74 +++++----- apps/testgame/scenes/ingame.h | 14 +- apps/testgame/scenes/scene.c | 2 +- apps/testgame/scenes/scene.h | 12 +- apps/testgame/scenes/title.c | 24 ++-- apps/testgame/scenes/title.h | 12 +- apps/testgame/state.h | 13 +- apps/testgame/world.c | 48 +++---- apps/testgame/world.h | 38 +++--- data/assets/9slice.png | 3 + include/twn_audio.h | 12 +- include/twn_camera.h | 14 +- include/twn_context.h | 8 +- include/twn_input.h | 72 +++++----- include/twn_rendering.h | 58 ++++---- include/twn_texture_modes.h | 4 +- include/twn_util.h | 36 ++--- include/twn_vec.h | 102 +++++++------- src/rendering/twn_circles.c | 10 +- src/rendering/twn_gl_15_gpu_texture.c | 8 +- src/rendering/twn_gl_15_rendering.c | 158 +++++++++++----------- src/rendering/twn_gl_any_rendering.c | 6 +- src/rendering/twn_gpu_texture_c.h | 14 +- src/rendering/twn_rendering.c | 16 +-- src/rendering/twn_rendering_c.h | 187 +++++++++++++------------- src/rendering/twn_sprites.c | 94 ++++++------- src/rendering/twn_text.c | 54 +++----- src/rendering/twn_text_c.h | 16 ++- src/rendering/twn_triangles.c | 44 +++--- src/twn_audio.c | 54 ++++---- src/twn_audio_c.h | 22 +-- src/twn_camera.c | 12 +- src/twn_context.c | 2 +- src/twn_engine_context_c.h | 19 +-- src/twn_input.c | 82 +++++------ src/twn_input_c.h | 2 +- src/twn_loop.c | 2 +- src/twn_textures.c | 76 +++++------ src/twn_textures_c.h | 52 +++---- src/twn_util.c | 20 +-- 43 files changed, 795 insertions(+), 793 deletions(-) create mode 100644 data/assets/9slice.png diff --git a/apps/testgame/game.c b/apps/testgame/game.c index 70320e8..b56507e 100644 --- a/apps/testgame/game.c +++ b/apps/testgame/game.c @@ -13,9 +13,9 @@ void game_tick(void) { if (ctx.initialization_needed) { if (!ctx.udata) { - ctx.udata = ccalloc(1, sizeof (struct state)); + ctx.udata = ccalloc(1, sizeof (State)); - struct state *state = ctx.udata; + State *state = ctx.udata; state->ctx = &ctx; state->scene = title_scene(state); } @@ -48,7 +48,7 @@ void game_tick(void) { input_bind_action_scancode(&ctx.input, "mouse_capture_toggle", SDL_SCANCODE_ESCAPE); } - struct state *state = ctx.udata; + State *state = ctx.udata; if (input_is_action_just_pressed(&ctx.input, "debug_toggle")) { ctx.debug = !ctx.debug; @@ -67,7 +67,7 @@ void game_tick(void) { void game_end(void) { - struct state *state = ctx.udata; + State *state = ctx.udata; state->scene->end(state); free(state); } diff --git a/apps/testgame/player.c b/apps/testgame/player.c index e5e9e8b..ee135b9 100644 --- a/apps/testgame/player.c +++ b/apps/testgame/player.c @@ -10,14 +10,14 @@ #include -static void update_timers(struct player *player) { +static void update_timers(Player *player) { tick_timer(&player->jump_air_timer); tick_timer(&player->jump_coyote_timer); tick_timer(&player->jump_buffer_timer); } -static void input_move(struct input_state *input, struct player *player) { +static void input_move(InputState *input, Player *player) { /* apply horizontal damping when the player stops moving */ /* in other words, make it decelerate to a standstill */ if (!input_is_action_pressed(input, "player_left") && @@ -44,7 +44,7 @@ static void input_move(struct input_state *input, struct player *player) { } -static void jump(struct player *player) { +static void jump(Player *player) { player->jump_coyote_timer = 0; player->jump_buffer_timer = 0; player->dy = player->jump_force_initial; @@ -53,7 +53,7 @@ static void jump(struct player *player) { } -static void input_jump(struct input_state *input, struct player *player) { +static void input_jump(InputState *input, Player *player) { player->current_gravity_multiplier = player->jump_default_multiplier; if (input_is_action_just_pressed(input, "player_jump")) { @@ -74,7 +74,7 @@ static void input_jump(struct input_state *input, struct player *player) { } -static void update_collider_x(struct player *player) { +static void update_collider_x(Player *player) { player->collider_x.w = player->rect.w; player->collider_x.h = player->rect.h - 8; player->collider_x.x = player->rect.x; @@ -82,7 +82,7 @@ static void update_collider_x(struct player *player) { } -static void update_collider_y(struct player *player) { +static void update_collider_y(Player *player) { player->collider_y.w = player->rect.w; player->collider_y.h = player->rect.h; player->collider_y.x = player->rect.x + ((player->rect.w - player->collider_y.w) / 2); @@ -90,7 +90,7 @@ static void update_collider_y(struct player *player) { } -static void apply_gravity(struct player *player, float gravity) { +static void apply_gravity(Player *player, float gravity) { player->dy -= gravity * player->current_gravity_multiplier; player->dy = fmax(player->dy, -player->terminal_velocity); @@ -106,7 +106,7 @@ static void apply_gravity(struct player *player, float gravity) { /* returns whether or not a correction was applied */ -static bool corner_correct(struct player *player, t_frect collision) { +static bool corner_correct(Player *player, Rect collision) { /* * somewhat of a hack here. we only want to do corner correction * if the corner in question really is the corner of a "platform," @@ -145,16 +145,16 @@ static bool corner_correct(struct player *player, t_frect collision) { } -static void calc_collisions_x(struct player *player) { - t_frect collision; +static void calc_collisions_x(Player *player) { + Rect collision; bool is_colliding = world_find_intersect_frect(player->world, player->collider_x, &collision); if (!is_colliding) return; float player_center_x = player->collider_x.x + (player->collider_x.w / 2); float collision_center_x = collision.x + (collision.w / 2); - enum collision_direction { COLLISION_LEFT = -1, COLLISION_RIGHT = 1 }; - enum collision_direction dir_x = + typedef enum CollisionDirection { COLLISION_LEFT = -1, COLLISION_RIGHT = 1 } CollisionDirection; + CollisionDirection dir_x = player_center_x > collision_center_x ? COLLISION_LEFT : COLLISION_RIGHT; player->rect.x -= collision.w * (float)dir_x; @@ -162,16 +162,16 @@ static void calc_collisions_x(struct player *player) { } -static void calc_collisions_y(struct player *player) { - t_frect collision; +static void calc_collisions_y(Player *player) { + Rect collision; bool is_colliding = world_find_intersect_frect(player->world, player->collider_y, &collision); if (!is_colliding) return; float player_center_y = player->collider_y.y + (player->collider_y.h / 2); float collision_center_y = collision.y + (collision.h / 2); - enum collision_direction { COLLISION_ABOVE = -1, COLLISION_BELOW = 1 }; - enum collision_direction dir_y = + typedef enum CollisionDirection { COLLISION_ABOVE = -1, COLLISION_BELOW = 1 } CollisionDirection; + CollisionDirection dir_y = player_center_y > collision_center_y ? COLLISION_ABOVE : COLLISION_BELOW; /* before the resolution */ @@ -202,16 +202,16 @@ static void calc_collisions_y(struct player *player) { } -struct player *player_create(struct world *world) { - struct player *player = cmalloc(sizeof *player); +Player *player_create(World *world) { + Player *player = cmalloc(sizeof *player); - *player = (struct player) { + *player = (Player) { .world = world, .sprite_w = 48, .sprite_h = 48, - .rect = (t_frect) { + .rect = (Rect) { .x = 92, .y = 200, .w = 16, @@ -243,22 +243,22 @@ struct player *player_create(struct world *world) { } -static void drawdef(struct player *player) { +static void drawdef(Player *player) { m_sprite("/assets/player/baron-walk.png", - (t_frect) { + (Rect) { .x = player->rect.x + ((player->rect.w - player->sprite_w) / 2), .y = player->rect.y - 8, .w = player->sprite_w, .h = player->sprite_h, }); - push_circle((t_fvec2) { 256, 128 }, + push_circle((Vec2) { 256, 128 }, 24, - (t_color) { 255, 0, 0, 255 }); + (Color) { 255, 0, 0, 255 }); } -static void drawdef_debug(struct player *player) { +static void drawdef_debug(Player *player) { if (!ctx.debug) return; @@ -269,19 +269,19 @@ static void drawdef_debug(struct player *player) { /* }; */ push_rectangle(player->collider_x, - (t_color){ 0, 0, 255, 128 }); + (Color){ 0, 0, 255, 128 }); push_rectangle(player->collider_y, - (t_color){ 0, 0, 255, 128 }); + (Color){ 0, 0, 255, 128 }); } -void player_destroy(struct player *player) { +void player_destroy(Player *player) { free(player); } -void player_calc(struct player *player) { +void player_calc(Player *player) { update_timers(player); input_move(&ctx.input, player); diff --git a/apps/testgame/player.h b/apps/testgame/player.h index 16c53ba..3d32a39 100644 --- a/apps/testgame/player.h +++ b/apps/testgame/player.h @@ -4,32 +4,32 @@ #include "twn_game_api.h" -struct world; +typedef struct World World; -enum player_action { +typedef enum PlayerAction { PLAYER_ACTION_GROUND, PLAYER_ACTION_FALL, PLAYER_ACTION_JUMP, -}; +} PlayerAction; -struct player { - struct world *world; +typedef struct Player { + World *world; /* visual */ float sprite_w; float sprite_h; /* body */ - t_frect rect; + Rect rect; /* state */ - enum player_action action; + PlayerAction action; /* physics */ - t_frect collider_x; - t_frect collider_y; + Rect collider_x; + Rect collider_y; int collider_thickness; float dx; float dy; @@ -54,12 +54,12 @@ struct player { float jump_boosted_multiplier; float jump_corner_correction_offset; /* from center */ -}; +} Player; -struct player *player_create(struct world *world); -void player_destroy(struct player *player); -void player_calc(struct player *player); +Player *player_create(World *world); +void player_destroy(Player *player); +void player_calc(Player *player); #endif diff --git a/apps/testgame/scenes/ingame.c b/apps/testgame/scenes/ingame.c index 89fafeb..3869cf3 100644 --- a/apps/testgame/scenes/ingame.c +++ b/apps/testgame/scenes/ingame.c @@ -8,8 +8,8 @@ #include -static void ingame_tick(struct state *state) { - struct scene_ingame *scn = (struct scene_ingame *)state->scene; +static void ingame_tick(State *state) { + SceneIngame *scn = (SceneIngame *)state->scene; world_drawdef(scn->world); player_calc(scn->player); @@ -23,26 +23,26 @@ static void ingame_tick(struct state *state) { const float yaw_rad = scn->yaw * (float)DEG2RAD; const float pitch_rad = scn->pitch * (float)DEG2RAD; - scn->cam.target = m_vec_norm(((t_fvec3){ + scn->cam.target = m_vec_norm(((Vec3){ cosf(yaw_rad) * cosf(pitch_rad), sinf(pitch_rad), sinf(yaw_rad) * cosf(pitch_rad) })); } - const t_fvec3 right = m_vec_norm(m_vec_cross(scn->cam.target, scn->cam.up)); + const Vec3 right = m_vec_norm(m_vec_cross(scn->cam.target, scn->cam.up)); const float speed = 0.04f; /* TODO: put this in a better place */ if (input_is_action_pressed(&ctx.input, "player_left")) - scn->cam.pos = fvec3_sub(scn->cam.pos, m_vec_scale(right, speed)); + scn->cam.pos = vec3_sub(scn->cam.pos, m_vec_scale(right, speed)); if (input_is_action_pressed(&ctx.input, "player_right")) - scn->cam.pos = fvec3_add(scn->cam.pos, m_vec_scale(right, speed)); + scn->cam.pos = vec3_add(scn->cam.pos, m_vec_scale(right, speed)); if (input_is_action_pressed(&ctx.input, "player_forward")) - scn->cam.pos = fvec3_add(scn->cam.pos, m_vec_scale(scn->cam.target, speed)); + scn->cam.pos = vec3_add(scn->cam.pos, m_vec_scale(scn->cam.target, speed)); if (input_is_action_pressed(&ctx.input, "player_backward")) - scn->cam.pos = fvec3_sub(scn->cam.pos, m_vec_scale(scn->cam.target, speed)); + scn->cam.pos = vec3_sub(scn->cam.pos, m_vec_scale(scn->cam.target, speed)); if (input_is_action_pressed(&ctx.input, "player_jump")) scn->cam.pos.y += speed; @@ -56,27 +56,27 @@ static void ingame_tick(struct state *state) { } m_sprite(m_set(path, "/assets/9slice.png"), - m_set(rect, ((t_frect){ 16, 16, 128, 128 })), - m_opt(texture_region, ((t_frect){ 0, 0, (float)(ctx.tick_count % 48), (float)(ctx.tick_count % 48) }))); + m_set(rect, ((Rect){ 16, 16, 128, 128 })), + m_opt(texture_region, ((Rect){ 0, 0, (float)(ctx.tick_count % 48), (float)(ctx.tick_count % 48) }))); m_sprite(m_set(path, "/assets/light.png"), - m_set(rect, ((t_frect){ 48, 64, 64, 64 })), - m_opt(color, ((t_color){ 255, 0, 0, 255 }))); + m_set(rect, ((Rect){ 48, 64, 64, 64 })), + m_opt(color, ((Color){ 255, 0, 0, 255 }))); m_sprite(m_set(path, "/assets/light.png"), - m_set(rect, ((t_frect){ 64, 64, 64, 64 })), - m_opt(color, ((t_color){ 0, 255, 0, 255 }))); + m_set(rect, ((Rect){ 64, 64, 64, 64 })), + m_opt(color, ((Color){ 0, 255, 0, 255 }))); m_sprite(m_set(path, "/assets/light.png"), - m_set(rect, ((t_frect){ 80, 64, 64, 64 })), - m_opt(color, ((t_color){ 0, 0, 255, 255 }))); + m_set(rect, ((Rect){ 80, 64, 64, 64 })), + m_opt(color, ((Color){ 0, 0, 255, 255 }))); m_sprite(m_set(path, "/assets/player/baron-walk.png"), - m_set(rect, ((t_frect){ 32, 32, 64, 64 })), + m_set(rect, ((Rect){ 32, 32, 64, 64 })), m_opt(rotation, (float)M_PI * 2 * (float)(ctx.tick_count % 64) / 64 )); m_sprite(m_set(path, "/assets/player/baron-walk.png"), - m_set(rect, ((t_frect){ 128, 32, 128, 64 })), + m_set(rect, ((Rect){ 128, 32, 128, 64 })), m_opt(rotation, (float)M_PI * 2 * (float)(ctx.tick_count % 64) / 64 )); set_camera(&scn->cam); @@ -91,51 +91,51 @@ static void ingame_tick(struct state *state) { float d3 = stb_perlin_noise3((float)x * TERRAIN_FREQUENCY, (float)(y - 1) * TERRAIN_FREQUENCY, 0, 0, 0, 0) * 20 - 6; unfurl_triangle("/assets/grass.gif", - (t_fvec3){ (float)x, d0, (float)y }, - (t_fvec3){ (float)x + 1, d1, (float)y }, - (t_fvec3){ (float)x, d3, (float)y - 1 }, - (t_shvec2){ 1024, 768 }, - (t_shvec2){ 1024, 0 }, - (t_shvec2){ 0, 768 }); + (Vec3){ (float)x, d0, (float)y }, + (Vec3){ (float)x + 1, d1, (float)y }, + (Vec3){ (float)x, d3, (float)y - 1 }, + (Vec2sh){ 1024, 768 }, + (Vec2sh){ 1024, 0 }, + (Vec2sh){ 0, 768 }); unfurl_triangle("/assets/grass.gif", - (t_fvec3){ (float)x + 1, d1, (float)y }, - (t_fvec3){ (float)x + 1, d2, (float)y - 1 }, - (t_fvec3){ (float)x, d3, (float)y - 1 }, - (t_shvec2){ 1024, 0 }, - (t_shvec2){ 0, 0 }, - (t_shvec2){ 0, 768 }); + (Vec3){ (float)x + 1, d1, (float)y }, + (Vec3){ (float)x + 1, d2, (float)y - 1 }, + (Vec3){ (float)x, d3, (float)y - 1 }, + (Vec2sh){ 1024, 0 }, + (Vec2sh){ 0, 0 }, + (Vec2sh){ 0, 768 }); } } } -static void ingame_end(struct state *state) { - struct scene_ingame *scn = (struct scene_ingame *)state->scene; +static void ingame_end(State *state) { + SceneIngame *scn = (SceneIngame *)state->scene; player_destroy(scn->player); world_destroy(scn->world); free(state->scene); } -struct scene *ingame_scene(struct state *state) { +Scene *ingame_scene(State *state) { (void)state; - struct scene_ingame *new_scene = ccalloc(1, sizeof *new_scene); + SceneIngame *new_scene = ccalloc(1, sizeof *new_scene); new_scene->base.tick = ingame_tick; new_scene->base.end = ingame_end; new_scene->world = world_create(); new_scene->player = player_create(new_scene->world); - new_scene->cam = (t_camera){ .pos = { 32, 0, 1 }, .up = { 0, 1, 0 }, .fov = (float)M_PI_2 }; + new_scene->cam = (Camera){ .pos = { 32, 0, 1 }, .up = { 0, 1, 0 }, .fov = (float)M_PI_2 }; - play_audio_ex("music/mod65.xm", "soundtrack", (t_play_audio_args){ + audio_play_ex("music/mod65.xm", "soundtrack", (PlayAudioArgs){ .repeat = true, .volume = 1.0f }); input_set_mouse_captured(&ctx.input, true); - return (struct scene *)new_scene; + return (Scene *)new_scene; } diff --git a/apps/testgame/scenes/ingame.h b/apps/testgame/scenes/ingame.h index 061dff0..56090ba 100644 --- a/apps/testgame/scenes/ingame.h +++ b/apps/testgame/scenes/ingame.h @@ -9,22 +9,22 @@ #include "../world.h" -struct scene_ingame { - struct scene base; +typedef struct SceneIngame { + Scene base; - struct world *world; - struct player *player; + World *world; + Player *player; - t_camera cam; + Camera cam; /* TODO: put this in a better place */ float yaw; float pitch; float roll; -}; +} SceneIngame; -struct scene *ingame_scene(struct state *state); +Scene *ingame_scene(State *state); #endif diff --git a/apps/testgame/scenes/scene.c b/apps/testgame/scenes/scene.c index 4dd8a82..e39778f 100644 --- a/apps/testgame/scenes/scene.c +++ b/apps/testgame/scenes/scene.c @@ -2,7 +2,7 @@ #include "../state.h" -void switch_to(struct state *state, struct scene *(*scene_func)(struct state *)) { +void switch_to(State *state, Scene *(*scene_func)(State *)) { state->next_scene = scene_func(state); state->is_scene_switching = true; } diff --git a/apps/testgame/scenes/scene.h b/apps/testgame/scenes/scene.h index 26b712d..4d1eab1 100644 --- a/apps/testgame/scenes/scene.h +++ b/apps/testgame/scenes/scene.h @@ -2,15 +2,15 @@ #define SCENE_H -struct state; -struct scene { +typedef struct State State; +typedef struct Scene { char *id; - void (*tick)(struct state *); - void (*end)(struct state *); -}; + void (*tick)(State *); + void (*end)(State *); +} Scene; -void switch_to(struct state *state, struct scene *(*scene_func)(struct state *)); +void switch_to(State *state, Scene *(*scene_func)(State *)); #endif diff --git a/apps/testgame/scenes/title.c b/apps/testgame/scenes/title.c index 4fb0568..7839ea2 100644 --- a/apps/testgame/scenes/title.c +++ b/apps/testgame/scenes/title.c @@ -8,8 +8,8 @@ #include -static void title_tick(struct state *state) { - struct scene_title *scn = (struct scene_title *)state->scene; +static void title_tick(State *state) { + SceneTitle *scn = (SceneTitle *)state->scene; (void)scn; if (input_is_action_just_pressed(&state->ctx->input, "ui_accept")) { @@ -17,7 +17,7 @@ static void title_tick(struct state *state) { } - m_sprite("/assets/title.png", ((t_frect) { + m_sprite("/assets/title.png", ((Rect) { ((float)RENDER_BASE_WIDTH / 2) - ((float)320 / 2), 64, 320, 128 })); @@ -31,42 +31,42 @@ static void title_tick(struct state *state) { int text_w = get_text_width(text_str, text_h, font); push_rectangle( - (t_frect) { + (Rect) { .x = 0, .y = 0, .w = (float)text_w, .h = (float)text_h, }, - (t_color) { 0, 0, 0, 255 } + (Color) { 0, 0, 0, 255 } ); push_text( text_str, - (t_fvec2){ 0, 0 }, + (Vec2){ 0, 0 }, text_h, - (t_color) { 255, 255, 255, 255 }, + (Color) { 255, 255, 255, 255 }, font ); free(text_str); } -static void title_end(struct state *state) { - struct scene_title *scn = (struct scene_title *)state->scene; +static void title_end(State *state) { + SceneTitle *scn = (SceneTitle *)state->scene; player_destroy(scn->player); world_destroy(scn->world); free(state->scene); } -struct scene *title_scene(struct state *state) { +Scene *title_scene(State *state) { (void)state; - struct scene_title *new_scene = ccalloc(1, sizeof *new_scene); + SceneTitle *new_scene = ccalloc(1, sizeof *new_scene); new_scene->base.tick = title_tick; new_scene->base.end = title_end; new_scene->world = world_create(); new_scene->player = player_create(new_scene->world); - return (struct scene *)new_scene; + return (Scene *)new_scene; } diff --git a/apps/testgame/scenes/title.h b/apps/testgame/scenes/title.h index 89b99d7..dbef6f1 100644 --- a/apps/testgame/scenes/title.h +++ b/apps/testgame/scenes/title.h @@ -7,15 +7,15 @@ #include "../world.h" -struct scene_title { - struct scene base; +typedef struct SceneTitle { + Scene base; - struct world *world; - struct player *player; -}; + World *world; + Player *player; +} SceneTitle; -struct scene *title_scene(struct state *state); +Scene *title_scene(State *state); #endif diff --git a/apps/testgame/state.h b/apps/testgame/state.h index 9bb8647..082a856 100644 --- a/apps/testgame/state.h +++ b/apps/testgame/state.h @@ -6,12 +6,15 @@ #include -struct state { - t_ctx *ctx; - struct scene *scene; - struct scene *next_scene; + +typedef struct Scene Scene; + +typedef struct State { + Context *ctx; + Scene *scene; + Scene *next_scene; bool is_scene_switching; -}; +} State; #endif diff --git a/apps/testgame/world.c b/apps/testgame/world.c index 17bcd85..ddd5f69 100644 --- a/apps/testgame/world.c +++ b/apps/testgame/world.c @@ -8,11 +8,11 @@ #include -static void update_tiles(struct world *world) { +static void update_tiles(struct World *world) { for (size_t row = 0; row < world->tilemap_height; ++row) { for (size_t col = 0; col < world->tilemap_width; ++col) { - world->tiles[(row * world->tilemap_width) + col] = (struct tile) { - .rect = (t_rect) { + world->tiles[(row * world->tilemap_width) + col] = (struct Tile) { + .rect = (Recti) { .x = (int)col * world->tile_size, .y = (int)row * world->tile_size, .w = world->tile_size, @@ -25,30 +25,30 @@ static void update_tiles(struct world *world) { } -static t_vec2 to_grid_location(struct world *world, float x, float y) { - return (t_vec2) { +static Vec2i to_grid_location(struct World *world, float x, float y) { + return (Vec2i) { .x = (int)floor(x / (float)world->tile_size), .y = (int)floor(y / (float)world->tile_size), }; } -static void drawdef_debug(struct world *world) { +static void drawdef_debug(struct World *world) { if (!ctx.debug) return; for (size_t i = 0; i < world->tilemap_height * world->tilemap_width; ++i) { if (world->tiles[i].type == TILE_TYPE_VOID) continue; push_rectangle(to_frect(world->tiles[i].rect), - (t_color) { 255, 0, 255, 128 }); + (Color) { 255, 0, 255, 128 }); } } -struct world *world_create(void) { - struct world *world = cmalloc(sizeof *world); +struct World *world_create(void) { + struct World *world = cmalloc(sizeof *world); - *world = (struct world) { + *world = (struct World) { .tiles = NULL, .tile_size = 42, .tilemap_width = 20, @@ -89,7 +89,7 @@ struct world *world_create(void) { } -void world_destroy(struct world *world) { +void world_destroy(struct World *world) { free(world->tiles); for (size_t i = 0; i < world->tilemap_height; ++i) { @@ -101,7 +101,7 @@ void world_destroy(struct world *world) { } -void world_drawdef(struct world *world) { +void world_drawdef(struct World *world) { for (size_t i = 0; i < world->tilemap_height * world->tilemap_width; ++i) { if (world->tiles[i].type == TILE_TYPE_VOID) continue; @@ -113,7 +113,7 @@ void world_drawdef(struct world *world) { } -bool world_find_intersect_frect(struct world *world, t_frect rect, t_frect *intersection) { +bool world_find_intersect_frect(struct World *world, Rect rect, Rect *intersection) { bool is_intersecting = false; const size_t tile_count = world->tilemap_height * world->tilemap_width; @@ -121,7 +121,7 @@ bool world_find_intersect_frect(struct world *world, t_frect rect, t_frect *inte if (world->tiles[i].type == TILE_TYPE_VOID) continue; - t_frect tile_frect = { + Rect tile_frect = { .x = (float)(world->tiles[i].rect.x), .y = (float)(world->tiles[i].rect.y), .w = (float)(world->tiles[i].rect.w), @@ -129,7 +129,7 @@ bool world_find_intersect_frect(struct world *world, t_frect rect, t_frect *inte }; if (intersection == NULL) { - t_frect temp; + Rect temp; is_intersecting = overlap_frect(&rect, &tile_frect, &temp); } else { is_intersecting = overlap_frect(&rect, &tile_frect, intersection); @@ -143,7 +143,7 @@ bool world_find_intersect_frect(struct world *world, t_frect rect, t_frect *inte } -bool world_find_intersect_rect(struct world *world, t_rect rect, t_rect *intersection) { +bool world_find_intersect_rect(struct World *world, Recti rect, Recti *intersection) { bool is_intersecting = false; const size_t tile_count = world->tilemap_height * world->tilemap_width; @@ -151,10 +151,10 @@ bool world_find_intersect_rect(struct world *world, t_rect rect, t_rect *interse if (world->tiles[i].type == TILE_TYPE_VOID) continue; - t_rect *tile_rect = &world->tiles[i].rect; + Recti *tile_rect = &world->tiles[i].rect; if (intersection == NULL) { - t_rect temp; + Recti temp; is_intersecting = overlap_rect(&rect, tile_rect, &temp); } else { is_intersecting = overlap_rect(&rect, tile_rect, intersection); @@ -168,21 +168,21 @@ bool world_find_intersect_rect(struct world *world, t_rect rect, t_rect *interse } -bool world_is_tile_at(struct world *world, float x, float y) { - t_vec2 position_in_grid = to_grid_location(world, x, y); +bool world_is_tile_at(struct World *world, float x, float y) { + Vec2i position_in_grid = to_grid_location(world, x, y); return world->tilemap[position_in_grid.y][position_in_grid.x] != TILE_TYPE_VOID; } -void world_place_tile(struct world *world, float x, float y) { - t_vec2 position_in_grid = to_grid_location(world, x, y); +void world_place_tile(struct World *world, float x, float y) { + Vec2i position_in_grid = to_grid_location(world, x, y); world->tilemap[position_in_grid.y][position_in_grid.x] = TILE_TYPE_SOLID; update_tiles(world); } -void world_remove_tile(struct world *world, float x, float y) { - t_vec2 position_in_grid = to_grid_location(world, x, y); +void world_remove_tile(struct World *world, float x, float y) { + Vec2i position_in_grid = to_grid_location(world, x, y); world->tilemap[position_in_grid.y][position_in_grid.x] = TILE_TYPE_VOID; update_tiles(world); } diff --git a/apps/testgame/world.h b/apps/testgame/world.h index d721a2a..be1c0b4 100644 --- a/apps/testgame/world.h +++ b/apps/testgame/world.h @@ -1,42 +1,44 @@ #ifndef WORLD_H #define WORLD_H +#include "twn_game_api.h" + #include #include -enum tile_type { +typedef enum TileType { TILE_TYPE_VOID, TILE_TYPE_SOLID, -}; +} TileType; -struct tile { - t_rect rect; - enum tile_type type; -}; +typedef struct Tile { + Recti rect; + TileType type; +} Tile; -struct world { - enum tile_type **tilemap; - struct tile *tiles; +typedef struct World { + TileType **tilemap; + Tile *tiles; int tile_size; unsigned int tilemap_width; unsigned int tilemap_height; size_t tile_nonvoid_count; float gravity; -}; +} World; -struct world *world_create(void); -void world_destroy(struct world *world); -void world_drawdef(struct world *world); -bool world_find_intersect_frect(struct world *world, t_frect rect, t_frect *intersection); -bool world_find_intersect_rect(struct world *world, t_rect rect, t_rect *intersection); -bool world_is_tile_at(struct world *world, float x, float y); -void world_place_tile(struct world *world, float x, float y); -void world_remove_tile(struct world *world, float x, float y); +World *world_create(void); +void world_destroy(World *world); +void world_drawdef(World *world); +bool world_find_intersect_frect(World *world, Rect rect, Rect *intersection); +bool world_find_intersect_rect(World *world, Recti rect, Recti *intersection); +bool world_is_tile_at(World *world, float x, float y); +void world_place_tile(World *world, float x, float y); +void world_remove_tile(World *world, float x, float y); #endif diff --git a/data/assets/9slice.png b/data/assets/9slice.png new file mode 100644 index 0000000..0439118 --- /dev/null +++ b/data/assets/9slice.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70992a9f69a8f339b9f18c81e33511aa7ddc5323852d116f56bff3697515ba65 +size 1115 diff --git a/include/twn_audio.h b/include/twn_audio.h index ec41e99..8823d1d 100644 --- a/include/twn_audio.h +++ b/include/twn_audio.h @@ -6,7 +6,7 @@ #include -typedef struct play_audio_args { +typedef struct PlayAudioArgs { /* default: false */ bool repeat; /* crossfade between already playing audio on a given channel, if any */ @@ -18,21 +18,21 @@ typedef struct play_audio_args { /* range: -1.0 to 1.0f */ /* default: 0.0f */ float panning; -} t_play_audio_args; +} PlayAudioArgs; /* plays audio file at specified channel or anywhere if NULL is passed */ /* path must contain valid file extension to infer which file format it is */ /* supported formats: .ogg, .xm */ /* preserves args that are already specified on the channel */ -TWN_API void play_audio(const char *path, const char *channel); +TWN_API void audio_play(const char *path, const char *channel); -TWN_API void play_audio_ex(const char *path, const char *channel, t_play_audio_args args); +TWN_API void audio_play_ex(const char *path, const char *channel, PlayAudioArgs args); /* could be used for modifying args */ /* warn: is only valid if no other calls to audio are made */ -TWN_API t_play_audio_args *get_audio_args(const char *channel); +TWN_API PlayAudioArgs *audio_get_args(const char *channel); -TWN_API t_play_audio_args get_default_audio_args(void); +TWN_API PlayAudioArgs audio_get_default_args(void); #endif diff --git a/include/twn_camera.h b/include/twn_camera.h index d57a667..fb8ca28 100644 --- a/include/twn_camera.h +++ b/include/twn_camera.h @@ -8,15 +8,15 @@ /* for example, perspective matrix only needs recaluclation on FOV change */ /* first person camera class */ -typedef struct camera { - t_fvec3 pos; /* eye position */ - t_fvec3 target; /* normalized target vector */ - t_fvec3 up; /* normalized up vector */ +typedef struct Camera { + Vec3 pos; /* eye position */ + Vec3 target; /* normalized target vector */ + Vec3 up; /* normalized up vector */ float fov; /* field of view, in radians */ -} t_camera; +} Camera; -TWN_API t_matrix4 camera_look_at(const t_camera *camera); +TWN_API Matrix4 camera_look_at(const Camera *camera); -TWN_API t_matrix4 camera_perspective(const t_camera *const camera); +TWN_API Matrix4 camera_perspective(const Camera *const camera); #endif diff --git a/include/twn_context.h b/include/twn_context.h index f1df1ff..46e6b60 100644 --- a/include/twn_context.h +++ b/include/twn_context.h @@ -8,8 +8,8 @@ #include -typedef struct context { - struct input_state input; +typedef struct Context { + struct InputState input; int64_t delta_time; /* preserves real time frame delta with no manipilation */ uint64_t tick_count; @@ -31,10 +31,10 @@ typedef struct context { bool is_running; bool window_size_has_changed; bool initialization_needed; -} t_ctx; +} Context; #ifndef TWN_ENGINE_CONTEXT_C_H -TWN_API extern t_ctx ctx; +TWN_API extern Context ctx; #endif #endif diff --git a/include/twn_input.h b/include/twn_input.h index f0e6cdc..9333f96 100644 --- a/include/twn_input.h +++ b/include/twn_input.h @@ -12,16 +12,16 @@ #include -enum button_source { +typedef enum ButtonSource { BUTTON_SOURCE_NOT_SET, BUTTON_SOURCE_KEYBOARD_PHYSICAL, BUTTON_SOURCE_KEYBOARD_CHARACTER, BUTTON_SOURCE_GAMEPAD, BUTTON_SOURCE_MOUSE, -}; +} ButtonSource; -union button_code { +union ButtonCode { SDL_Scancode scancode; SDL_Keycode keycode; SDL_GameControllerButton gamepad_button; @@ -31,71 +31,71 @@ union button_code { /* an input to which an action is bound */ /* it is not limited to literal buttons */ -struct button { - enum button_source source; - union button_code code; -}; +typedef struct Button { + enum ButtonSource source; + union ButtonCode code; +} Button; /* represents the collective state of a group of buttons */ /* that is, changes in the states of any of the bound buttons will affect it */ -struct action { +typedef struct Action { size_t num_bindings; /* if you bind more than NUM_KEYBIND_SLOTS (set in config.h) */ - /* it forgets the first button to add the new one at the end */ - struct button bindings[NUM_KEYBIND_SLOTS]; + /* it forgets the first Button to add the new one at the end */ + Button bindings[NUM_KEYBIND_SLOTS]; - t_fvec2 position; /* set if applicable, e.g. mouse click */ + Vec2 position; /* set if applicable, e.g. mouse click */ bool is_pressed; bool just_changed; -}; +} Action; -struct action_hash_item { +typedef struct ActionHashItem { char *key; - struct action value; -}; + Action value; +} ActionHashItem; -struct input_state { - struct action_hash_item *action_hash; +typedef struct InputState { + ActionHashItem *action_hash; const uint8_t *keyboard_state; /* array of booleans indexed by scancode */ uint32_t mouse_state; /* SDL mouse button bitmask */ - t_vec2 mouse_window_position; - t_vec2 mouse_relative_position; - enum button_source last_active_source; + Vec2i mouse_window_position; + Vec2i mouse_relative_position; + ButtonSource last_active_source; bool is_anything_just_pressed; -}; +} InputState; -TWN_API void input_state_init(struct input_state *input); -TWN_API void input_state_deinit(struct input_state *input); -TWN_API void input_state_update(struct input_state *input); +TWN_API void input_state_init(InputState *input); +TWN_API void input_state_deinit(InputState *input); +TWN_API void input_state_update(InputState *input); -TWN_API void input_bind_action_scancode(struct input_state *input, +TWN_API void input_bind_action_scancode(InputState *input, char *action_name, SDL_Scancode scancode); -TWN_API void input_unbind_action_scancode(struct input_state *input, +TWN_API void input_unbind_action_scancode(InputState *input, char *action_name, SDL_Scancode scancode); -TWN_API void input_bind_action_mouse(struct input_state *input, +TWN_API void input_bind_action_mouse(InputState *input, char *action_name, uint8_t mouse_button); -TWN_API void input_unbind_action_mouse(struct input_state *input, +TWN_API void input_unbind_action_mouse(InputState *input, char *action_name, uint8_t mouse_button); -TWN_API void input_add_action(struct input_state *input, char *action_name); -TWN_API void input_delete_action(struct input_state *input, char *action_name); +TWN_API void input_add_action(InputState *input, char *action_name); +TWN_API void input_delete_action(InputState *input, char *action_name); -TWN_API bool input_is_action_pressed(struct input_state *input, char *action_name); -TWN_API bool input_is_action_just_pressed(struct input_state *input, char *action_name); -TWN_API bool input_is_action_just_released(struct input_state *input, char *action_name); +TWN_API bool input_is_action_pressed(InputState *input, char *action_name); +TWN_API bool input_is_action_just_pressed(InputState *input, char *action_name); +TWN_API bool input_is_action_just_released(InputState *input, char *action_name); -TWN_API t_fvec2 input_get_action_position(struct input_state *input, char *action_name); +TWN_API Vec2 input_get_action_position(InputState *input, char *action_name); -TWN_API void input_set_mouse_captured(struct input_state *input, bool value); -TWN_API bool input_is_mouse_captured(struct input_state *input); +TWN_API void input_set_mouse_captured(InputState *input, bool value); +TWN_API bool input_is_mouse_captured(InputState *input); #endif diff --git a/include/twn_rendering.h b/include/twn_rendering.h index 0ee9d09..17ead8e 100644 --- a/include/twn_rendering.h +++ b/include/twn_rendering.h @@ -10,67 +10,67 @@ #include -typedef struct push_sprite_args { +typedef struct PushSpriteArgs { char *path; - t_frect rect; + Rect rect; m_option_list( - t_frect, texture_region, - t_color, color, + Rect, texture_region, + Color, color, float, rotation, bool, flip_x, bool, flip_y, bool, stretch ) -} t_push_sprite_args; +} PushSpriteArgs; /* pushes a sprite onto the sprite render queue */ /* this is a simplified version of push_sprite_ex for the most common case. */ /* it assumes you want no color modulation, no rotation, no flip */ -TWN_API void push_sprite(t_push_sprite_args args); -#define m_sprite(...) (push_sprite((t_push_sprite_args){__VA_ARGS__})) +TWN_API void push_sprite(PushSpriteArgs args); +#define m_sprite(...) (push_sprite((PushSpriteArgs){__VA_ARGS__})) /* pushes a filled rectangle onto the rectangle render queue */ -TWN_API void push_rectangle(t_frect rect, t_color color); +TWN_API void push_rectangle(Rect rect, Color color); /* pushes a filled circle onto the circle render queue */ -TWN_API void push_circle(t_fvec2 position, float radius, t_color color); +TWN_API void push_circle(Vec2 position, float radius, Color color); -TWN_API void push_text(char *string, t_fvec2 position, int height_px, t_color color, const char *font_path); +TWN_API void push_text(char *string, Vec2 position, int height_px, Color color, const char *font_path); TWN_API int get_text_width(char *string, int height_px, const char *font_path); /* pushes a textured 3d triangle onto the render queue */ /* vertices are in absolute coordinates, relative to world origin */ /* texture coordinates are in pixels */ TWN_API void unfurl_triangle(const char *path, - t_fvec3 v0, - t_fvec3 v1, - t_fvec3 v2, - t_shvec2 uv0, - t_shvec2 uv1, - t_shvec2 uv2); + Vec3 v0, + Vec3 v1, + Vec3 v2, + Vec2sh uv0, + Vec2sh uv1, + Vec2sh uv2); // TODO: decide whether it's needed to begin with? // intended usage for it is baked lighting, i would think. /* pushes a colored textured 3d triangle onto the render queue */ // void unfurl_colored_triangle(const char *path, -// t_fvec3 v0, -// t_fvec3 v1, -// t_fvec3 v2, -// t_shvec2 uv0, -// t_shvec2 uv1, -// t_shvec2 uv2, -// t_color c0, -// t_color c1, -// t_color c2); +// Vec3 v0, +// Vec3 v1, +// Vec3 v2, +// Vec2sh uv0, +// Vec2sh uv1, +// Vec2sh uv2, +// Color c0, +// Color c1, +// Color c2); // TODO: // http://www.lighthouse3d.com/opengl/billboarding/index.php?billCheat2 // void unfurl_billboard(const char *path, -// t_fvec3 position, -// t_fvec2 scaling, -// t_frect uvs); +// Vec2 position, +// Vec2 scaling, +// Rect uvs); /* pushes a camera state to be used for all future unfurl_* commands */ -TWN_API void set_camera(const t_camera *camera); +TWN_API void set_camera(const Camera *camera); #endif diff --git a/include/twn_texture_modes.h b/include/twn_texture_modes.h index 052f331..30bcb17 100644 --- a/include/twn_texture_modes.h +++ b/include/twn_texture_modes.h @@ -2,10 +2,10 @@ #define TWN_TEXTURES_MODES_H /* alpha channel information */ -enum texture_mode { +typedef enum TextureMode { TEXTURE_MODE_OPAQUE, /* all pixels are solid */ TEXTURE_MODE_SEETHROUGH, /* some pixels are alpha zero */ TEXTURE_MODE_GHOSTLY, /* arbitrary alpha values */ -}; +} TextureMode; #endif diff --git a/include/twn_util.h b/include/twn_util.h index 57cc577..d3fba71 100644 --- a/include/twn_util.h +++ b/include/twn_util.h @@ -80,54 +80,54 @@ TWN_API TWN_API bool strends(const char *str, const char *suffix); /* */ /* 32-bit color data */ -typedef struct color { +typedef struct Color { _Alignas(4) uint8_t r; uint8_t g; uint8_t b; uint8_t a; -} t_color; +} Color; /* a rectangle with the origin at the upper left (integer) */ -typedef struct rect { +typedef struct Recti { _Alignas(16) int32_t x; int32_t y; int32_t w; int32_t h; -} t_rect; +} Recti; /* a rectangle with the origin at the upper left (floating point) */ -typedef struct frect { +typedef struct Rect { _Alignas(16) float x; float y; float w; float h; -} t_frect; +} Rect; /* calculates the overlap of two rectangles and places it in result. */ /* result may be NULL. if this is the case, it will simply be ignored. */ /* returns true if the rectangles are indeed intersecting. */ -TWN_API bool overlap_rect(const t_rect *a, const t_rect *b, t_rect *result); -TWN_API bool overlap_frect(const t_frect *a, const t_frect *b, t_frect *result); +TWN_API bool overlap_rect(const Recti *a, const Recti *b, Recti *result); +TWN_API bool overlap_frect(const Rect *a, const Rect *b, Rect *result); /* returns true if two rectangles are intersecting */ -TWN_API bool intersect_rect(const t_rect *a, const t_rect *b); -TWN_API bool intersect_frect(const t_frect *a, const t_frect *b); +TWN_API bool intersect_rect(const Recti *a, const Recti *b); +TWN_API bool intersect_frect(const Rect *a, const Rect *b); -/* TODO: generics and specials (see m_to_fvec2() for an example)*/ -TWN_API t_frect to_frect(t_rect rect); +/* TODO: generics and specials (see m_vec2_from() for an example)*/ +TWN_API Rect to_frect(Recti rect); -TWN_API t_fvec2 frect_center(t_frect rect); +TWN_API Vec2 frect_center(Rect rect); -typedef struct matrix4 { - t_fvec4 row[4]; -} t_matrix4; +typedef struct Matrix4 { + Vec4 row[4]; +} Matrix4; /* decrements an lvalue (which should be an int), stopping at 0 */ @@ -162,9 +162,9 @@ static inline float fast_sqrt(float x) } -static inline t_fvec2 fast_cossine(float a) { +static inline Vec2 fast_cossine(float a) { const float s = sinf(a); - return (t_fvec2){ + return (Vec2){ .x = fast_sqrt(1.0f - s * s) * (a >= (float)M_PI_2 && a < (float)(M_PI + M_PI_2) ? -1 : 1), .y = s }; diff --git a/include/twn_vec.h b/include/twn_vec.h index 2cd8645..a3cd521 100644 --- a/include/twn_vec.h +++ b/include/twn_vec.h @@ -6,92 +6,92 @@ /* a point in some space (integer) */ -typedef struct vec2 { +typedef struct Vec2i { _Alignas(8) int32_t x; int32_t y; -} t_vec2; +} Vec2i; /* a point in some space (floating point) */ -typedef struct fvec2 { +typedef struct Vec2 { _Alignas(8) float x; float y; -} t_fvec2; +} Vec2; /* a point in some three dimension space (floating point) */ /* y goes up, x goes to the right */ -typedef struct fvec3 { +typedef struct Vec3 { _Alignas(16) float x; float y; float z; -} t_fvec3; +} Vec3; /* a point in some three dimension space (floating point) */ /* y goes up, x goes to the right */ -typedef struct fvec4 { +typedef struct Vec4 { _Alignas(16) float x; float y; float z; float w; -} t_fvec4; +} Vec4; /* a point in some space (short) */ -typedef struct shvec2 { +typedef struct Vec2sh { _Alignas(4) int16_t x; int16_t y; -} t_shvec2; +} Vec2sh; /* aren't macros to prevent double evaluation with side effects */ /* maybe could be inlined? i hope LTO will resolve this */ -static inline t_fvec2 fvec2_from_vec2(t_vec2 vec) { - return (t_fvec2) { +static inline Vec2 vec2_from_vec2i(Vec2i vec) { + return (Vec2) { .x = (float)vec.x, .y = (float)vec.y, }; } -static inline t_fvec2 fvec2_from_shvec2(t_shvec2 vec) { - return (t_fvec2) { +static inline Vec2 vec2_from_vec2sh(Vec2sh vec) { + return (Vec2) { .x = (float)vec.x, .y = (float)vec.y, }; } -static inline t_fvec3 fvec3_add(t_fvec3 a, t_fvec3 b) { - return (t_fvec3) { a.x + b.x, a.y + b.y, a.z + b.z }; +static inline Vec3 vec3_add(Vec3 a, Vec3 b) { + return (Vec3) { a.x + b.x, a.y + b.y, a.z + b.z }; } -static inline t_fvec3 fvec3_sub(t_fvec3 a, t_fvec3 b) { - return (t_fvec3) { a.x - b.x, a.y - b.y, a.z - b.z }; +static inline Vec3 vec3_sub(Vec3 a, Vec3 b) { + return (Vec3) { a.x - b.x, a.y - b.y, a.z - b.z }; } -static inline t_fvec2 fvec2_div(t_fvec2 a, t_fvec2 b) { - return (t_fvec2) { a.x / b.x, a.y / b.y }; +static inline Vec2 vec2_div(Vec2 a, Vec2 b) { + return (Vec2) { a.x / b.x, a.y / b.y }; } -static inline t_fvec2 fvec2_scale(t_fvec2 a, float s) { - return (t_fvec2) { a.x * s, a.y * s }; +static inline Vec2 vec2_scale(Vec2 a, float s) { + return (Vec2) { a.x * s, a.y * s }; } -static inline t_fvec3 fvec3_scale(t_fvec3 a, float s) { - return (t_fvec3) { a.x * s, a.y * s, a.z * s }; +static inline Vec3 vec3_scale(Vec3 a, float s) { + return (Vec3) { a.x * s, a.y * s, a.z * s }; } -static inline float fvec3_dot(t_fvec3 a, t_fvec3 b) { +static inline float vec3_dot(Vec3 a, Vec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; } -static inline t_fvec3 fvec3_cross(t_fvec3 a, t_fvec3 b) { - return (t_fvec3) { +static inline Vec3 vec3_cross(Vec3 a, Vec3 b) { + return (Vec3) { a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x, @@ -99,66 +99,66 @@ static inline t_fvec3 fvec3_cross(t_fvec3 a, t_fvec3 b) { } /* TODO: fast_sqrt version? */ -static inline t_fvec3 fvec3_norm(t_fvec3 a) { - const float n = sqrtf(fvec3_dot(a, a)); +static inline Vec3 vec3_norm(Vec3 a) { + const float n = sqrtf(vec3_dot(a, a)); /* TODO: do we need truncating over epsilon as cglm does? */ - return fvec3_scale(a, 1.0f / n); + return vec3_scale(a, 1.0f / n); } -static inline t_fvec3 fvec3_rotate(t_fvec3 v, float angle, t_fvec3 axis) { +static inline Vec3 vec3_rotate(Vec3 v, float angle, Vec3 axis) { /* from cglm */ - t_fvec3 v1, v2, k; + Vec3 v1, v2, k; float c, s; c = cosf(angle); s = sinf(angle); - k = fvec3_norm(axis); + k = vec3_norm(axis); /* Right Hand, Rodrigues' rotation formula: v = v*cos(t) + (kxv)sin(t) + k*(k.v)(1 - cos(t)) */ - v1 = fvec3_scale(v, c); + v1 = vec3_scale(v, c); - v2 = fvec3_cross(k, v); - v2 = fvec3_scale(v2, s); + v2 = vec3_cross(k, v); + v2 = vec3_scale(v2, s); - v1 = fvec3_add(v1, v2); + v1 = vec3_add(v1, v2); - v2 = fvec3_scale(k, fvec3_dot(k, v) * (1.0f - c)); - v = fvec3_add(v1, v2); + v2 = vec3_scale(k, vec3_dot(k, v) * (1.0f - c)); + v = vec3_add(v1, v2); return v; } -#define m_to_fvec2(p_any_vec2) (_Generic((p_any_vec2), \ - t_vec2: fvec2_from_vec2, \ - t_shvec2: fvec2_from_shvec2 \ +#define m_vec2_from(p_any_vec2) (_Generic((p_any_vec2), \ + Vec2i: vec2_from_vec2i, \ + Vec2sh: vec2_from_vec2sh \ )(p_any_vec2)) #define m_vec_sub(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \ - t_fvec3: fvec3_sub \ + Vec3: vec3_sub \ )(p_any_vec0, p_any_vec1)) #define m_vec_div(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \ - t_fvec2: fvec2_div \ + Vec2: vec2_div \ )(p_any_vec0, p_any_vec1)) -#define m_vec_scale(p_any_vec, p_any_scalar) (_Generic((p_any_vec), \ - t_fvec2: fvec2_scale, \ - t_fvec3: fvec3_scale \ +#define m_vec_scale(p_any_vec, p_any_scalar) (_Generic((p_any_vec), \ + Vec2: vec2_scale, \ + Vec3: vec3_scale \ )(p_any_vec, p_any_scalar)) #define m_vec_dot(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \ - t_fvec3: fvec3_dot \ + Vec3: vec3_dot \ )(p_any_vec0, p_any_vec1)) -#define m_vec_cross(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \ - t_fvec3: fvec3_cross \ +#define m_vec_cross(p_any_vec0, p_any_vec1) (_Generic((p_any_vec0), \ + Vec3: vec3_cross \ )(p_any_vec0, p_any_vec1)) #define m_vec_norm(p_any_vec) (_Generic((p_any_vec), \ - t_fvec3: fvec3_norm \ + Vec3: vec3_norm \ )(p_any_vec)) #endif diff --git a/src/rendering/twn_circles.c b/src/rendering/twn_circles.c index 4408ecf..3ac0178 100644 --- a/src/rendering/twn_circles.c +++ b/src/rendering/twn_circles.c @@ -7,14 +7,14 @@ #include -void push_circle(t_fvec2 position, float radius, t_color color) { - struct circle_primitive circle = { +void push_circle(Vec2 position, float radius, Color color) { + CirclePrimitive circle = { .radius = radius, .color = color, .position = position, }; - struct primitive_2d primitive = { + Primitive2D primitive = { .type = PRIMITIVE_2D_CIRCLE, .circle = circle, }; @@ -24,8 +24,8 @@ void push_circle(t_fvec2 position, float radius, t_color color) { /* TODO: caching and reuse scheme */ /* vertices_out and indices_out MUST BE FREED */ -void create_circle_geometry(t_fvec2 position, - t_color color, +void create_circle_geometry(Vec2 position, + Color color, float radius, size_t num_vertices, SDL_Vertex **vertices_out, diff --git a/src/rendering/twn_gl_15_gpu_texture.c b/src/rendering/twn_gl_15_gpu_texture.c index f4cad53..7d6301c 100644 --- a/src/rendering/twn_gl_15_gpu_texture.c +++ b/src/rendering/twn_gl_15_gpu_texture.c @@ -2,7 +2,7 @@ #include "twn_util.h" -gpu_texture create_gpu_texture(enum texture_filter filter, bool generate_mipmaps) { +GPUTexture create_gpu_texture(TextureFilter filter, bool generate_mipmaps) { GLuint texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); @@ -29,12 +29,12 @@ gpu_texture create_gpu_texture(enum texture_filter filter, bool generate_mipmaps } -void delete_gpu_texture(gpu_texture texture) { +void delete_gpu_texture(GPUTexture texture) { glDeleteTextures(1, &texture); } -void upload_gpu_texture(gpu_texture texture, void *pixels, int channels, int width, int height) { +void upload_gpu_texture(GPUTexture texture, void *pixels, int channels, int width, int height) { glBindTexture(GL_TEXTURE_2D, texture); int format_internal, format; @@ -66,6 +66,6 @@ void upload_gpu_texture(gpu_texture texture, void *pixels, int channels, int wid } -void bind_gpu_texture(gpu_texture texture) { +void bind_gpu_texture(GPUTexture texture) { glBindTexture(GL_TEXTURE_2D, texture); } diff --git a/src/rendering/twn_gl_15_rendering.c b/src/rendering/twn_gl_15_rendering.c index bb44505..4ae7aad 100644 --- a/src/rendering/twn_gl_15_rendering.c +++ b/src/rendering/twn_gl_15_rendering.c @@ -11,50 +11,50 @@ /* TODO: use int16_t for uvs */ /* TODO: use packed types? */ /* TODO: int16_t could be used for positioning, but we would need to have more CPU calcs */ -struct element_indexed_quad { +typedef struct ElementIndexedQuad { /* upper-left */ - t_fvec2 v0; - t_fvec2 uv0; - t_color c0; + Vec2 v0; + Vec2 uv0; + Color c0; /* bottom-left */ - t_fvec2 v1; - t_fvec2 uv1; - t_color c1; + Vec2 v1; + Vec2 uv1; + Color c1; /* bottom-right */ - t_fvec2 v2; - t_fvec2 uv2; - t_color c2; + Vec2 v2; + Vec2 uv2; + Color c2; /* upper-right */ - t_fvec2 v3; - t_fvec2 uv3; - t_color c3; -}; + Vec2 v3; + Vec2 uv3; + Color c3; +} ElementIndexedQuad; -struct element_indexed_quad_without_color { +typedef struct ElementIndexedQuadWithoutColor { /* upper-left */ - t_fvec2 v0; - t_fvec2 uv0; + Vec2 v0; + Vec2 uv0; /* bottom-left */ - t_fvec2 v1; - t_fvec2 uv1; + Vec2 v1; + Vec2 uv1; /* bottom-right */ - t_fvec2 v2; - t_fvec2 uv2; + Vec2 v2; + Vec2 uv2; /* upper-right */ - t_fvec2 v3; - t_fvec2 uv3; -}; + Vec2 v3; + Vec2 uv3; +} ElementIndexedQuadWithoutColor; typedef enum { PIPELINE_NO, PIPELINE_SPACE, PIPELINE_2D, -} pipeline; +} Pipeline; -static pipeline pipeline_last_used = PIPELINE_NO; +static Pipeline pipeline_last_used = PIPELINE_NO; void use_space_pipeline(void) { @@ -117,7 +117,7 @@ void use_2d_pipeline(void) { } -void upload_quad_vertices(t_frect rect) { +void upload_quad_vertices(Rect rect) { /* client memory needs to be reachable on glDraw*, so */ static float vertices[6 * 2]; @@ -132,7 +132,7 @@ void upload_quad_vertices(t_frect rect) { } -void render_rectangle(const struct rect_primitive *rectangle) { +void render_rectangle(const RectPrimitive *rectangle) { glColor4ub(rectangle->color.r, rectangle->color.g, rectangle->color.b, rectangle->color.a); @@ -144,7 +144,7 @@ void render_rectangle(const struct rect_primitive *rectangle) { } -void render_circle(const struct circle_primitive *circle) { +void render_circle(const CirclePrimitive *circle) { SDL_Vertex *vertices = NULL; int *indices = NULL; int num_vertices = (int)circle->radius; @@ -181,7 +181,7 @@ void render_circle(const struct circle_primitive *circle) { } -void use_texture_mode(enum texture_mode mode) { +void use_texture_mode(TextureMode mode) { if (mode == TEXTURE_MODE_GHOSTLY) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -203,21 +203,21 @@ void use_texture_mode(enum texture_mode mode) { } -vertex_buffer_builder build_vertex_buffer(vertex_buffer buffer, size_t bytes) { +VertexBufferBuilder build_vertex_buffer(VertexBuffer buffer, size_t bytes) { glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, bytes, NULL, GL_STREAM_DRAW); void *mapping = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); if (!mapping) CRY("build_vertex_buffer", "Error mapping a vertex array buffer"); - return (vertex_buffer_builder) { + return (VertexBufferBuilder) { .mapping = mapping, .bytes_left = bytes, }; } -bool push_to_vertex_buffer_builder(vertex_buffer_builder *builder, +bool push_to_vertex_buffer_builder(VertexBufferBuilder *builder, void *bytes, size_t size) { if (builder->bytes_left == 0) return false; @@ -237,9 +237,9 @@ bool push_to_vertex_buffer_builder(vertex_buffer_builder *builder, } -void finally_render_sprites(const struct primitive_2d primitives[], - const struct sprite_batch batch, - const vertex_buffer buffer) +void finally_render_sprites(const Primitive2D primitives[], + const struct SpriteBatch batch, + const VertexBuffer buffer) { /* TODO: maybe do, dunno */ // glBindBuffer(GL_VERTEX_ARRAY, vertex_buffer); @@ -250,13 +250,13 @@ void finally_render_sprites(const struct primitive_2d primitives[], GLsizei uvoff; if (!batch.constant_colored) { - off = offsetof(struct element_indexed_quad, v1); - voff = offsetof(struct element_indexed_quad, v0); - uvoff = offsetof(struct element_indexed_quad, uv0); + off = offsetof(ElementIndexedQuad, v1); + voff = offsetof(ElementIndexedQuad, v0); + uvoff = offsetof(ElementIndexedQuad, uv0); } else { - off = offsetof(struct element_indexed_quad_without_color, v1); - voff = offsetof(struct element_indexed_quad_without_color, v0); - uvoff = offsetof(struct element_indexed_quad_without_color, uv0); + off = offsetof(ElementIndexedQuadWithoutColor, v1); + voff = offsetof(ElementIndexedQuadWithoutColor, v0); + uvoff = offsetof(ElementIndexedQuadWithoutColor, uv0); } /* vertex specification */ @@ -278,7 +278,7 @@ void finally_render_sprites(const struct primitive_2d primitives[], glColorPointer(4, GL_UNSIGNED_BYTE, off, - (void *)offsetof(struct element_indexed_quad, c0)); + (void *)offsetof(ElementIndexedQuad, c0)); } else glColor4ub(primitives[0].sprite.color.r, primitives[0].sprite.color.g, @@ -307,22 +307,22 @@ void finally_render_sprites(const struct primitive_2d primitives[], } -size_t get_sprite_payload_size(struct sprite_batch batch) { +size_t get_sprite_payload_size(struct SpriteBatch batch) { if (batch.constant_colored) - return sizeof (struct element_indexed_quad_without_color); + return sizeof (ElementIndexedQuadWithoutColor); else - return sizeof (struct element_indexed_quad); + return sizeof (ElementIndexedQuad); } -bool push_sprite_payload_to_vertex_buffer_builder(struct sprite_batch batch, - vertex_buffer_builder *builder, - t_fvec2 v0, t_fvec2 v1, t_fvec2 v2, t_fvec2 v3, - t_fvec2 uv0, t_fvec2 uv1, t_fvec2 uv2, t_fvec2 uv3, - t_color color) +bool push_sprite_payload_to_vertex_buffer_builder(struct SpriteBatch batch, + VertexBufferBuilder *builder, + Vec2 v0, Vec2 v1, Vec2 v2, Vec2 v3, + Vec2 uv0, Vec2 uv1, Vec2 uv2, Vec2 uv3, + Color color) { if (!batch.constant_colored) { - struct element_indexed_quad buffer_element = { + ElementIndexedQuad buffer_element = { .v0 = v0, .v1 = v1, .v2 = v2, @@ -343,7 +343,7 @@ bool push_sprite_payload_to_vertex_buffer_builder(struct sprite_batch batch, return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); } else { - struct element_indexed_quad_without_color buffer_element = { + ElementIndexedQuadWithoutColor buffer_element = { .v0 = v0, .v1 = v1, .v2 = v2, @@ -360,9 +360,9 @@ bool push_sprite_payload_to_vertex_buffer_builder(struct sprite_batch batch, } -void finally_draw_uncolored_space_traingle_batch(const struct mesh_batch *batch, - const t_texture_key texture_key, - const vertex_buffer buffer) +void finally_draw_uncolored_space_traingle_batch(const MeshBatch *batch, + const TextureKey texture_key, + const VertexBuffer buffer) { const size_t primitives_len = arrlenu(batch->primitives); @@ -374,15 +374,15 @@ void finally_draw_uncolored_space_traingle_batch(const struct mesh_batch *batch, glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, - offsetof(struct uncolored_space_triangle_payload, v1), - (void *)offsetof(struct uncolored_space_triangle_payload, v0)); + offsetof(struct UncoloredSpaceTrianglePayload, v1), + (void *)offsetof(struct UncoloredSpaceTrianglePayload, v0)); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTexture(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, - offsetof(struct uncolored_space_triangle_payload, v1), - (void *)offsetof(struct uncolored_space_triangle_payload, uv0)); + offsetof(struct UncoloredSpaceTrianglePayload, v1), + (void *)offsetof(struct UncoloredSpaceTrianglePayload, uv0)); /* commit for drawing */ glDrawArrays(GL_TRIANGLES, 0, 3 * (GLint)primitives_len); @@ -396,32 +396,32 @@ void finally_draw_uncolored_space_traingle_batch(const struct mesh_batch *batch, } -bool push_text_payload_to_vertex_buffer_builder(struct font_data const *font_data, - vertex_buffer_builder *builder, +bool push_text_payload_to_vertex_buffer_builder(FontData const *font_data, + VertexBufferBuilder *builder, stbtt_aligned_quad quad) { (void)font_data; - struct element_indexed_quad_without_color buffer_element = { - .v0 = (t_fvec2){ quad.x0, quad.y0 }, - .v1 = (t_fvec2){ quad.x1, quad.y0 }, - .v2 = (t_fvec2){ quad.x1, quad.y1 }, - .v3 = (t_fvec2){ quad.x0, quad.y1 }, + ElementIndexedQuadWithoutColor buffer_element = { + .v0 = (Vec2){ quad.x0, quad.y0 }, + .v1 = (Vec2){ quad.x1, quad.y0 }, + .v2 = (Vec2){ quad.x1, quad.y1 }, + .v3 = (Vec2){ quad.x0, quad.y1 }, - .uv0 = (t_fvec2){ quad.s0, quad.t0 }, - .uv1 = (t_fvec2){ quad.s1, quad.t0 }, - .uv2 = (t_fvec2){ quad.s1, quad.t1 }, - .uv3 = (t_fvec2){ quad.s0, quad.t1 }, + .uv0 = (Vec2){ quad.s0, quad.t0 }, + .uv1 = (Vec2){ quad.s1, quad.t0 }, + .uv2 = (Vec2){ quad.s1, quad.t1 }, + .uv3 = (Vec2){ quad.s0, quad.t1 }, }; return push_to_vertex_buffer_builder(builder, &buffer_element, sizeof buffer_element); } -void finally_draw_text(struct font_data const *font_data, +void finally_draw_text(FontData const *font_data, size_t len, - t_color color, - vertex_buffer buffer) + Color color, + VertexBuffer buffer) { (void)buffer; @@ -429,15 +429,15 @@ void finally_draw_text(struct font_data const *font_data, glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, - offsetof(struct element_indexed_quad_without_color, v1), - (void *)(size_t)offsetof(struct element_indexed_quad_without_color, v0)); + offsetof(ElementIndexedQuadWithoutColor, v1), + (void *)(size_t)offsetof(ElementIndexedQuadWithoutColor, v0)); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTexture(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, - offsetof(struct element_indexed_quad_without_color, v1), - (void *)(size_t)offsetof(struct element_indexed_quad_without_color, uv0)); + offsetof(ElementIndexedQuadWithoutColor, v1), + (void *)(size_t)offsetof(ElementIndexedQuadWithoutColor, uv0)); bind_quad_element_buffer(); @@ -462,5 +462,5 @@ void finally_draw_text(struct font_data const *font_data, size_t get_text_payload_size(void) { - return sizeof (struct element_indexed_quad_without_color); + return sizeof (ElementIndexedQuadWithoutColor); } diff --git a/src/rendering/twn_gl_any_rendering.c b/src/rendering/twn_gl_any_rendering.c index 7625f20..be74346 100644 --- a/src/rendering/twn_gl_any_rendering.c +++ b/src/rendering/twn_gl_any_rendering.c @@ -14,19 +14,19 @@ void setup_viewport(int x, int y, int width, int height) { } -vertex_buffer create_vertex_buffer(void) { +VertexBuffer create_vertex_buffer(void) { GLuint result; glGenBuffers(1, &result); return result; } -void delete_vertex_buffer(vertex_buffer buffer) { +void delete_vertex_buffer(VertexBuffer buffer) { glDeleteBuffers(1, &buffer); } -void specify_vertex_buffer(vertex_buffer buffer, void *data, size_t bytes) { +void specify_vertex_buffer(VertexBuffer buffer, void *data, size_t bytes) { glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, bytes, data, GL_STREAM_DRAW); } diff --git a/src/rendering/twn_gpu_texture_c.h b/src/rendering/twn_gpu_texture_c.h index 6ed3d7e..5ccacbf 100644 --- a/src/rendering/twn_gpu_texture_c.h +++ b/src/rendering/twn_gpu_texture_c.h @@ -3,19 +3,19 @@ #include -typedef GLuint gpu_texture; +typedef GLuint GPUTexture; -enum texture_filter { +typedef enum TextureFilter { TEXTURE_FILTER_NEAREAST, TEXTURE_FILTER_LINEAR, -}; +} TextureFilter; -gpu_texture create_gpu_texture(enum texture_filter filter, bool generate_mipmaps); +GPUTexture create_gpu_texture(TextureFilter filter, bool generate_mipmaps); -void delete_gpu_texture(gpu_texture texture); +void delete_gpu_texture(GPUTexture texture); -void upload_gpu_texture(gpu_texture texture, void *pixels, int channels, int width, int height); +void upload_gpu_texture(GPUTexture texture, void *pixels, int channels, int width, int height); -void bind_gpu_texture(gpu_texture texture); +void bind_gpu_texture(GPUTexture texture); #endif diff --git a/src/rendering/twn_rendering.c b/src/rendering/twn_rendering.c index bd9b04e..e04d485 100644 --- a/src/rendering/twn_rendering.c +++ b/src/rendering/twn_rendering.c @@ -17,8 +17,8 @@ /* TODO: have a default initialized one */ -t_matrix4 camera_projection_matrix; -t_matrix4 camera_look_at_matrix; +Matrix4 camera_projection_matrix; +Matrix4 camera_look_at_matrix; void render_queue_clear(void) { @@ -41,13 +41,13 @@ void render_queue_clear(void) { /* rectangle */ -void push_rectangle(t_frect rect, t_color color) { - struct rect_primitive rectangle = { +void push_rectangle(Rect rect, Color color) { + RectPrimitive rectangle = { .rect = rect, .color = color, }; - struct primitive_2d primitive = { + Primitive2D primitive = { .type = PRIMITIVE_2D_RECT, .rect = rectangle, }; @@ -64,11 +64,11 @@ static void render_2d(void) { size_t batch_count = 0; for (size_t i = 0; i < render_queue_len; ++i) { - const struct primitive_2d *current = &ctx.render_queue_2d[i]; + const Primitive2D *current = &ctx.render_queue_2d[i]; switch (current->type) { case PRIMITIVE_2D_SPRITE: { - const struct sprite_batch batch = + const struct SpriteBatch batch = collect_sprite_batch(current, render_queue_len - i); /* TODO: what's even the point? just use OR_EQUAL comparison */ @@ -140,7 +140,7 @@ void render(void) { } -void set_camera(const t_camera *const camera) { +void set_camera(const Camera *const camera) { /* TODO: skip recaulculating if it's the same? */ camera_projection_matrix = camera_perspective(camera); camera_look_at_matrix = camera_look_at(camera); diff --git a/src/rendering/twn_rendering_c.h b/src/rendering/twn_rendering_c.h index 3782c5d..d99a4fc 100644 --- a/src/rendering/twn_rendering_c.h +++ b/src/rendering/twn_rendering_c.h @@ -2,6 +2,7 @@ #define TWN_RENDERING_C_H #include "twn_textures_c.h" +#include "twn_text_c.h" #include "twn_util.h" #include "twn_option.h" @@ -16,107 +17,107 @@ #include -extern t_matrix4 camera_projection_matrix; -extern t_matrix4 camera_look_at_matrix; +extern Matrix4 camera_projection_matrix; +extern Matrix4 camera_look_at_matrix; #define QUAD_ELEMENT_BUFFER_LENGTH (65536 / 6) -typedef GLuint vertex_buffer; +typedef GLuint VertexBuffer; -typedef struct vertex_buffer_builder { +typedef struct VertexBufferBuilder { size_t bytes_left; void *mapping; -} vertex_buffer_builder; +} VertexBufferBuilder; -struct sprite_primitive { - t_frect rect; - t_color color; +typedef struct SpritePrimitive { + Rect rect; + Color color; float rotation; - t_texture_key texture_key; + TextureKey texture_key; bool flip_x; bool flip_y; bool repeat; m_option_list( - t_frect, texture_region ) -}; + Rect, texture_region ) +} SpritePrimitive; -struct rect_primitive { - t_frect rect; - t_color color; -}; +typedef struct RectPrimitive { + Rect rect; + Color color; +} RectPrimitive; -struct circle_primitive { +typedef struct CirclePrimitive { float radius; - t_color color; - t_fvec2 position; -}; + Color color; + Vec2 position; +} CirclePrimitive; -struct text_primitive { - t_color color; - t_fvec2 position; +typedef struct TextPrimitive { + Color color; + Vec2 position; char *text; const char *font; int height_px; -}; +} TextPrimitive; -enum primitive_2d_type { +typedef enum Primitive2DType { PRIMITIVE_2D_SPRITE, PRIMITIVE_2D_RECT, PRIMITIVE_2D_CIRCLE, PRIMITIVE_2D_TEXT, -}; +} Primitive2DType; -struct primitive_2d { - enum primitive_2d_type type; +typedef struct Primitive2D { + Primitive2DType type; union { - struct sprite_primitive sprite; - struct rect_primitive rect; - struct circle_primitive circle; - struct text_primitive text; + SpritePrimitive sprite; + RectPrimitive rect; + CirclePrimitive circle; + TextPrimitive text; }; -}; +} Primitive2D; /* union for in-place recalculation of texture coordinates */ -union uncolored_space_triangle { +union UncoloredSpaceTriangle { /* pending for sending, uvs are not final as texture atlases could update */ - struct uncolored_space_triangle_primitive { - t_fvec3 v0; - t_fvec2 uv0; /* in pixels */ - t_fvec3 v1; - t_fvec2 uv1; /* in pixels */ - t_fvec3 v2; - t_fvec2 uv2; /* in pixels */ + struct UncoloredSpaceTrianglePrimitive { + Vec3 v0; + Vec2 uv0; /* in pixels */ + Vec3 v1; + Vec2 uv1; /* in pixels */ + Vec3 v2; + Vec2 uv2; /* in pixels */ } primitive; /* TODO: have it packed? */ /* structure that is passed in opengl vertex array */ - struct uncolored_space_triangle_payload { - t_fvec3 v0; - t_fvec2 uv0; - t_fvec3 v1; - t_fvec2 uv1; - t_fvec3 v2; - t_fvec2 uv2; + struct UncoloredSpaceTrianglePayload { + Vec3 v0; + Vec2 uv0; + Vec3 v1; + Vec2 uv1; + Vec3 v2; + Vec2 uv2; } payload; }; /* batch of primitives with overlapping properties */ -struct mesh_batch { +typedef struct MeshBatch { uint8_t *primitives; -}; +} MeshBatch; -struct mesh_batch_item { - t_texture_key key; - struct mesh_batch value; -}; +typedef struct MeshBatchItem { + TextureKey key; + struct MeshBatch value; +} MeshBatchItem; -struct text_cache { - struct font_data **data; -}; +typedef struct TextCache { + struct FontData **data; +} TextCache; /* renders the background, then the primitives in all render queues */ @@ -125,47 +126,47 @@ void render(void); /* clears all render queues */ void render_queue_clear(void); -void create_circle_geometry(t_fvec2 position, - t_color color, +void create_circle_geometry(Vec2 position, + Color color, float radius, size_t num_vertices, SDL_Vertex **vertices_out, int **indices_out); -struct sprite_batch { +struct SpriteBatch { size_t size; /* how many primitives are in current batch */ - enum texture_mode mode; + TextureMode mode; bool constant_colored; /* whether colored batch is uniformly colored */ bool repeat; /* whether repeat is needed */ -} collect_sprite_batch(const struct primitive_2d primitives[], size_t len); +} collect_sprite_batch(const Primitive2D primitives[], size_t len); -void render_sprites(const struct primitive_2d primitives[], - const struct sprite_batch batch); +void render_sprites(const Primitive2D primitives[], + const struct SpriteBatch batch); -void draw_uncolored_space_traingle_batch(struct mesh_batch *batch, - t_texture_key texture_key); +void draw_uncolored_space_traingle_batch(MeshBatch *batch, + TextureKey texture_key); /* text */ -void render_text(const struct text_primitive *text); +void render_text(const TextPrimitive *text); -void text_cache_init(struct text_cache *cache); +void text_cache_init(TextCache *cache); -void text_cache_deinit(struct text_cache *cache); +void text_cache_deinit(TextCache *cache); /* vertex buffer */ -vertex_buffer create_vertex_buffer(void); +VertexBuffer create_vertex_buffer(void); -void delete_vertex_buffer(vertex_buffer buffer); +void delete_vertex_buffer(VertexBuffer buffer); -void specify_vertex_buffer(vertex_buffer buffer, void *data, size_t bytes); +void specify_vertex_buffer(VertexBuffer buffer, void *data, size_t bytes); /* uses present in 1.5 buffer mapping feature */ -vertex_buffer_builder build_vertex_buffer(vertex_buffer buffer, size_t bytes); +VertexBufferBuilder build_vertex_buffer(VertexBuffer buffer, size_t bytes); /* collects bytes for sending to the gpu until all is pushed, which is when false is returned */ -bool push_to_vertex_buffer_builder(vertex_buffer_builder *builder, +bool push_to_vertex_buffer_builder(VertexBufferBuilder *builder, void *bytes, size_t size); @@ -181,41 +182,41 @@ void set_depth_range(double low, double high); void bind_quad_element_buffer(void); -void render_circle(const struct circle_primitive *circle); +void render_circle(const CirclePrimitive *circle); -void render_rectangle(const struct rect_primitive *rectangle); +void render_rectangle(const RectPrimitive *rectangle); void use_space_pipeline(void); void use_2d_pipeline(void); -void use_texture_mode(enum texture_mode mode); +void use_texture_mode(TextureMode mode); -void finally_render_sprites(struct primitive_2d const primitives[], - struct sprite_batch batch, - vertex_buffer buffer); +void finally_render_sprites(Primitive2D const primitives[], + struct SpriteBatch batch, + VertexBuffer buffer); -size_t get_sprite_payload_size(struct sprite_batch batch); +size_t get_sprite_payload_size(struct SpriteBatch batch); -bool push_sprite_payload_to_vertex_buffer_builder(struct sprite_batch batch, - vertex_buffer_builder *builder, - t_fvec2 v0, t_fvec2 v1, t_fvec2 v2, t_fvec2 v3, - t_fvec2 uv0, t_fvec2 uv1, t_fvec2 uv2, t_fvec2 uv3, - t_color color); +bool push_sprite_payload_to_vertex_buffer_builder(struct SpriteBatch batch, + VertexBufferBuilder *builder, + Vec2 v0, Vec2 v1, Vec2 v2, Vec2 v3, + Vec2 uv0, Vec2 uv1, Vec2 uv2, Vec2 uv3, + Color color); -void finally_draw_uncolored_space_traingle_batch(struct mesh_batch const *batch, - t_texture_key texture_key, - vertex_buffer buffer); +void finally_draw_uncolored_space_traingle_batch(MeshBatch const *batch, + TextureKey texture_key, + VertexBuffer buffer); size_t get_text_payload_size(void); -bool push_text_payload_to_vertex_buffer_builder(struct font_data const *font_data, - vertex_buffer_builder *builder, +bool push_text_payload_to_vertex_buffer_builder(FontData const *font_data, + VertexBufferBuilder *builder, stbtt_aligned_quad quad); -void finally_draw_text(struct font_data const *font_data, +void finally_draw_text(FontData const *font_data, size_t len, - t_color color, - vertex_buffer buffer); + Color color, + VertexBuffer buffer); #endif diff --git a/src/rendering/twn_sprites.c b/src/rendering/twn_sprites.c index e31a842..890969c 100644 --- a/src/rendering/twn_sprites.c +++ b/src/rendering/twn_sprites.c @@ -17,10 +17,10 @@ */ /* TODO: it might make sense to infer alpha channel presence / meaningfulness for textures in atlas */ /* so that they are rendered with no blend / batched in a way to reduce overdraw automatically */ -void push_sprite(const t_push_sprite_args args) { - struct sprite_primitive sprite = { +void push_sprite(const PushSpriteArgs args) { + SpritePrimitive sprite = { .rect = args.rect, - .color = m_or(args, color, ((t_color) { 255, 255, 255, 255 })), + .color = m_or(args, color, ((Color) { 255, 255, 255, 255 })), .rotation = m_or(args, rotation, 0.0f), .texture_key = textures_get_key(&ctx.texture_cache, args.path), .flip_x = m_or(args, flip_x, false), @@ -29,7 +29,7 @@ void push_sprite(const t_push_sprite_args args) { m_opt_from(texture_region, args, texture_region) }; - struct primitive_2d primitive = { + Primitive2D primitive = { .type = PRIMITIVE_2D_SPRITE, .sprite = sprite, }; @@ -38,12 +38,12 @@ void push_sprite(const t_push_sprite_args args) { } -struct sprite_batch collect_sprite_batch(const struct primitive_2d primitives[], size_t len) { +struct SpriteBatch collect_sprite_batch(const Primitive2D primitives[], size_t len) { /* assumes that first primitive is already a sprite */ const uint16_t texture_key_id = primitives[0].sprite.texture_key.id; const int atlas_id = textures_get_atlas_id(&ctx.texture_cache, primitives[0].sprite.texture_key); - struct sprite_batch batch = { + struct SpriteBatch batch = { .mode = textures_get_mode(&ctx.texture_cache, primitives[0].sprite.texture_key), .constant_colored = true, .repeat = primitives[0].sprite.repeat, @@ -56,14 +56,14 @@ struct sprite_batch collect_sprite_batch(const struct primitive_2d primitives[], len = QUAD_ELEMENT_BUFFER_LENGTH; for (size_t i = 0; i < len; ++i) { - const struct primitive_2d *const current = &primitives[i]; + const Primitive2D *const current = &primitives[i]; /* don't touch things other than sprites */ if (current->type != PRIMITIVE_2D_SPRITE) break; /* only collect the same blend modes */ - const enum texture_mode mode = textures_get_mode(&ctx.texture_cache, current->sprite.texture_key); + const TextureMode mode = textures_get_mode(&ctx.texture_cache, current->sprite.texture_key); if (mode != batch.mode) break; @@ -94,32 +94,32 @@ struct sprite_batch collect_sprite_batch(const struct primitive_2d primitives[], /* assumes that orthogonal matrix setup is done already */ -void render_sprites(const struct primitive_2d primitives[], - const struct sprite_batch batch) +void render_sprites(const Primitive2D primitives[], + const struct SpriteBatch batch) { /* single vertex array is used for every batch with NULL glBufferData() trick at the end */ - static vertex_buffer vertex_array = 0; + static VertexBuffer vertex_array = 0; if (vertex_array == 0) vertex_array = create_vertex_buffer(); use_texture_mode(batch.mode); - const t_frect dims = + const Rect dims = textures_get_dims(&ctx.texture_cache, primitives->sprite.texture_key); /* vertex population over a vertex buffer builder interface */ { - vertex_buffer_builder payload = build_vertex_buffer(vertex_array, get_sprite_payload_size(batch) * batch.size); + VertexBufferBuilder payload = build_vertex_buffer(vertex_array, get_sprite_payload_size(batch) * batch.size); for (size_t i = 0; i < batch.size; ++i) { /* render opaques front to back */ const size_t cur = batch.mode == TEXTURE_MODE_GHOSTLY ? i : batch.size - i - 1; - const struct sprite_primitive sprite = primitives[cur].sprite; + const SpritePrimitive sprite = primitives[cur].sprite; - const t_frect srcrect = + const Rect srcrect = textures_get_srcrect(&ctx.texture_cache, primitives[cur].sprite.texture_key); - t_fvec2 uv0, uv1, uv2, uv3; + Vec2 uv0, uv1, uv2, uv3; if (!sprite.repeat) { const float wr = srcrect.w / dims.w; @@ -128,20 +128,20 @@ void render_sprites(const struct primitive_2d primitives[], const float yr = srcrect.y / dims.h; if (!m_is_set(sprite, texture_region)) { - uv0 = (t_fvec2){ xr + wr * sprite.flip_x, yr + hr * sprite.flip_y }; - uv1 = (t_fvec2){ xr + wr * sprite.flip_x, yr + hr * !sprite.flip_y }; - uv2 = (t_fvec2){ xr + wr * !sprite.flip_x, yr + hr * !sprite.flip_y }; - uv3 = (t_fvec2){ xr + wr * !sprite.flip_x, yr + hr * sprite.flip_y }; + uv0 = (Vec2){ xr + wr * sprite.flip_x, yr + hr * sprite.flip_y }; + uv1 = (Vec2){ xr + wr * sprite.flip_x, yr + hr * !sprite.flip_y }; + uv2 = (Vec2){ xr + wr * !sprite.flip_x, yr + hr * !sprite.flip_y }; + uv3 = (Vec2){ xr + wr * !sprite.flip_x, yr + hr * sprite.flip_y }; } else { const float offx = (sprite.texture_region_opt.x / srcrect.w) * (srcrect.w / dims.w); const float offy = (sprite.texture_region_opt.y / srcrect.h) * (srcrect.h / dims.h); const float offw = (1.0f - (sprite.texture_region_opt.w / srcrect.w)) * (srcrect.w / dims.w); const float offh = (1.0f - (sprite.texture_region_opt.h / srcrect.h)) * (srcrect.h / dims.h); - uv0 = (t_fvec2){ xr + offx + wr * sprite.flip_x, yr + offy + hr * sprite.flip_y }; - uv1 = (t_fvec2){ xr + offx + wr * sprite.flip_x, yr - offh + hr * !sprite.flip_y }; - uv2 = (t_fvec2){ xr - offw + wr * !sprite.flip_x, yr - offh + hr * !sprite.flip_y }; - uv3 = (t_fvec2){ xr - offw + wr * !sprite.flip_x, yr + offy + hr * sprite.flip_y }; + uv0 = (Vec2){ xr + offx + wr * sprite.flip_x, yr + offy + hr * sprite.flip_y }; + uv1 = (Vec2){ xr + offx + wr * sprite.flip_x, yr - offh + hr * !sprite.flip_y }; + uv2 = (Vec2){ xr - offw + wr * !sprite.flip_x, yr - offh + hr * !sprite.flip_y }; + uv3 = (Vec2){ xr - offw + wr * !sprite.flip_x, yr + offy + hr * sprite.flip_y }; } } else { /* try fitting texture into supplied destination rectangle */ @@ -149,10 +149,10 @@ void render_sprites(const struct primitive_2d primitives[], const float rx = sprite.rect.w / srcrect.w; const float ry = sprite.rect.h / srcrect.h; - uv0 = (t_fvec2){ rx * sprite.flip_x, ry * sprite.flip_y }; - uv1 = (t_fvec2){ rx * sprite.flip_x, ry * !sprite.flip_y }; - uv2 = (t_fvec2){ rx * !sprite.flip_x, ry * !sprite.flip_y }; - uv3 = (t_fvec2){ rx * !sprite.flip_x, ry * sprite.flip_y }; + uv0 = (Vec2){ rx * sprite.flip_x, ry * sprite.flip_y }; + uv1 = (Vec2){ rx * sprite.flip_x, ry * !sprite.flip_y }; + uv2 = (Vec2){ rx * !sprite.flip_x, ry * !sprite.flip_y }; + uv3 = (Vec2){ rx * !sprite.flip_x, ry * sprite.flip_y }; if (m_is_set(sprite, texture_region)) { /* displace origin */ @@ -165,44 +165,44 @@ void render_sprites(const struct primitive_2d primitives[], } } - t_fvec2 v0, v1, v2, v3; + Vec2 v0, v1, v2, v3; /* todo: fast PI/2 degree divisible rotations? */ if (sprite.rotation == 0.0f) { /* non-rotated case */ - v0 = (t_fvec2){ sprite.rect.x, sprite.rect.y }; - v1 = (t_fvec2){ sprite.rect.x, sprite.rect.y + sprite.rect.h }; - v2 = (t_fvec2){ sprite.rect.x + sprite.rect.w, sprite.rect.y + sprite.rect.h }; - v3 = (t_fvec2){ sprite.rect.x + sprite.rect.w, sprite.rect.y }; + v0 = (Vec2){ sprite.rect.x, sprite.rect.y }; + v1 = (Vec2){ sprite.rect.x, sprite.rect.y + sprite.rect.h }; + v2 = (Vec2){ sprite.rect.x + sprite.rect.w, sprite.rect.y + sprite.rect.h }; + v3 = (Vec2){ sprite.rect.x + sprite.rect.w, sprite.rect.y }; } else if (sprite.rect.w == sprite.rect.h) { /* rotated square case */ - const t_fvec2 c = frect_center(sprite.rect); - const t_fvec2 t = fast_cossine(sprite.rotation + (float)M_PI_4); - const t_fvec2 d = { + const Vec2 c = frect_center(sprite.rect); + const Vec2 t = fast_cossine(sprite.rotation + (float)M_PI_4); + const Vec2 d = { .x = t.x * sprite.rect.w * (float)M_SQRT1_2, .y = t.y * sprite.rect.h * (float)M_SQRT1_2, }; - v0 = (t_fvec2){ c.x - d.x, c.y - d.y }; - v1 = (t_fvec2){ c.x - d.y, c.y + d.x }; - v2 = (t_fvec2){ c.x + d.x, c.y + d.y }; - v3 = (t_fvec2){ c.x + d.y, c.y - d.x }; + v0 = (Vec2){ c.x - d.x, c.y - d.y }; + v1 = (Vec2){ c.x - d.y, c.y + d.x }; + v2 = (Vec2){ c.x + d.x, c.y + d.y }; + v3 = (Vec2){ c.x + d.y, c.y - d.x }; } else { /* rotated non-square case*/ - const t_fvec2 c = frect_center(sprite.rect); - const t_fvec2 t = fast_cossine(sprite.rotation); + const Vec2 c = frect_center(sprite.rect); + const Vec2 t = fast_cossine(sprite.rotation); - const t_fvec2 h = { sprite.rect.w / 2, sprite.rect.h / 2 }; + const Vec2 h = { sprite.rect.w / 2, sprite.rect.h / 2 }; - v0 = (t_fvec2){ c.x + t.x * -h.x - t.y * -h.y, c.y + t.y * -h.x + t.x * -h.y }; - v1 = (t_fvec2){ c.x + t.x * -h.x - t.y * +h.y, c.y + t.y * -h.x + t.x * +h.y }; - v2 = (t_fvec2){ c.x + t.x * +h.x - t.y * +h.y, c.y + t.y * +h.x + t.x * +h.y }; - v3 = (t_fvec2){ c.x + t.x * +h.x - t.y * -h.y, c.y + t.y * +h.x + t.x * -h.y }; + v0 = (Vec2){ c.x + t.x * -h.x - t.y * -h.y, c.y + t.y * -h.x + t.x * -h.y }; + v1 = (Vec2){ c.x + t.x * -h.x - t.y * +h.y, c.y + t.y * -h.x + t.x * +h.y }; + v2 = (Vec2){ c.x + t.x * +h.x - t.y * +h.y, c.y + t.y * +h.x + t.x * +h.y }; + v3 = (Vec2){ c.x + t.x * +h.x - t.y * -h.y, c.y + t.y * +h.x + t.x * -h.y }; } push_sprite_payload_to_vertex_buffer_builder(batch, &payload, v0, v1, v2, v3, uv0, uv1, uv2, uv3, sprite.color); diff --git a/src/rendering/twn_text.c b/src/rendering/twn_text.c index af83872..59f99ae 100644 --- a/src/rendering/twn_text.c +++ b/src/rendering/twn_text.c @@ -12,26 +12,8 @@ #define NUM_DISPLAY_ASCII ((ASCII_END - ASCII_START) + 1) -struct font_data { - stbtt_packedchar char_data[NUM_DISPLAY_ASCII]; - stbtt_fontinfo info; - - const char *file_path; - unsigned char *file_bytes; - size_t file_bytes_len; - - gpu_texture texture; - - int height_px; - float scale_factor; - int ascent; - int descent; - int line_gap; -}; - - -static struct font_data *text_load_font_data(const char *path, int height_px) { - struct font_data *font_data = ccalloc(1, sizeof *font_data); +static FontData *text_load_font_data(const char *path, int height_px) { + FontData *font_data = ccalloc(1, sizeof *font_data); font_data->file_path = path; font_data->height_px = height_px; @@ -77,21 +59,21 @@ static struct font_data *text_load_font_data(const char *path, int height_px) { } -static void text_destroy_font_data(struct font_data *font_data) { +static void text_destroy_font_data(FontData *font_data) { free(font_data->file_bytes); delete_gpu_texture(font_data->texture); free(font_data); } -static void text_draw_with(struct font_data* font_data, char* text, t_fvec2 position, t_color color) { - static vertex_buffer vertex_array = 0; +static void text_draw_with(FontData* font_data, char* text, Vec2 position, Color color) { + VertexBuffer vertex_array = 0; if (vertex_array == 0) vertex_array = create_vertex_buffer(); const size_t len = SDL_strlen(text); - vertex_buffer_builder payload = build_vertex_buffer(vertex_array, get_text_payload_size() * len); + VertexBufferBuilder payload = build_vertex_buffer(vertex_array, get_text_payload_size() * len); for (size_t i = 0; i < len; ++i) { const char c = text[i]; @@ -131,21 +113,21 @@ static void ensure_font_cache(const char *font_path, int height_px) { /* HACK: stupid, bad, don't do this */ bool is_cached = false; for (size_t i = 0; i < arrlenu(ctx.text_cache.data); ++i) { - struct font_data *font_data = ctx.text_cache.data[i]; + FontData *font_data = ctx.text_cache.data[i]; if ((strcmp(font_path, font_data->file_path) == 0) && height_px == font_data->height_px) { is_cached = true; break; } } if (!is_cached) { - struct font_data *new_font_data = text_load_font_data(font_path, height_px); + FontData *new_font_data = text_load_font_data(font_path, height_px); arrput(ctx.text_cache.data, new_font_data); } } -static struct font_data *get_font_data(const char *font_path, int height_px) { - struct font_data *font_data = NULL; +static FontData *get_font_data(const char *font_path, int height_px) { + FontData *font_data = NULL; for (size_t i = 0; i < arrlenu(ctx.text_cache.data); ++i) { font_data = ctx.text_cache.data[i]; if ((strcmp(font_path, font_data->file_path) == 0) && height_px == font_data->height_px) { @@ -156,18 +138,18 @@ static struct font_data *get_font_data(const char *font_path, int height_px) { } -void render_text(const struct text_primitive *text) { - struct font_data *font_data = get_font_data(text->font, text->height_px); +void render_text(const TextPrimitive *text) { + FontData *font_data = get_font_data(text->font, text->height_px); text_draw_with(font_data, text->text, text->position, text->color); } -void text_cache_init(struct text_cache *cache) { +void text_cache_init(TextCache *cache) { arrsetlen(cache->data, 0); } -void text_cache_deinit(struct text_cache *cache) { +void text_cache_deinit(TextCache *cache) { for (size_t i = 0; i < arrlenu(ctx.text_cache.data); ++i) { text_destroy_font_data(ctx.text_cache.data[i]); } @@ -176,7 +158,7 @@ void text_cache_deinit(struct text_cache *cache) { } -void push_text(char *string, t_fvec2 position, int height_px, t_color color, const char *font_path) { +void push_text(char *string, Vec2 position, int height_px, Color color, const char *font_path) { ensure_font_cache(font_path, height_px); /* the string might not be around by the time it's used, so copy it */ @@ -185,7 +167,7 @@ void push_text(char *string, t_fvec2 position, int height_px, t_color color, con char *dup_string = cmalloc(strlen(string) + 1); strcpy(dup_string, string); - struct text_primitive text = { + TextPrimitive text = { .color = color, .position = position, .text = dup_string, @@ -193,7 +175,7 @@ void push_text(char *string, t_fvec2 position, int height_px, t_color color, con .height_px = height_px, }; - struct primitive_2d primitive = { + Primitive2D primitive = { .type = PRIMITIVE_2D_TEXT, .text = text, }; @@ -204,7 +186,7 @@ void push_text(char *string, t_fvec2 position, int height_px, t_color color, con int get_text_width(char *string, int height_px, const char *font_path) { ensure_font_cache(font_path, height_px); - struct font_data *font_data = get_font_data(font_path, height_px); + FontData *font_data = get_font_data(font_path, height_px); int length = 0; for (const char *p = string; *p != '\0'; ++p) { diff --git a/src/rendering/twn_text_c.h b/src/rendering/twn_text_c.h index d1940df..16e53c3 100644 --- a/src/rendering/twn_text_c.h +++ b/src/rendering/twn_text_c.h @@ -1,3 +1,10 @@ +#ifndef TWN_TEXT_C_H +#define TWN_TEXT_C_H + + +#include "twn_gpu_texture_c.h" + + #include @@ -6,7 +13,7 @@ #define NUM_DISPLAY_ASCII ((ASCII_END - ASCII_START) + 1) -struct font_data { +typedef struct FontData { stbtt_packedchar char_data[NUM_DISPLAY_ASCII]; stbtt_fontinfo info; @@ -14,11 +21,14 @@ struct font_data { unsigned char *file_bytes; size_t file_bytes_len; - gpu_texture texture; + GPUTexture texture; int height_px; float scale_factor; int ascent; int descent; int line_gap; -}; +} FontData; + + +#endif diff --git a/src/rendering/twn_triangles.c b/src/rendering/twn_triangles.c index f47d59c..aa98cef 100644 --- a/src/rendering/twn_triangles.c +++ b/src/rendering/twn_triangles.c @@ -9,42 +9,42 @@ /* TODO: automatic handling of repeating textures */ /* for that we could allocate a loner texture */ void unfurl_triangle(const char *path, - t_fvec3 v0, - t_fvec3 v1, - t_fvec3 v2, - t_shvec2 uv0, - t_shvec2 uv1, - t_shvec2 uv2) + Vec3 v0, + Vec3 v1, + Vec3 v2, + Vec2sh uv0, + Vec2sh uv1, + Vec2sh uv2) { - const t_texture_key texture_key = textures_get_key(&ctx.texture_cache, path); + const TextureKey texture_key = textures_get_key(&ctx.texture_cache, path); - struct mesh_batch_item *batch_p = hmgetp_null(ctx.uncolored_mesh_batches, texture_key); + struct MeshBatchItem *batch_p = hmgetp_null(ctx.uncolored_mesh_batches, texture_key); if (!batch_p) { - struct mesh_batch item = {0}; + struct MeshBatch item = {0}; hmput(ctx.uncolored_mesh_batches, texture_key, item); batch_p = &ctx.uncolored_mesh_batches[hmlenu(ctx.uncolored_mesh_batches) - 1]; /* TODO: can last index be used? */ } - union uncolored_space_triangle triangle = { .primitive = { + union UncoloredSpaceTriangle triangle = { .primitive = { .v0 = v0, .v1 = v1, .v2 = v2, - .uv1 = m_to_fvec2(uv1), - .uv0 = m_to_fvec2(uv0), - .uv2 = m_to_fvec2(uv2), + .uv1 = m_vec2_from(uv1), + .uv0 = m_vec2_from(uv0), + .uv2 = m_vec2_from(uv2), }}; - union uncolored_space_triangle *triangles = (union uncolored_space_triangle *)batch_p->value.primitives; + union UncoloredSpaceTriangle *triangles = (union UncoloredSpaceTriangle *)batch_p->value.primitives; arrpush(triangles, triangle); batch_p->value.primitives = (uint8_t *)triangles; } -void draw_uncolored_space_traingle_batch(struct mesh_batch *batch, - t_texture_key texture_key) +void draw_uncolored_space_traingle_batch(struct MeshBatch *batch, + TextureKey texture_key) { - static vertex_buffer vertex_array = 0; + static VertexBuffer vertex_array = 0; if (vertex_array == 0) vertex_array = create_vertex_buffer(); @@ -54,8 +54,8 @@ void draw_uncolored_space_traingle_batch(struct mesh_batch *batch, if (primitives_len == 0) return; - const t_frect srcrect = textures_get_srcrect(&ctx.texture_cache, texture_key); - const t_frect dims = textures_get_dims(&ctx.texture_cache, texture_key); + const Rect srcrect = textures_get_srcrect(&ctx.texture_cache, texture_key); + const Rect dims = textures_get_dims(&ctx.texture_cache, texture_key); const float wr = srcrect.w / dims.w; const float hr = srcrect.h / dims.h; @@ -64,8 +64,8 @@ void draw_uncolored_space_traingle_batch(struct mesh_batch *batch, /* update pixel-based uvs to correspond with texture atlases */ for (size_t i = 0; i < primitives_len; ++i) { - struct uncolored_space_triangle_payload *payload = - &((union uncolored_space_triangle *)batch->primitives)[i].payload; + struct UncoloredSpaceTrianglePayload *payload = + &((union UncoloredSpaceTriangle *)batch->primitives)[i].payload; payload->uv0.x = xr + ((float)payload->uv0.x / srcrect.w) * wr; payload->uv0.y = yr + ((float)payload->uv0.y / srcrect.h) * hr; @@ -75,7 +75,7 @@ void draw_uncolored_space_traingle_batch(struct mesh_batch *batch, payload->uv2.y = yr + ((float)payload->uv2.y / srcrect.h) * hr; } - specify_vertex_buffer(vertex_array, batch->primitives, primitives_len * sizeof (struct uncolored_space_triangle_payload)); + specify_vertex_buffer(vertex_array, batch->primitives, primitives_len * sizeof (struct UncoloredSpaceTrianglePayload)); finally_draw_uncolored_space_traingle_batch(batch, texture_key, vertex_array); } diff --git a/src/twn_audio.c b/src/twn_audio.c index acbc02b..8e4493c 100644 --- a/src/twn_audio.c +++ b/src/twn_audio.c @@ -24,9 +24,9 @@ static const char *audio_exts[audio_file_type_count] = { /* TODO: count frames without use, free the memory when threshold is met */ /* TODO: count repeated usages for sound effect cases with rendering to ram? */ /* stores path to data hash, useful for sound effects */ -static struct audio_file_cache { +static struct AudioFileCache { char *key; - struct audio_file_cache_value { + struct AudioFileCacheValue { unsigned char *data; size_t len; } value; @@ -34,7 +34,7 @@ static struct audio_file_cache { static int64_t get_audio_data(const char *path, unsigned char **data) { - const struct audio_file_cache *cache = shgetp_null(audio_file_cache, path); + const struct AudioFileCache *cache = shgetp_null(audio_file_cache, path); if (!cache) { unsigned char *file; int64_t len = file_to_bytes(path, &file); @@ -43,7 +43,7 @@ static int64_t get_audio_data(const char *path, unsigned char **data) { return -1; } - const struct audio_file_cache_value value = { file, (size_t)len }; + const struct AudioFileCacheValue value = { file, (size_t)len }; shput(audio_file_cache, path, value); *data = file; @@ -55,16 +55,16 @@ static int64_t get_audio_data(const char *path, unsigned char **data) { } -void play_audio(const char *path, const char *channel) { - const struct audio_channel_item *pair = shgetp_null(ctx.audio_channels, channel); +void audio_play(const char *path, const char *channel) { + const AudioChannelItem *pair = shgetp_null(ctx.audio_channels, channel); if (!pair) - play_audio_ex(path, channel, get_default_audio_args()); + audio_play_ex(path, channel, audio_get_default_args()); else - play_audio_ex(path, channel, pair->value.args); + audio_play_ex(path, channel, pair->value.args); } -static t_audio_file_type infer_audio_file_type(const char *path) { +static AudioFileType infer_audio_file_type(const char *path) { size_t path_len = strlen(path); for (int i = 0; i < audio_file_type_count; ++i) { @@ -73,7 +73,7 @@ static t_audio_file_type infer_audio_file_type(const char *path) { continue; if (strcmp(&path[path_len - ext_length], audio_exts[i]) == 0) - return (t_audio_file_type)i; + return (AudioFileType)i; } return audio_file_type_unknown; @@ -82,7 +82,7 @@ static t_audio_file_type infer_audio_file_type(const char *path) { /* TODO: error propagation and clearing of resources on partial success? */ /* or should we expect things to simply fail? */ -static union audio_context init_audio_context(const char *path, t_audio_file_type type) { +static union AudioContext init_audio_context(const char *path, AudioFileType type) { switch (type) { case audio_file_type_ogg: { unsigned char *data; @@ -101,7 +101,7 @@ static union audio_context init_audio_context(const char *path, t_audio_file_typ stb_vorbis_info info = stb_vorbis_get_info(handle); - return (union audio_context) { + return (union AudioContext) { .vorbis = { .data = data, .handle = handle, @@ -131,21 +131,21 @@ static union audio_context init_audio_context(const char *path, t_audio_file_typ xm_set_max_loop_count(handle, 1); - return (union audio_context) { + return (union AudioContext) { .xm = { .handle = handle } }; } default: CRY("Audio error", "Unhandled audio format (in init)"); - return (union audio_context){0}; + return (union AudioContext){0}; } - return (union audio_context){0}; + return (union AudioContext){0}; } -static void repeat_audio(struct audio_channel *channel) { +static void repeat_audio(AudioChannel *channel) { switch (channel->file_type) { case audio_file_type_ogg: { stb_vorbis_seek_start(channel->context.vorbis.handle); @@ -164,13 +164,13 @@ static void repeat_audio(struct audio_channel *channel) { } -void play_audio_ex(const char *path, const char *channel, t_play_audio_args args) { - struct audio_channel_item *pair = shgetp_null(ctx.audio_channels, channel); +void audio_play_ex(const char *path, const char *channel, PlayAudioArgs args) { + AudioChannelItem *pair = shgetp_null(ctx.audio_channels, channel); /* create a channel if it doesn't exist */ if (!pair) { - t_audio_file_type file_type = infer_audio_file_type(path); - struct audio_channel new_channel = { + AudioFileType file_type = infer_audio_file_type(path); + AudioChannel new_channel = { .args = args, .file_type = file_type, .context = init_audio_context(path, file_type), @@ -189,8 +189,8 @@ void play_audio_ex(const char *path, const char *channel, t_play_audio_args args } -t_play_audio_args *get_audio_args(const char *channel) { - struct audio_channel_item *pair = shgetp_null(ctx.audio_channels, channel); +PlayAudioArgs *audio_get_args(const char *channel) { + AudioChannelItem *pair = shgetp_null(ctx.audio_channels, channel); if (!pair) return NULL; @@ -198,8 +198,8 @@ t_play_audio_args *get_audio_args(const char *channel) { } -t_play_audio_args get_default_audio_args(void) { - return (t_play_audio_args){ +PlayAudioArgs audio_get_default_args(void) { + return (PlayAudioArgs){ .repeat = false, .crossfade = false, .volume = 1.0f, @@ -209,7 +209,7 @@ t_play_audio_args get_default_audio_args(void) { /* this assumes int16_t based streams */ -static void audio_mixin_streams(const struct audio_channel *channel, +static void audio_mixin_streams(const AudioChannel *channel, uint8_t *restrict a, uint8_t *restrict b, size_t frames) @@ -236,7 +236,7 @@ static void audio_mixin_streams(const struct audio_channel *channel, /* remember: sample is data for all channels where frame is a part of it */ -static void audio_sample_and_mixin_channel(const struct audio_channel *channel, +static void audio_sample_and_mixin_channel(const AudioChannel *channel, uint8_t *stream, int len) { @@ -323,7 +323,7 @@ static void audio_sample_and_mixin_channel(const struct audio_channel *channel, } -static void sanity_check_channel(const struct audio_channel *channel) { +static void sanity_check_channel(const AudioChannel *channel) { if (channel->args.volume < 0.0f || channel->args.volume > 1.0f) log_warn("Volume argument is out of range for channel (%s)", channel->name); diff --git a/src/twn_audio_c.h b/src/twn_audio_c.h index af9012f..4ab3bde 100644 --- a/src/twn_audio_c.h +++ b/src/twn_audio_c.h @@ -13,15 +13,15 @@ #include -typedef enum audio_file_type { +typedef enum AudioFileType { audio_file_type_ogg, audio_file_type_xm, audio_file_type_count, audio_file_type_unknown, -} t_audio_file_type; +} AudioFileType; -union audio_context { +union AudioContext { struct { stb_vorbis *handle; unsigned char *data; @@ -35,19 +35,19 @@ union audio_context { }; -struct audio_channel { - t_play_audio_args args; - enum audio_file_type file_type; - union audio_context context; /* interpreted by `file_type` value */ +typedef struct AudioChannel { + PlayAudioArgs args; + AudioFileType file_type; + union AudioContext context; /* interpreted by `file_type` value */ const char *path; const char *name; -}; +} AudioChannel; -struct audio_channel_item { +typedef struct AudioChannelItem { char *key; - struct audio_channel value; -}; + struct AudioChannel value; +} AudioChannelItem; void audio_callback(void *userdata, uint8_t *stream, int len); diff --git a/src/twn_camera.c b/src/twn_camera.c index 267a503..c1eabab 100644 --- a/src/twn_camera.c +++ b/src/twn_camera.c @@ -8,12 +8,12 @@ #define CAMERA_FAR_Z 100.0f -t_matrix4 camera_look_at(const t_camera *const camera) { +Matrix4 camera_look_at(const Camera *const camera) { /* from cglm */ - const t_fvec3 r = m_vec_norm(m_vec_cross(camera->target, camera->up)); - const t_fvec3 u = m_vec_cross(r, camera->target); + const Vec3 r = m_vec_norm(m_vec_cross(camera->target, camera->up)); + const Vec3 u = m_vec_cross(r, camera->target); - t_matrix4 result; + Matrix4 result; result.row[0].x = r.x; result.row[0].y = u.x; @@ -33,9 +33,9 @@ t_matrix4 camera_look_at(const t_camera *const camera) { return result; } -t_matrix4 camera_perspective(const t_camera *const camera) { +Matrix4 camera_perspective(const Camera *const camera) { /* from cglm */ - t_matrix4 result = {0}; + Matrix4 result = {0}; const float aspect = RENDER_BASE_RATIO; diff --git a/src/twn_context.c b/src/twn_context.c index 30a9143..9792c1d 100644 --- a/src/twn_context.c +++ b/src/twn_context.c @@ -2,4 +2,4 @@ /* internally there's only one context, but it gets type casted to game and engine variants based on which header is included */ /* engine parts should never mix twn_engine_context_c.h with twn_context.h */ -t_engine_ctx ctx = {0}; +EngineContext ctx = {0}; diff --git a/src/twn_engine_context_c.h b/src/twn_engine_context_c.h index 60c9bb2..86bfb42 100644 --- a/src/twn_engine_context_c.h +++ b/src/twn_engine_context_c.h @@ -3,6 +3,7 @@ #include "twn_context.h" #include "twn_textures_c.h" +#include "twn_audio_c.h" #include "twn_engine_api.h" #include "twn_input.h" #include "rendering/twn_rendering_c.h" @@ -13,20 +14,20 @@ #include -typedef struct engine_context { +typedef struct EngineContext { /* user code facing context */ - t_ctx game; + Context game; /* the program's actual argc and argv */ int argc; char **argv; - struct primitive_2d *render_queue_2d; - struct mesh_batch_item *uncolored_mesh_batches; - struct text_cache text_cache; - struct texture_cache texture_cache; + struct Primitive2D *render_queue_2d; + MeshBatchItem *uncolored_mesh_batches; + struct TextCache text_cache; + TextureCache texture_cache; - struct audio_channel_item *audio_channels; + AudioChannelItem *audio_channels; SDL_AudioDeviceID audio_device; int audio_stream_frequency; SDL_AudioFormat audio_stream_format; @@ -46,8 +47,8 @@ typedef struct engine_context { bool resync_flag; bool was_successful; -} t_engine_ctx; +} EngineContext; -TWN_API extern t_engine_ctx ctx; +TWN_API extern EngineContext ctx; #endif diff --git a/src/twn_input.c b/src/twn_input.c index 63d1510..5efb76e 100644 --- a/src/twn_input.c +++ b/src/twn_input.c @@ -8,7 +8,7 @@ #include -static void update_action_pressed_state(struct input_state *input, struct action *action) { +static void update_action_pressed_state(InputState *input, Action *action) { for (size_t i = 0; i < SDL_arraysize(action->bindings); ++i) { switch (action->bindings[i].source) { case BUTTON_SOURCE_NOT_SET: @@ -61,21 +61,21 @@ static void update_action_pressed_state(struct input_state *input, struct action } -static void input_bind_code_to_action(struct input_state *input, +static void input_bind_code_to_action(InputState *input, char *action_name, - enum button_source source, - union button_code code) + ButtonSource source, + union ButtonCode code) { - struct action_hash_item *action_item = shgetp_null(input->action_hash, action_name); + ActionHashItem *action_item = shgetp_null(input->action_hash, action_name); if (action_item == NULL) { log_warn("(%s) Action \"%s\" does not exist.", __func__, action_name); return; } - struct action *action = &action_item->value; + Action *action = &action_item->value; /* check every binding to make sure this code isn't already bound */ for (size_t i = 0; i < SDL_arraysize(action->bindings); ++i) { - struct button *binding = &action->bindings[i]; + Button *binding = &action->bindings[i]; if (binding->source != source) break; @@ -111,30 +111,30 @@ static void input_bind_code_to_action(struct input_state *input, memmove(action->bindings, action->bindings + 1, shifted_size); } - action->bindings[action->num_bindings++] = (struct button) { + action->bindings[action->num_bindings++] = (Button) { .source = source, .code = code, }; } -static void input_unbind_code_from_action(struct input_state *input, +static void input_unbind_code_from_action(InputState *input, char *action_name, - enum button_source source, - union button_code code) + ButtonSource source, + union ButtonCode code) { - struct action_hash_item *action_item = shgetp_null(input->action_hash, action_name); + ActionHashItem *action_item = shgetp_null(input->action_hash, action_name); if (action_item == NULL) { log_warn("(%s) Action \"%s\" does not exist.", __func__, action_name); return; } - struct action *action = &action_item->value; + Action *action = &action_item->value; /* check every binding to make sure this code is bound */ size_t index = 0; bool is_bound = false; for (index = 0; index < SDL_arraysize(action->bindings); ++index) { - struct button *binding = &action->bindings[index]; + Button *binding = &action->bindings[index]; if (binding->source != source) continue; @@ -174,17 +174,17 @@ static void input_unbind_code_from_action(struct input_state *input, } -void input_state_init(struct input_state *input) { +void input_state_init(InputState *input) { sh_new_strdup(input->action_hash); } -void input_state_deinit(struct input_state *input) { +void input_state_deinit(InputState *input) { shfree(input->action_hash); } -void input_state_update(struct input_state *input) { +void input_state_update(InputState *input) { input->keyboard_state = SDL_GetKeyboardState(NULL); input->mouse_state = SDL_GetMouseState(&input->mouse_window_position.x, &input->mouse_window_position.y); @@ -193,74 +193,74 @@ void input_state_update(struct input_state *input) { &input->mouse_relative_position.y); for (size_t i = 0; i < shlenu(input->action_hash); ++i) { - struct action *action = &input->action_hash[i].value; + Action *action = &input->action_hash[i].value; update_action_pressed_state(input, action); } } -void input_bind_action_scancode(struct input_state *input, +void input_bind_action_scancode(InputState *input, char *action_name, SDL_Scancode scancode) { input_bind_code_to_action(input, action_name, BUTTON_SOURCE_KEYBOARD_PHYSICAL, - (union button_code) { .scancode = scancode }); + (union ButtonCode) { .scancode = scancode }); } -void input_unbind_action_scancode(struct input_state *input, +void input_unbind_action_scancode(InputState *input, char *action_name, SDL_Scancode scancode) { input_unbind_code_from_action(input, action_name, BUTTON_SOURCE_KEYBOARD_PHYSICAL, - (union button_code) { .scancode = scancode }); + (union ButtonCode) { .scancode = scancode }); } -void input_bind_action_mouse(struct input_state *input, +void input_bind_action_mouse(InputState *input, char *action_name, uint8_t mouse_button) { input_bind_code_to_action(input, action_name, BUTTON_SOURCE_MOUSE, - (union button_code) { .mouse_button = mouse_button}); + (union ButtonCode) { .mouse_button = mouse_button}); } -void input_unbind_action_mouse(struct input_state *input, +void input_unbind_action_mouse(InputState *input, char *action_name, uint8_t mouse_button) { input_unbind_code_from_action(input, action_name, BUTTON_SOURCE_MOUSE, - (union button_code) { .mouse_button = mouse_button}); + (union ButtonCode) { .mouse_button = mouse_button}); } -void input_add_action(struct input_state *input, char *action_name) { +void input_add_action(InputState *input, char *action_name) { if (shgeti(input->action_hash, action_name) >= 0) { log_warn("(%s) Action \"%s\" is already registered.", __func__, action_name); return; } - shput(input->action_hash, action_name, (struct action) { 0 }); + shput(input->action_hash, action_name, (Action) { 0 }); } -void input_delete_action(struct input_state *input, char *action_name) { +void input_delete_action(InputState *input, char *action_name) { if (shdel(input->action_hash, action_name) == 0) log_warn("(%s) Action \"%s\" is not registered.", __func__, action_name); } -bool input_is_action_pressed(struct input_state *input, char *action_name) { - struct action_hash_item *action = shgetp_null(input->action_hash, action_name); +bool input_is_action_pressed(InputState *input, char *action_name) { + ActionHashItem *action = shgetp_null(input->action_hash, action_name); if (action == NULL) { log_warn("(%s) Action \"%s\" does not exist.", __func__, action_name); return false; @@ -269,8 +269,8 @@ bool input_is_action_pressed(struct input_state *input, char *action_name) { } -bool input_is_action_just_pressed(struct input_state *input, char *action_name) { - struct action_hash_item *action = shgetp_null(input->action_hash, action_name); +bool input_is_action_just_pressed(InputState *input, char *action_name) { + ActionHashItem *action = shgetp_null(input->action_hash, action_name); if (action == NULL) { log_warn("(%s) Action \"%s\" does not exist.", __func__, action_name); return false; @@ -279,8 +279,8 @@ bool input_is_action_just_pressed(struct input_state *input, char *action_name) } -bool input_is_action_just_released(struct input_state *input, char *action_name) { - struct action_hash_item *action = shgetp_null(input->action_hash, action_name); +bool input_is_action_just_released(InputState *input, char *action_name) { + ActionHashItem *action = shgetp_null(input->action_hash, action_name); if (action == NULL) { log_warn("(%s) Action \"%s\" does not exist.", __func__, action_name); return false; @@ -289,30 +289,30 @@ bool input_is_action_just_released(struct input_state *input, char *action_name) } -t_fvec2 input_get_action_position(struct input_state *input, char *action_name) { - struct action_hash_item *action = shgetp_null(input->action_hash, action_name); +Vec2 input_get_action_position(InputState *input, char *action_name) { + ActionHashItem *action = shgetp_null(input->action_hash, action_name); if (action == NULL) { log_warn("(%s) Action \"%s\" does not exist.", __func__, action_name); - return (t_fvec2) { 0 }; + return (Vec2) { 0 }; } return action->value.position; } -void input_set_mouse_captured(struct input_state *input, bool enabled) { +void input_set_mouse_captured(InputState *input, bool enabled) { (void)input; /* TODO: returns -1 if not supported, but like... do we care? */ SDL_SetRelativeMouseMode(enabled); } -bool input_is_mouse_captured(struct input_state *input) { +bool input_is_mouse_captured(InputState *input) { (void)input; return SDL_GetRelativeMouseMode(); } -void input_reset_state(struct input_state *input) { +void input_reset_state(InputState *input) { stbds_shfree(input->action_hash); } diff --git a/src/twn_input_c.h b/src/twn_input_c.h index 06a6f4a..5bb81de 100644 --- a/src/twn_input_c.h +++ b/src/twn_input_c.h @@ -3,6 +3,6 @@ #include "twn_input.h" -void input_reset_state(struct input_state *input); +void input_reset_state(InputState *input); #endif diff --git a/src/twn_loop.c b/src/twn_loop.c index 8d56764..824982d 100644 --- a/src/twn_loop.c +++ b/src/twn_loop.c @@ -167,7 +167,7 @@ static void main_loop(void) { poll_events(); if (ctx.game.window_size_has_changed) { - t_vec2 size; + Vec2i size; SDL_GetWindowSize(ctx.window, &size.x, &size.y); ctx.game.window_w = size.x; ctx.game.window_h = size.y; diff --git a/src/twn_textures.c b/src/twn_textures.c index 94c2873..baae49f 100644 --- a/src/twn_textures.c +++ b/src/twn_textures.c @@ -113,14 +113,14 @@ static SDL_Surface *create_surface(int width, int height) { /* adds a new, blank atlas surface to the cache */ -static void add_new_atlas(struct texture_cache *cache) { +static void add_new_atlas(TextureCache *cache) { SDL_Surface *new_atlas = create_surface(TEXTURE_ATLAS_SIZE, TEXTURE_ATLAS_SIZE); arrput(cache->atlas_surfaces, new_atlas); arrput(cache->atlas_textures, create_gpu_texture(TEXTURE_FILTER_NEAREAST, true)); } -static void upload_texture_from_surface(gpu_texture texture, SDL_Surface *surface) { +static void upload_texture_from_surface(GPUTexture texture, SDL_Surface *surface) { SDL_LockSurface(surface); upload_gpu_texture(texture, surface->pixels, surface->format->BytesPerPixel, surface->w, surface->h); @@ -129,7 +129,7 @@ static void upload_texture_from_surface(gpu_texture texture, SDL_Surface *surfac } -static void recreate_current_atlas_texture(struct texture_cache *cache) { +static void recreate_current_atlas_texture(TextureCache *cache) { /* TODO: should surfaces be freed after they cannot be referenced in atlas builing? */ /* for example, if full page of 64x64 tiles was already filled, there's no real reason to process them further */ SDL_Surface *atlas_surface = cache->atlas_surfaces[cache->atlas_index]; @@ -164,7 +164,7 @@ static void recreate_current_atlas_texture(struct texture_cache *cache) { /* uses the textures currently in the cache to create an array of stbrp_rects */ -static stbrp_rect *create_rects_from_cache(struct texture_cache *cache) { +static stbrp_rect *create_rects_from_cache(TextureCache *cache) { stbrp_rect *rects = NULL; for (size_t i = 0; i < shlenu(cache->hash); ++i) { if (cache->hash[i].value.loner_texture != 0) @@ -203,7 +203,7 @@ static stbrp_rect *filter_unpacked_rects(stbrp_rect *rects) { /* updates the original rects array with the data from packed_rects */ /* returns true if all rects were packed successfully */ -static bool update_rects(struct texture_cache *cache, stbrp_rect *rects, stbrp_rect *packed_rects) { +static bool update_rects(TextureCache *cache, stbrp_rect *rects, stbrp_rect *packed_rects) { /* !!! do not grow either of the arrays !!! */ /* the reallocation will try to reassign the array pointer, to no effect. */ /* see stb_ds.h */ @@ -229,13 +229,13 @@ static bool update_rects(struct texture_cache *cache, stbrp_rect *rects, stbrp_r /* updates the atlas location of every rect in the cache */ -static void update_texture_rects_in_atlas(struct texture_cache *cache, stbrp_rect *rects) { +static void update_texture_rects_in_atlas(TextureCache *cache, stbrp_rect *rects) { int r = 0; for (size_t i = 0; i < shlenu(cache->hash); ++i) { if (cache->hash[i].value.loner_texture != 0) continue; - cache->hash[i].value.srcrect = (t_frect) { + cache->hash[i].value.srcrect = (Rect) { .x = (float)rects[r].x, .y = (float)rects[r].y, .w = (float)rects[r].w, @@ -247,7 +247,7 @@ static void update_texture_rects_in_atlas(struct texture_cache *cache, stbrp_rec } -void textures_cache_init(struct texture_cache *cache, SDL_Window *window) { +void textures_cache_init(TextureCache *cache, SDL_Window *window) { cache->window = window; sh_new_arena(cache->hash); @@ -258,7 +258,7 @@ void textures_cache_init(struct texture_cache *cache, SDL_Window *window) { } -void textures_cache_deinit(struct texture_cache *cache) { +void textures_cache_deinit(TextureCache *cache) { /* free atlas textures */ for (size_t i = 0; i < arrlenu(cache->atlas_textures); ++i) { delete_gpu_texture(cache->atlas_textures[i]); @@ -282,7 +282,7 @@ void textures_cache_deinit(struct texture_cache *cache) { } -void textures_dump_atlases(struct texture_cache *cache) { +void textures_dump_atlases(TextureCache *cache) { PHYSFS_mkdir("/dump"); const char string_template[] = "/dump/atlas%zd.png"; @@ -307,18 +307,18 @@ void textures_dump_atlases(struct texture_cache *cache) { } -static enum texture_mode infer_texture_mode(SDL_Surface *surface) { +static enum TextureMode infer_texture_mode(SDL_Surface *surface) { const uint32_t amask = surface->format->Amask; if (amask == 0) return TEXTURE_MODE_OPAQUE; - enum texture_mode result = TEXTURE_MODE_OPAQUE; + enum TextureMode result = TEXTURE_MODE_OPAQUE; SDL_LockSurface(surface); for (int i = 0; i < surface->w * surface->h; ++i) { /* TODO: don't assume 32 bit depth ? */ - t_color color; + Color color; SDL_GetRGBA(((uint32_t *)surface->pixels)[i], surface->format, &color.r, &color.g, &color.b, &color.a); if (color.a == 0) @@ -335,14 +335,14 @@ static enum texture_mode infer_texture_mode(SDL_Surface *surface) { } -static t_texture_key textures_load(struct texture_cache *cache, const char *path) { +static TextureKey textures_load(TextureCache *cache, const char *path) { /* no need to do anything if it was loaded already */ const ptrdiff_t i = shgeti(cache->hash, path); if (i >= 0) - return (t_texture_key){ (uint16_t)i }; + return (TextureKey){ (uint16_t)i }; SDL_Surface *surface = image_to_surface(path); - struct texture new_texture = { + Texture new_texture = { .data = surface, .mode = infer_texture_mode(surface), }; @@ -357,18 +357,18 @@ static t_texture_key textures_load(struct texture_cache *cache, const char *path } new_texture.loner_texture = create_gpu_texture(TEXTURE_FILTER_NEAREAST, true); upload_texture_from_surface(new_texture.loner_texture, surface); - new_texture.srcrect = (t_frect) { .w = (float)surface->w, .h = (float)surface->h }; + new_texture.srcrect = (Rect) { .w = (float)surface->w, .h = (float)surface->h }; } else { /* will be fully populated as the atlas updates */ new_texture.atlas_index = cache->atlas_index; cache->is_dirty = true; } shput(cache->hash, path, new_texture); - return (t_texture_key){ (uint16_t)shgeti(cache->hash, path) }; + return (TextureKey){ (uint16_t)shgeti(cache->hash, path) }; } -void textures_update_atlas(struct texture_cache *cache) { +void textures_update_atlas(TextureCache *cache) { if (!cache->is_dirty) return; @@ -421,14 +421,14 @@ static const char *rodata_start; static const char *rodata_stop; static const char *last_path = NULL; -static t_texture_key last_texture; -static struct ptr_to_texture { +static TextureKey last_texture; +static struct PtrToTexture { const void *key; - t_texture_key value; + TextureKey value; } *ptr_to_texture; /* TODO: separate and reuse */ -t_texture_key textures_get_key(struct texture_cache *cache, const char *path) { +TextureKey textures_get_key(TextureCache *cache, const char *path) { if (rodata_stop == NULL) if (!infer_elf_section_bounds(".rodata", &rodata_start, &rodata_stop)) CRY("Section inference", ".rodata section lookup failed"); @@ -458,7 +458,7 @@ t_texture_key textures_get_key(struct texture_cache *cache, const char *path) { } #else -t_texture_key textures_get_key(struct texture_cache *cache, const char *path) { +TextureKey textures_get_key(TextureCache *cache, const char *path) { /* hash tables are assumed to be stable, so we just return indices */ const ptrdiff_t texture = shgeti(cache->hash, path); @@ -466,12 +466,12 @@ t_texture_key textures_get_key(struct texture_cache *cache, const char *path) { if (texture == -1) { return textures_load(cache, path); } else - return (t_texture_key){ (uint16_t)texture }; + return (TextureKey){ (uint16_t)texture }; } #endif /* generic implementation of textures_get_key() */ -int32_t textures_get_atlas_id(const struct texture_cache *cache, t_texture_key key) { +int32_t textures_get_atlas_id(const TextureCache *cache, TextureKey key) { if (m_texture_key_is_valid(key)) { if (cache->hash[key.id].value.loner_texture != 0) return -cache->hash[key.id].value.loner_texture; @@ -484,32 +484,32 @@ int32_t textures_get_atlas_id(const struct texture_cache *cache, t_texture_key k } } -t_frect textures_get_srcrect(const struct texture_cache *cache, t_texture_key key) { +Rect textures_get_srcrect(const TextureCache *cache, TextureKey key) { if (m_texture_key_is_valid(key)) { return cache->hash[key.id].value.srcrect; } else { CRY("Texture lookup failed.", "Tried to get texture that isn't loaded."); - return (t_frect){ 0, 0, 0, 0 }; + return (Rect){ 0, 0, 0, 0 }; } } -t_frect textures_get_dims(const struct texture_cache *cache, t_texture_key key) { +Rect textures_get_dims(const TextureCache *cache, TextureKey key) { if (m_texture_key_is_valid(key)) { if (cache->hash[key.id].value.loner_texture != 0) return cache->hash[key.id].value.srcrect; else - return (t_frect){ .w = TEXTURE_ATLAS_SIZE, .h = TEXTURE_ATLAS_SIZE }; + return (Rect){ .w = TEXTURE_ATLAS_SIZE, .h = TEXTURE_ATLAS_SIZE }; } else { CRY("Texture lookup failed.", "Tried to get texture that isn't loaded."); - return (t_frect){ 0, 0, 0, 0 }; + return (Rect){ 0, 0, 0, 0 }; } } -void textures_bind(const struct texture_cache *cache, t_texture_key key) { +void textures_bind(const TextureCache *cache, TextureKey key) { if (m_texture_key_is_valid(key)) { if (cache->hash[key.id].value.loner_texture == 0) bind_gpu_texture(cache->atlas_textures[cache->hash[key.id].value.atlas_index]); @@ -523,7 +523,7 @@ void textures_bind(const struct texture_cache *cache, t_texture_key key) { /* TODO: alternative schemes, such as: array texture, fragment shader and geometry division */ -void textures_bind_repeating(const struct texture_cache *cache, t_texture_key key) { +void textures_bind_repeating(const TextureCache *cache, TextureKey key) { if (m_texture_key_is_valid(key)) { if (cache->hash[key.id].value.loner_texture == 0) { @@ -533,9 +533,9 @@ void textures_bind_repeating(const struct texture_cache *cache, t_texture_key ke return; } - const struct texture texture = cache->hash[key.id].value; + const Texture texture = cache->hash[key.id].value; - const gpu_texture repeating_texture = create_gpu_texture(TEXTURE_FILTER_NEAREAST, false); + const GPUTexture repeating_texture = create_gpu_texture(TEXTURE_FILTER_NEAREAST, false); SDL_LockSurface(texture.data); @@ -561,7 +561,7 @@ void textures_bind_repeating(const struct texture_cache *cache, t_texture_key ke } -enum texture_mode textures_get_mode(const struct texture_cache *cache, t_texture_key key) { +TextureMode textures_get_mode(const TextureCache *cache, TextureKey key) { if (m_texture_key_is_valid(key)) { return cache->hash[key.id].value.mode; } else { @@ -572,14 +572,14 @@ enum texture_mode textures_get_mode(const struct texture_cache *cache, t_texture } -size_t textures_get_num_atlases(const struct texture_cache *cache) { +size_t textures_get_num_atlases(const TextureCache *cache) { return cache->atlas_index + 1; } void textures_reset_state(void) { #if defined(__linux__) && !defined(HOT_RELOAD_SUPPORT) last_path = NULL; - last_texture = (t_texture_key){0}; + last_texture = (TextureKey){0}; shfree(ptr_to_texture); #endif diff --git a/src/twn_textures_c.h b/src/twn_textures_c.h index 6dfbaeb..36867dc 100644 --- a/src/twn_textures_c.h +++ b/src/twn_textures_c.h @@ -11,47 +11,47 @@ #include -struct texture { - t_frect srcrect; /* position in atlas */ +typedef struct Texture { + Rect srcrect; /* position in atlas */ SDL_Surface *data; /* original image data */ int atlas_index; - gpu_texture loner_texture; /* stored directly for loners, == 0 means atlas_index should be used */ - gpu_texture repeating_texture; /* separately allocated texture, for loners == loner_texture */ - enum texture_mode mode; -}; + GPUTexture loner_texture; /* stored directly for loners, == 0 means atlas_index should be used */ + GPUTexture repeating_texture; /* separately allocated Texture, for loners == loner_texture */ + enum TextureMode mode; +} Texture; -struct texture_cache_item { +typedef struct TextureCacheItem { char *key; - struct texture value; -}; + struct Texture value; +} TextureCacheItem; -struct texture_cache { +typedef struct TextureCache { SDL_Window *window; /* from context */ - struct texture_cache_item *hash; + struct TextureCacheItem *hash; stbrp_node *node_buffer; /* used internally by stb_rect_pack */ SDL_Surface **atlas_surfaces; - gpu_texture *atlas_textures; /* shared by atlas textures */ + GPUTexture *atlas_textures; /* shared by atlas textures */ int atlas_index; /* atlas that is currently being built */ bool is_dirty; /* current atlas needs to be recreated */ -}; +} TextureCache; /* type safe structure for persistent texture handles */ -typedef struct { uint16_t id; } t_texture_key; +typedef struct TextureKey { uint16_t id; } TextureKey; /* tests whether given key structure corresponds to any texture */ #define m_texture_key_is_valid(p_key) ((p_key).id != (uint16_t)-1) -void textures_cache_init(struct texture_cache *cache, SDL_Window *window); -void textures_cache_deinit(struct texture_cache *cache); +void textures_cache_init(struct TextureCache *cache, SDL_Window *window); +void textures_cache_deinit(struct TextureCache *cache); /* for debugging */ -void textures_dump_atlases(struct texture_cache *cache); +void textures_dump_atlases(struct TextureCache *cache); /* loads an image if it isn't in the cache, otherwise a no-op. */ /* can be called from anywhere at any time after init, useful if you want to */ @@ -61,30 +61,30 @@ void textures_dump_atlases(struct texture_cache *cache); /* repacks the current texture atlas based on the texture cache if needed */ /* any previously returned srcrect results are invalidated after that */ /* call it every time before rendering */ -void textures_update_atlas(struct texture_cache *cache); +void textures_update_atlas(TextureCache *cache); /* returns a persistent handle to some texture in cache, loading it if needed */ /* check the result with m_texture_key_is_valid() */ -t_texture_key textures_get_key(struct texture_cache *cache, const char *path); +TextureKey textures_get_key(TextureCache *cache, const char *path); /* returns a rect in a texture cache of the given key */ -t_frect textures_get_srcrect(const struct texture_cache *cache, t_texture_key key); +Rect textures_get_srcrect(const TextureCache *cache, TextureKey key); /* returns a rect of dimensions of the whole texture (whole atlas) */ -t_frect textures_get_dims(const struct texture_cache *cache, t_texture_key key); +Rect textures_get_dims(const TextureCache *cache, TextureKey key); /* returns an identifier that is equal for all textures placed in the same atlas */ -int32_t textures_get_atlas_id(const struct texture_cache *cache, t_texture_key key); +int32_t textures_get_atlas_id(const TextureCache *cache, TextureKey key); -void textures_bind(const struct texture_cache *cache, t_texture_key key); +void textures_bind(const TextureCache *cache, TextureKey key); -void textures_bind_repeating(const struct texture_cache *cache, t_texture_key key); +void textures_bind_repeating(const TextureCache *cache, TextureKey key); /* returns helpful information about contents of alpha channel in given texture */ -enum texture_mode textures_get_mode(const struct texture_cache *cache, t_texture_key key); +TextureMode textures_get_mode(const TextureCache *cache, TextureKey key); /* returns the number of atlases in the cache */ -size_t textures_get_num_atlases(const struct texture_cache *cache); +size_t textures_get_num_atlases(const TextureCache *cache); /* TODO: should recieve texture_cache, get_key optimization cache should be cleared some other way */ void textures_reset_state(void); diff --git a/src/twn_util.c b/src/twn_util.c index da55790..20821e7 100644 --- a/src/twn_util.c +++ b/src/twn_util.c @@ -171,7 +171,7 @@ bool strends(const char *str, const char *suffix) { } -bool overlap_rect(const t_rect *a, const t_rect *b, t_rect *result) { +bool overlap_rect(const Recti *a, const Recti *b, Recti *result) { SDL_Rect a_sdl = { a->x, a->y, a->w, a->h }; SDL_Rect b_sdl = { b->x, b->y, b->w, b->h }; SDL_Rect result_sdl = { 0 }; @@ -179,13 +179,13 @@ bool overlap_rect(const t_rect *a, const t_rect *b, t_rect *result) { bool intersection = SDL_IntersectRect(&a_sdl, &b_sdl, &result_sdl); if (result != NULL) - *result = (t_rect){ result_sdl.x, result_sdl.y, result_sdl.w, result_sdl.h }; + *result = (Recti){ result_sdl.x, result_sdl.y, result_sdl.w, result_sdl.h }; return intersection; } -bool overlap_frect(const t_frect *a, const t_frect *b, t_frect *result) { +bool overlap_frect(const Rect *a, const Rect *b, Rect *result) { SDL_FRect a_sdl = { a->x, a->y, a->w, a->h }; SDL_FRect b_sdl = { b->x, b->y, b->w, b->h }; SDL_FRect result_sdl = { 0 }; @@ -193,28 +193,28 @@ bool overlap_frect(const t_frect *a, const t_frect *b, t_frect *result) { bool intersection = SDL_IntersectFRect(&a_sdl, &b_sdl, &result_sdl); if (result != NULL) - *result = (t_frect){ result_sdl.x, result_sdl.y, result_sdl.w, result_sdl.h }; + *result = (Rect){ result_sdl.x, result_sdl.y, result_sdl.w, result_sdl.h }; return intersection; } -bool intersect_rect(const t_rect *a, const t_rect *b) { +bool intersect_rect(const Recti *a, const Recti *b) { SDL_Rect a_sdl = { a->x, a->y, a->w, a->h }; SDL_Rect b_sdl = { b->x, b->y, b->w, b->h }; return SDL_HasIntersection(&a_sdl, &b_sdl); } -bool intersect_frect(const t_frect *a, const t_frect *b) { +bool intersect_frect(const Rect *a, const Rect *b) { SDL_FRect a_sdl = { a->x, a->y, a->w, a->h }; SDL_FRect b_sdl = { b->x, b->y, b->w, b->h }; return SDL_HasIntersectionF(&a_sdl, &b_sdl); } -t_frect to_frect(t_rect rect) { - return (t_frect) { +Rect to_frect(Recti rect) { + return (Rect) { .h = (float)rect.h, .w = (float)rect.w, .x = (float)rect.x, @@ -223,8 +223,8 @@ t_frect to_frect(t_rect rect) { } -t_fvec2 frect_center(t_frect rect) { - return (t_fvec2){ +Vec2 frect_center(Rect rect) { + return (Vec2){ .x = rect.x + rect.w / 2, .y = rect.y + rect.h / 2, };