Asset manager can load and display images.

This commit is contained in:
Ulysse Cura 2026-07-22 02:43:43 +02:00
parent 40ce153123
commit 58f16dfcae
6 changed files with 163 additions and 29 deletions

View File

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

View File

@ -1,9 +1,12 @@
#include "asset_manager.h"
#include <SDL2/SDL_render.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include "linked_list.h"
#include "memory_alloc.h"
#include "display.h"
asset_t *create_asset(asset_type_t asset_type)
{
@ -21,25 +24,73 @@ void destroy_asset(asset_t *asset)
switch(asset->type)
{
case TEXTURE:
case ASSET_TEXTURE:
SDL_DestroyTexture(asset->data.texture);
default:
return;
break;
}
free(asset);
}
void destroy_asset_header_def(asset_header_def_t *asset_header_def)
{
free(asset_header_def->name);
free(asset_header_def);
}
void asset_manager_init(asset_manager_t *asset_manager)
{
linked_list_init(&asset_manager->assets, sizeof(asset_t), (deleter_t)destroy_asset);
linked_list_init(&asset_manager->assets_header_defs, sizeof(asset_header_def_t), (deleter_t)destroy_asset_header_def);
asset_manager->asset_file = fopen(ASSET_FILE_NAME, "rb");
if(!asset_manager->asset_file)
{
printf("can't open asset file : %s.\n", ASSET_FILE_NAME);
return;
}
size_t nb_assets;
size_t ret = fread(&nb_assets, sizeof(nb_assets), 1, asset_manager->asset_file);
if(ret != 1)
{
printf("can't read asset file.");
return;
}
for(size_t i = 0; i < nb_assets; i++)
{
elem_t *elem = elem_create(&asset_manager->assets_header_defs);
size_t cap = 0;
ret = getdelim(&((asset_header_def_t *)elem->data)->name, &cap, '\0', asset_manager->asset_file);
if(ret == SIZE_MAX)
{
printf("can't read asset file.");
return;
}
ret = fread(&((asset_header_def_t *)elem->data)->start, sizeof(((asset_header_def_t *)elem->data)->start), 1, asset_manager->asset_file);
if(ret != 1)
{
printf("can't read asset file.");
return;
}
linked_list_push_back_elem(&asset_manager->assets_header_defs, elem);
}
}
void asset_manager_exit(asset_manager_t *asset_manager)
{
linked_list_clear(&asset_manager->assets_header_defs);
linked_list_clear(&asset_manager->assets);
fclose(asset_manager->asset_file);
}
// Only for this file
// No args
static inline bool condition_is_asset_unused(elem_t *elem, va_list args __attribute__((unused)))
@ -59,6 +110,56 @@ static inline bool condition_is_asset_name(elem_t *elem, va_list args)
return !strcmp(((asset_t *)elem->data)->name, va_arg(args, const char *));
}
//Only for this file
// Arg : const char *asset_name
static inline bool condition_is_asset_header_def_name(elem_t *elem, va_list args)
{
return !strcmp(((asset_header_def_t *)elem->data)->name, va_arg(args, const char *));
}
static inline void load_texture(asset_manager_t *asset_manager, asset_t *asset, asset_header_def_t *asset_header_def)
{
if(fseek(asset_manager->asset_file, asset_header_def->start, SEEK_SET))
{
printf("Couldn't seek in asset file.");
return;
}
size_t width, height;
if(fread(&width, sizeof(width), 1, asset_manager->asset_file) != 1)
{
printf("Failed to read in asset file.");
return;
}
if(fread(&height, sizeof(height), 1, asset_manager->asset_file) != 1)
{
printf("Failed to read in asset file.");
return;
}
SDL_Surface *tmp_surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 16, SDL_PIXELFORMAT_RGB565);
if(SDL_LockSurface(tmp_surface))
{
printf("Couldn't lock surface : %s\n", SDL_GetError());
return;
}
if(fread(tmp_surface->pixels, sizeof(uint16_t), width * height, asset_manager->asset_file) != width * height)
{
printf("Failed to read asset file.");
return;
}
SDL_SetColorKey(tmp_surface, SDL_TRUE, SDL_MapRGB(tmp_surface->format, 0xFF, 0x00, 0xFF));
asset->data.texture = SDL_CreateTextureFromSurface(renderer, tmp_surface);
SDL_FreeSurface(tmp_surface);
}
void asset_manager_load_asset(asset_manager_t *asset_manager, const char *asset_name, asset_type_t asset_type)
{
asset_t *asset = linked_list_get_if(&asset_manager->assets, condition_is_asset_name, asset_name);
@ -68,11 +169,27 @@ void asset_manager_load_asset(asset_manager_t *asset_manager, const char *asset_
return;
}
asset_header_def_t *asset_header_def = linked_list_get_if(&asset_manager->assets_header_defs, condition_is_asset_header_def_name, asset_name);
if(!asset_header_def)
{
printf("Asset doesn't exist in asset file : %s\n", asset_name);
return;
}
asset = create_asset(asset_type);
asset->name = malloc(strlen(asset_name) + 1);
strcpy(asset->name, asset_name);
asset->type = asset_type;
// XXX LOAD ASSET FROM FILE XXX
switch(asset_type)
{
case ASSET_TEXTURE:
load_texture(asset_manager, asset, asset_header_def);
break;
default:
return;
}
linked_list_push_back(&asset_manager->assets, asset);
}
@ -88,8 +205,17 @@ void asset_manager_let_go_asset(asset_manager_t *asset_manager, const char *asse
texture_t *asset_manager_get_texture(asset_manager_t *asset_manager, const char *asset_name)
{
asset_t *asset = linked_list_get_if(&asset_manager->assets, condition_is_asset_name, asset_name);
if(!asset)
return NULL;
if(asset->type != ASSET_TEXTURE)
return NULL;
return asset->data.texture;
}
void asset_manager_draw_texture(texture_t *texture, rect_t *src_rect, rect_t *dst_rect, bool flip)
void asset_manager_draw_texture(texture_t *texture, rect_t *src_rect, rect_t *dst_rect, bool flip __attribute__((unused)))
{
SDL_RenderCopy(renderer, texture, src_rect, dst_rect);
}

View File

@ -1,18 +1,32 @@
#include "display.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
void display_init(void)
{
SDL_Init(SDL_INIT_EVERYTHING);
IMG_Init(IMG_INIT_PNG);
if(SDL_Init(SDL_INIT_EVERYTHING))
{
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
return;
}
window = SDL_CreateWindow("2D_Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, DISPLAY_WIDTH * RENDER_SCALE, DISPLAY_HEIGHT * RENDER_SCALE, SDL_WINDOW_SHOWN);
if(!window)
{
printf("Couldn't create window : %s\n", SDL_GetError());
return;
}
window = SDL_CreateWindow("2D_Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, DISPLAY_WIDTH * DISPLAY_SCALE, DISPLAY_HEIGHT * DISPLAY_SCALE, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if(!renderer)
{
printf("Couldn't create renderer : %s\n", SDL_GetError());
return;
}
}
void display_update(void)
@ -26,11 +40,6 @@ void display_clear(void)
SDL_RenderClear(renderer);
}
void display_subimage(image_t *image, const rect_t *dst_rect, const rect_t *src_rect, bool flip __attribute__((unused)))
{
SDL_RenderCopy(renderer, image, src_rect, dst_rect);
}
void display_exit(void)
{
SDL_DestroyRenderer(renderer);

View File

@ -3,13 +3,14 @@
#include <SDL2/SDL_render.h>
#include <stdbool.h>
#include <stdio.h>
#include "linked_list.h"
#include "vector2d.h"
typedef SDL_Texture texture_t;
typedef enum asset_type_t {
TEXTURE
ASSET_TEXTURE
} asset_type_t;
typedef struct asset_t {
@ -19,17 +20,26 @@ typedef struct asset_t {
texture_t *texture;
} data;
asset_type_t type;
size_t nb_refs;
asset_type_t type;
} asset_t;
asset_t *create_asset(asset_type_t asset_type);
void destroy_asset(asset_t *asset);
typedef struct asset_header_def_t {
char *name;
size_t start;
} asset_header_def_t;
void destroy_asset_header_def(asset_header_def_t *asset_header_def);
typedef struct asset_manager_t {
linked_list_t assets_header_defs;
linked_list_t assets;
FILE *asset_file;
} asset_manager_t;
void asset_manager_init(asset_manager_t *asset_manager);

View File

@ -2,14 +2,13 @@
#define DISPLAY_H
#include <SDL2/SDL_render.h>
#include "image.h"
#include "vector2d.h"
#define C_BLACK 0, 0, 0, 255
#define DISPLAY_WIDTH 396
#define DISPLAY_HEIGHT 224
#define DISPLAY_SCALE 2
#define RENDER_SCALE 2
extern SDL_Window *window;
extern SDL_Renderer *renderer;
@ -20,8 +19,6 @@ void display_update(void);
void display_clear(void);
void display_subimage(image_t *image, const rect_t *dst_rect, const rect_t *src_rect, bool flip);
void display_exit(void);
#endif // DISPLAY_H

View File

@ -1,8 +0,0 @@
#ifndef IMAGE_H
#define IMAGE_H
#include <SDL2/SDL_render.h>
typedef SDL_Texture image_t;
#endif // IMAGE_H