Connected the AssetManager to the GameEngine and added function in the
GameEngine API to allow for loading and removing assets as well as rendering textures using their AssetID
This commit is contained in:
1 parent
c4f1775392
commit
3f71cf0f3f
11 files changed
+156
-33
No files matched your search
+10
-3
@@ -1,9 +1,12 @@
|
||||
#ifndef ASSET_MANAGER_H
|
||||
#define ASSET_MANAGER_H
|
||||
|
||||
#include "Renderer.h"
|
||||
#include "SDL_mixer.h"
|
||||
#include "SDL_render.h"
|
||||
#include "reusable_ids.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int32_t AssetID;
|
||||
typedef enum {
|
||||
ASSET_TYPE_IMAGE,
|
||||
ASSET_TYPE_AUDIO_FX,
|
||||
@@ -14,8 +17,12 @@ typedef enum {
|
||||
typedef struct asset_manager AssetManager;
|
||||
|
||||
AssetManager *create_asset_manager();
|
||||
AssetID load_asset(AssetManager *am, const char *path, AssetType type);
|
||||
void close_asset(AssetManager *am, AssetID id);
|
||||
AssetID load_asset_to_manager(AssetManager *am, const char *path,
|
||||
AssetType type, Renderer *renderer);
|
||||
void remove_asset_from_manager(AssetManager *am, AssetID id);
|
||||
SDL_Texture *get_texture(AssetManager *am, AssetID id);
|
||||
Mix_Chunk *get_audio_chunk(AssetManager *am, AssetID id);
|
||||
Mix_Music *get_music(AssetManager *am, AssetID id);
|
||||
void destroy_asset_manager(AssetManager *am);
|
||||
|
||||
#endif // !ASSET_MANAGER_H
|
||||
@@ -1,15 +1,21 @@
|
||||
#ifndef GAME_H
|
||||
#define GAME_H
|
||||
|
||||
#include "AssetManager.h"
|
||||
#include "ObjectStore.h"
|
||||
#include "SDL_pixels.h"
|
||||
#include "reusable_ids.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
bool init_game(const char *game_name, int window_width, int window_height,
|
||||
bool full_screen);
|
||||
SDL_Color window_background_color, bool full_screen);
|
||||
bool game_running();
|
||||
ObjectID add_object(void *object, EventHandlerPtr eh, UpdateFuncPtr uf,
|
||||
RenderFuncPtr rf);
|
||||
void remove_object(ObjectID id);
|
||||
AssetID load_asset(const char *path, AssetType type);
|
||||
void render_texture_asset(AssetID id, float x, float y, float w, float h);
|
||||
void close_asset(AssetID id);
|
||||
void handle_events();
|
||||
void update();
|
||||
void render();
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
#include "Renderer.h"
|
||||
#include "SDL_events.h"
|
||||
#include "engine_build_config.h"
|
||||
#include "reusable_ids.h"
|
||||
|
||||
typedef int32_t ObjectID;
|
||||
typedef void (*EventHandlerPtr)(const SDL_Event *event, void *object);
|
||||
typedef void (*UpdateFuncPtr)(float delta, void *object);
|
||||
typedef void (*RenderFuncPtr)(Renderer *renderer, void *object);
|
||||
typedef void (*RenderFuncPtr)(void *object);
|
||||
|
||||
typedef struct object_store ObjectStore;
|
||||
|
||||
@@ -18,11 +18,11 @@ ObjectID add_object_to_store(ObjectStore *os, void *object, EventHandlerPtr eh,
|
||||
void remove_object_from_store(ObjectStore *os, ObjectID id);
|
||||
void handle_all_objects_events(ObjectStore *os, const SDL_Event *event);
|
||||
void update_all_objects(ObjectStore *os, float delta);
|
||||
void render_all_objects(ObjectStore *os, Renderer *renderer);
|
||||
void render_all_objects(ObjectStore *os);
|
||||
void destroy_object_store(ObjectStore *os);
|
||||
|
||||
#ifdef DEBUG_ENGINE
|
||||
void print_objects(ObjectStore *os);
|
||||
#endif /* DEBUG_ENGINE */
|
||||
#endif // !DEBUG_ENGINE
|
||||
|
||||
#endif // !OBJECT_STORE_H
|
||||
@@ -2,6 +2,7 @@
|
||||
#define RENDERER_H
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_render.h"
|
||||
#include "SDL_video.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
@@ -9,7 +10,10 @@ typedef struct renderer Renderer;
|
||||
|
||||
Renderer *create_renderer();
|
||||
bool init_renderer(Renderer *renderer, SDL_Window *window);
|
||||
SDL_Texture *load_texture(const Renderer *renderer, const char *path);
|
||||
void render_clear(const Renderer *renderer, SDL_Color color);
|
||||
void render_texture(const Renderer *renderer, SDL_Texture *texture, float x,
|
||||
float y, float w, float h);
|
||||
void swap_buffers(const Renderer *renderer);
|
||||
void destroy_renderer(Renderer *renderer);
|
||||
|
||||
|
||||
+3
-2
@@ -11,11 +11,12 @@ typedef struct window {
|
||||
int height;
|
||||
Renderer *renderer;
|
||||
SDL_Window *SDL_base_window;
|
||||
SDL_Color background_color;
|
||||
} Window;
|
||||
|
||||
bool init_window(Window *wnd, const char *title, int width, int height,
|
||||
bool full_screen);
|
||||
void fill_window_with_color(const Window *wnd, SDL_Color color);
|
||||
SDL_Color color, bool full_screen);
|
||||
void clear_window(const Window *wnd);
|
||||
void swap_render_buffers(const Window *wnd);
|
||||
void destroy_window(Window *wnd);
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int32_t ObjectID;
|
||||
typedef int32_t AssetID;
|
||||
|
||||
int32_t reuse_id(int32_t *ids, size_t count);
|
||||
|
||||
#endif // !REUSABLE_IDS_H
|
||||
+48
-12
@@ -1,10 +1,10 @@
|
||||
#include "AssetManager.h"
|
||||
#include "Renderer.h"
|
||||
#include "SDL_image.h"
|
||||
#include "SDL_mixer.h"
|
||||
#include "SDL_surface.h"
|
||||
#include "SDL_render.h"
|
||||
#include "constants.h"
|
||||
#include "reusable_ids.h"
|
||||
#include <SDL2/SDL_surface.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@@ -15,7 +15,7 @@ typedef struct asset {
|
||||
AssetType type;
|
||||
char *path;
|
||||
union {
|
||||
SDL_Surface *surface;
|
||||
SDL_Texture *texture;
|
||||
Mix_Chunk *chunk;
|
||||
Mix_Music *music;
|
||||
} data;
|
||||
@@ -42,7 +42,8 @@ AssetManager *create_asset_manager() {
|
||||
return am;
|
||||
}
|
||||
|
||||
AssetID load_asset(AssetManager *am, const char *path, AssetType type) {
|
||||
AssetID load_asset_to_manager(AssetManager *am, const char *path,
|
||||
AssetType type, Renderer *renderer) {
|
||||
if (!am || type == ASSET_TYPE_COUNT) {
|
||||
return -1;
|
||||
}
|
||||
@@ -56,16 +57,23 @@ AssetID load_asset(AssetManager *am, const char *path, AssetType type) {
|
||||
|
||||
switch (type) {
|
||||
case ASSET_TYPE_IMAGE:
|
||||
asset.data.surface = IMG_Load(path);
|
||||
if (!renderer) {
|
||||
loaded = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(asset.data.surface)) {
|
||||
asset.data.texture = load_texture(renderer, path);
|
||||
|
||||
if (!(asset.data.texture)) {
|
||||
loaded = false;
|
||||
}
|
||||
|
||||
break;
|
||||
case ASSET_TYPE_AUDIO_FX:
|
||||
// TODO (Abdelrahman): Implement loading audio chunks
|
||||
break;
|
||||
case ASSET_TYPE_MUSIC:
|
||||
// TODO (Abdelrahman): Implement loading music
|
||||
break;
|
||||
default:
|
||||
loaded = false;
|
||||
@@ -95,7 +103,7 @@ AssetID load_asset(AssetManager *am, const char *path, AssetType type) {
|
||||
|
||||
switch (type) {
|
||||
case ASSET_TYPE_IMAGE:
|
||||
asset.data.surface = NULL;
|
||||
asset.data.texture = NULL;
|
||||
break;
|
||||
case ASSET_TYPE_AUDIO_FX:
|
||||
asset.data.chunk = NULL;
|
||||
@@ -110,7 +118,7 @@ AssetID load_asset(AssetManager *am, const char *path, AssetType type) {
|
||||
return id;
|
||||
}
|
||||
|
||||
void close_asset(AssetManager *am, AssetID id) {
|
||||
void remove_asset_from_manager(AssetManager *am, AssetID id) {
|
||||
if (!am || am->count == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -120,12 +128,14 @@ void close_asset(AssetManager *am, AssetID id) {
|
||||
|
||||
switch (am->assets[id].type) {
|
||||
case ASSET_TYPE_IMAGE:
|
||||
SDL_FreeSurface(am->assets[id].data.surface);
|
||||
am->assets[id].data.surface = NULL;
|
||||
SDL_DestroyTexture(am->assets[id].data.texture);
|
||||
am->assets[id].data.texture = NULL;
|
||||
break;
|
||||
case ASSET_TYPE_AUDIO_FX:
|
||||
// TODO (Abdelrahman): Implement closing audio chunk
|
||||
break;
|
||||
case ASSET_TYPE_MUSIC:
|
||||
// TODO (Abdelrahman): Implement closing music
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -136,6 +146,30 @@ void close_asset(AssetManager *am, AssetID id) {
|
||||
am->count -= 1;
|
||||
}
|
||||
|
||||
SDL_Texture *get_texture(AssetManager *am, AssetID id) {
|
||||
if (am->assets[id].type != ASSET_TYPE_IMAGE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return am->assets[id].data.texture;
|
||||
}
|
||||
|
||||
Mix_Chunk *get_audio_chunk(AssetManager *am, AssetID id) {
|
||||
if (am->assets[id].type != ASSET_TYPE_AUDIO_FX) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return am->assets[id].data.chunk;
|
||||
}
|
||||
|
||||
Mix_Music *get_music(AssetManager *am, AssetID id) {
|
||||
if (am->assets[id].type != ASSET_TYPE_MUSIC) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return am->assets[id].data.music;
|
||||
}
|
||||
|
||||
void destroy_asset_manager(AssetManager *am) {
|
||||
if (!am) {
|
||||
return;
|
||||
@@ -147,12 +181,14 @@ void destroy_asset_manager(AssetManager *am) {
|
||||
|
||||
switch (am->assets[i].type) {
|
||||
case ASSET_TYPE_IMAGE:
|
||||
SDL_FreeSurface(am->assets[i].data.surface);
|
||||
am->assets[i].data.surface = NULL;
|
||||
SDL_DestroyTexture(am->assets[i].data.texture);
|
||||
am->assets[i].data.texture = NULL;
|
||||
break;
|
||||
case ASSET_TYPE_AUDIO_FX:
|
||||
// TODO (Abdelrahman): Implement closing audio chunk
|
||||
break;
|
||||
case ASSET_TYPE_MUSIC:
|
||||
// TODO (Abdelrahman): Implement closing music
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
+49
-5
@@ -1,13 +1,19 @@
|
||||
#include "GameEngine.h"
|
||||
#include "AssetManager.h"
|
||||
#include "ObjectStore.h"
|
||||
#include "Renderer.h"
|
||||
#include "SDL.h"
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_image.h"
|
||||
#include "SDL_pixels.h"
|
||||
#include "SDL_render.h"
|
||||
#include "Window.h"
|
||||
#include "constants.h"
|
||||
#include "engine_build_config.h"
|
||||
#include "reusable_ids.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef DEBUG_ENGINE
|
||||
#include <stdio.h>
|
||||
@@ -19,10 +25,11 @@ INTERNAL struct game {
|
||||
Window window;
|
||||
SDL_Event event;
|
||||
ObjectStore *object_store;
|
||||
AssetManager *asset_manager;
|
||||
} Game;
|
||||
|
||||
bool init_game(const char *game_name, int window_width, int window_height,
|
||||
bool full_screen) {
|
||||
SDL_Color window_background_color, bool full_screen) {
|
||||
bool initialisation_complete = true;
|
||||
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
||||
@@ -33,8 +40,12 @@ bool init_game(const char *game_name, int window_width, int window_height,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) {
|
||||
initialisation_complete = false;
|
||||
}
|
||||
|
||||
if (!init_window(&(Game.window), game_name, window_width, window_height,
|
||||
full_screen)) {
|
||||
window_background_color, full_screen)) {
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Failed to initialise window\n");
|
||||
#endif /* DEBUG_ENGINE */
|
||||
@@ -48,6 +59,12 @@ bool init_game(const char *game_name, int window_width, int window_height,
|
||||
initialisation_complete = false;
|
||||
}
|
||||
|
||||
Game.asset_manager = create_asset_manager();
|
||||
|
||||
if (!(Game.asset_manager)) {
|
||||
initialisation_complete = false;
|
||||
}
|
||||
|
||||
if (!initialisation_complete) {
|
||||
close_game();
|
||||
|
||||
@@ -55,7 +72,8 @@ bool init_game(const char *game_name, int window_width, int window_height,
|
||||
}
|
||||
|
||||
Game.running = true;
|
||||
Game.delta = 0.0f;
|
||||
// Game.delta = 0.0f;
|
||||
Game.delta = 1.0f / 60.0f;
|
||||
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Game initialised successfully\n");
|
||||
@@ -84,6 +102,27 @@ void remove_object(ObjectID id) {
|
||||
remove_object_from_store(Game.object_store, id);
|
||||
}
|
||||
|
||||
AssetID load_asset(const char *path, AssetType type) {
|
||||
return type == ASSET_TYPE_IMAGE
|
||||
? load_asset_to_manager(Game.asset_manager, path, type,
|
||||
Game.window.renderer)
|
||||
: load_asset_to_manager(Game.asset_manager, path, type, NULL);
|
||||
}
|
||||
|
||||
void render_texture_asset(AssetID id, float x, float y, float w, float h) {
|
||||
if (id < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_Texture *texture = get_texture(Game.asset_manager, id);
|
||||
|
||||
render_texture(Game.window.renderer, texture, x, y, w, h);
|
||||
}
|
||||
|
||||
void close_asset(AssetID id) {
|
||||
remove_asset_from_manager(Game.asset_manager, id);
|
||||
}
|
||||
|
||||
void handle_events() {
|
||||
if (!(Game.running)) {
|
||||
return;
|
||||
@@ -117,16 +156,19 @@ void render() {
|
||||
return;
|
||||
}
|
||||
|
||||
fill_window_with_color(&(Game.window), (SDL_Color){255, 255, 255, 255});
|
||||
clear_window(&(Game.window));
|
||||
|
||||
if (Game.object_store) {
|
||||
render_all_objects(Game.object_store, Game.window.renderer);
|
||||
render_all_objects(Game.object_store);
|
||||
}
|
||||
|
||||
swap_render_buffers(&(Game.window));
|
||||
}
|
||||
|
||||
void close_game() {
|
||||
destroy_asset_manager(Game.asset_manager);
|
||||
Game.asset_manager = NULL;
|
||||
|
||||
destroy_object_store(Game.object_store);
|
||||
Game.object_store = NULL;
|
||||
|
||||
@@ -136,6 +178,8 @@ void close_game() {
|
||||
|
||||
Game.running = false;
|
||||
|
||||
IMG_Quit();
|
||||
|
||||
SDL_Quit();
|
||||
|
||||
#ifdef DEBUG_ENGINE
|
||||
|
||||
+2
-2
@@ -119,7 +119,7 @@ void update_all_objects(ObjectStore *os, float delta) {
|
||||
}
|
||||
}
|
||||
|
||||
void render_all_objects(ObjectStore *os, Renderer *renderer) {
|
||||
void render_all_objects(ObjectStore *os) {
|
||||
if (!os || os->count == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -127,7 +127,7 @@ void render_all_objects(ObjectStore *os, Renderer *renderer) {
|
||||
for (int i = 0; i < os->count; ++i) {
|
||||
if (os->render_funcs[i]) {
|
||||
void *object = os->object_ptrs[i];
|
||||
(os->render_funcs[i])(renderer, object);
|
||||
(os->render_funcs[i])(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
-1
@@ -1,5 +1,7 @@
|
||||
#include "Renderer.h"
|
||||
#include "SDL.h"
|
||||
#include "SDL_image.h"
|
||||
#include "SDL_rect.h"
|
||||
#include "SDL_render.h"
|
||||
#include "engine_build_config.h"
|
||||
#include <stdbool.h>
|
||||
@@ -35,12 +37,25 @@ void render_clear(const Renderer *renderer, SDL_Color color) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(renderer->SDL_base_renderer, color.r, color.r, color.b,
|
||||
SDL_SetRenderDrawColor(renderer->SDL_base_renderer, color.r, color.g, color.b,
|
||||
color.a);
|
||||
|
||||
SDL_RenderClear(renderer->SDL_base_renderer);
|
||||
}
|
||||
|
||||
void render_texture(const Renderer *renderer, SDL_Texture *texture, float x,
|
||||
float y, float w, float h) {
|
||||
if (!renderer || !texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_FRect dest = {x, y, w, h};
|
||||
|
||||
// TODO (Abdelrahman): Look into using the SDL_RenderCopyExF instead to
|
||||
// support rotating the texture
|
||||
SDL_RenderCopyF(renderer->SDL_base_renderer, texture, NULL, &dest);
|
||||
}
|
||||
|
||||
void swap_buffers(const Renderer *renderer) {
|
||||
if (!renderer || !(renderer->SDL_base_renderer)) {
|
||||
return;
|
||||
@@ -49,6 +64,10 @@ void swap_buffers(const Renderer *renderer) {
|
||||
SDL_RenderPresent(renderer->SDL_base_renderer);
|
||||
}
|
||||
|
||||
SDL_Texture *load_texture(const Renderer *renderer, const char *path) {
|
||||
return IMG_LoadTexture(renderer->SDL_base_renderer, path);
|
||||
}
|
||||
|
||||
void destroy_renderer(Renderer *renderer) {
|
||||
if (renderer) {
|
||||
if (renderer->SDL_base_renderer) {
|
||||
|
||||
+6
-3
@@ -8,7 +8,7 @@
|
||||
#endif /* DEBUG_ENGINE */
|
||||
|
||||
bool init_window(Window *wnd, const char *title, int width, int height,
|
||||
bool full_screen) {
|
||||
SDL_Color color, bool full_screen) {
|
||||
if (!wnd) {
|
||||
return false;
|
||||
}
|
||||
@@ -29,6 +29,8 @@ bool init_window(Window *wnd, const char *title, int width, int height,
|
||||
|
||||
SDL_GetWindowSize(wnd->SDL_base_window, &(wnd->width), &(wnd->height));
|
||||
|
||||
wnd->background_color = color;
|
||||
|
||||
wnd->renderer = create_renderer();
|
||||
|
||||
if (!wnd->renderer || !init_renderer(wnd->renderer, wnd->SDL_base_window)) {
|
||||
@@ -46,12 +48,12 @@ bool init_window(Window *wnd, const char *title, int width, int height,
|
||||
return true;
|
||||
}
|
||||
|
||||
void fill_window_with_color(const Window *wnd, SDL_Color color) {
|
||||
void clear_window(const Window *wnd) {
|
||||
if (!wnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
render_clear(wnd->renderer, color);
|
||||
render_clear(wnd->renderer, wnd->background_color);
|
||||
}
|
||||
|
||||
void swap_render_buffers(const Window *wnd) {
|
||||
@@ -78,6 +80,7 @@ void destroy_window(Window *wnd) {
|
||||
|
||||
wnd->width = 0;
|
||||
wnd->height = 0;
|
||||
wnd->background_color = (SDL_Color){0, 0, 0, 255};
|
||||
|
||||
#ifdef DEBUG_ENGINE
|
||||
printf("Window destroyed successfully\n");
|
||||
|
||||
Reference in new issue
Block a user