Compare commits

..

2 Commits

Author SHA1 Message Date
Ulysse Cura 6ce19277e5 Added linear interpolation with time. 2026-09-01 17:29:56 +02:00
Ulysse Cura 0070779007 Even better error handling with goto. 2026-09-01 17:29:31 +02:00
9 changed files with 73 additions and 42 deletions

View File

@ -34,7 +34,7 @@ CORE_AR = ar
CORE_ARFLAGS =
# Used in final linking.
CORE_DEPS_FLAGS = $(shell pkg-config --libs sdl3)
CORE_DEPS_FLAGS = $(shell pkg-config --libs sdl3) -lm
# Deduce objects
CORE_OBJECTS = $(CORE_SOURCES:%.c=$(BUILD_DIR)/$(CORE_DIR)/%.o)

View File

@ -12,17 +12,8 @@
// Args : asset_type_t asset_type, const char *asset_name
int create_asset(asset_t *asset, va_list args)
{
asset->type = va_arg(args, asset_type_t);
const char *asset_name = va_arg(args, const char *);
asset->name = calloc(strlen(asset_name) + 1, sizeof(char));
if(!asset->name)
{
error_printf("Failed to allocate memory for asset name : %d", errno);
return EXIT_FAILURE;
}
strcpy(asset->name, asset_name);
asset->name = va_arg(args, const char *);
asset->type = ASSET_NULL;
asset->nb_refs = 0;
return EXIT_SUCCESS;
@ -30,8 +21,6 @@ int create_asset(asset_t *asset, va_list args)
int destroy_asset(asset_t *asset)
{
free(asset->name);
switch(asset->type)
{
case ASSET_TEXTURE:
@ -42,6 +31,9 @@ int destroy_asset(asset_t *asset)
if(destroy_map(asset->data)) return_failure_int;
break;
case ASSET_NULL:
break;
default:
error_printf("Asset type not valid : %d", asset->type);
return EXIT_FAILURE;
@ -154,9 +146,10 @@ asset_t *asset_manager_load_asset(char *asset_name, asset_type_t asset_type)
elem_t *asset_elem = linked_list_get_if(&game.asset_manager.assets, condition_is_asset_name, (void *)asset_name);
if(asset_elem)
{
((asset_t *)asset_elem->data)->nb_refs++;
asset_t *asset = asset_elem->data;
asset->nb_refs++;
debug_printf("Asset \"%s\" has already been loaded, nb refs : %d", ((asset_t *)asset_elem->data)->name, ((asset_t *)asset_elem->data)->nb_refs);
debug_printf("Asset \"%s\" has already been loaded, nb refs : %d", asset->name, asset->nb_refs);
}
else
{
@ -169,7 +162,7 @@ asset_t *asset_manager_load_asset(char *asset_name, asset_type_t asset_type)
}
asset_header_def_t *asset_header_def = asset_header_def_elem->data;
asset_elem = create_elem(&game.asset_manager.assets, asset_type, asset_name);
asset_elem = create_elem(&game.asset_manager.assets, asset_name);
if(!asset_elem) return_failure_ptr;
asset_t *asset = asset_elem->data;
@ -183,20 +176,24 @@ asset_t *asset_manager_load_asset(char *asset_name, asset_type_t asset_type)
{
case ASSET_TEXTURE:
asset->data = load_texture();
if(!asset->data) return_failure_ptr;
break;
case ASSET_MAP:
asset->data = load_map();
if(!asset->data) return_failure_ptr;
break;
default:
error_printf("Asset type doesn't exists : %d", asset_type);
destroy_asset(asset);
return NULL;
break;
}
if(!asset->data)
{
destroy_elem(&game.asset_manager.assets, asset_elem); // returns failure anyway
return_failure_ptr;
}
asset->type = asset_type;
asset->nb_refs++;
linked_list_push_back(&game.asset_manager.assets, asset_elem);
@ -217,7 +214,6 @@ int asset_manager_let_go_asset(char *asset_name)
}
asset_t *asset = asset_elem->data;
asset->nb_refs--;
debug_printf("Asset \"%s\" has been let go, nb refs : %d", asset->name, asset->nb_refs);

View File

@ -61,6 +61,7 @@ inline int display_init(void)
}
debug_printf("Initialized display.");
return EXIT_SUCCESS;
}

View File

@ -6,12 +6,13 @@
#include "linked_list.h"
typedef enum asset_type_t {
ASSET_NULL,
ASSET_TEXTURE,
ASSET_MAP
} asset_type_t;
typedef struct asset_t {
char *name;
const char *name;
void *data;

View File

@ -27,11 +27,18 @@
fprintf(stderr, "\tin %s:%d:%s()\n", __FILE__, __LINE__, __func__); \
return NULL; \
} while (0);
#define goto_failure \
do { \
fprintf(stderr, "\tin %s:%d:%s()\n", __FILE__, __LINE__, __func__); \
goto failure; \
} while (0);
#else
#define debug_printf(...)
#define return_failure_int return EXIT_FAILURE;
#define return_failure_ptr return NULL;
#define goto_failure goto failure;
#endif
#define warning_printf(...) \

View File

@ -130,6 +130,24 @@ void frect_to_rect(const frect_t *frect, rect_t *rect);
*/
#define intersect_frect(A, B, result) SDL_GetRectIntersectionFloat(A, B, result)
float lerp(float a, float b, float t);
/**
* @brief Lerp a to b with smoothing factor s.
*
* @param a Current value
* @param b Target value
* @param s Smoothing factor
*/
float lerp(float a, float b, float s);
/**
* @brief Lerp a to b with smoothing factor s and time basis t.
* Smoothing factor is for 60 fps call time.
*
* @param a Current value
* @param b Target value
* @param s Smoothing factor
* @param t Delta time
*/
float lerp_time(float a, float b, float s, float t);
#endif // VECTOR2D_H

View File

@ -2,6 +2,7 @@
#include <SDL3/SDL.h>
#include <stdlib.h>
#include "errors.h"
game_t game;
@ -16,19 +17,22 @@ static inline void update_time(void)
int main(void)
{
int exit_status = EXIT_SUCCESS;
if(game_init()) exit_status = EXIT_FAILURE;
if(game_init()) goto_failure;
while(game.is_running)
{
update_time();
game_handle_event();
if(game_update()) exit_status = EXIT_FAILURE;
if(game_render()) exit_status = EXIT_FAILURE;
if(game_update()) goto_failure;
if(game_render()) goto_failure;
}
if(game_exit()) exit_status = EXIT_FAILURE;
if(game_exit()) return_failure_int;
return exit_status;
return EXIT_SUCCESS;
failure:
game_exit(); // return failure anyway
return EXIT_FAILURE;
}

View File

@ -31,35 +31,34 @@ texture_t *load_texture(void)
if(!SDL_LockSurface(tmp_surface))
{
error_printf("Failed to lock temporary surface : %s", SDL_GetError());
SDL_DestroySurface(tmp_surface);
return NULL;
goto_failure;
}
if(fread(tmp_surface->pixels, sizeof(uint16_t), width * height, game.asset_manager.asset_file) != (size_t)width * (size_t)height)
{
error_printf("Failed to read asset file.");
SDL_DestroySurface(tmp_surface);
return NULL;
goto_failure;
}
if(!SDL_SetSurfaceColorKey(tmp_surface, true, TEXTURE_TRANSPARENT_COLOR))
{
error_printf("Failed to set color key of temporary surface : %s", SDL_GetError());
SDL_DestroySurface(tmp_surface);
return NULL;
goto_failure;
}
texture_t *texture = SDL_CreateTextureFromSurface(game.display.renderer, tmp_surface);
if(!texture)
{
error_printf("Failed to create texture from temporary surface : %s", SDL_GetError());
SDL_DestroySurface(tmp_surface);
return NULL;
goto_failure;
}
SDL_DestroySurface(tmp_surface);
return texture;
failure:
SDL_DestroySurface(tmp_surface);
return NULL;
}
void destroy_texture(texture_t *texture)

View File

@ -16,7 +16,12 @@ void frect_to_rect(const frect_t *frect, rect_t *rect)
rect->h = (int)frect->h;
}
float lerp(float a, float b, float t)
inline float lerp(float a, float b, float s)
{
return a * (1 - t) + b * t;
return a * (1 - s) + b * s;
}
inline float lerp_time(float a, float b, float s, float t)
{
return lerp(a, b, 1 - powf(1 - s, t * 60.0f));
}