From dbc8c88b892bc30572d9645eff5c44f5387d1075 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 25 Sep 2022 15:58:54 +0100 Subject: [PATCH] Added ability to open, close and render fonts --- include/AssetManager.h | 3 +++ include/GameEngine.h | 11 +++++--- include/Renderer.h | 3 +++ src/AssetManager.c | 29 +++++++++++++++++++++ src/GameEngine.c | 59 ++++++++++++++++++++++++++++++++++++++---- src/Renderer.c | 15 +++++++++++ 6 files changed, 111 insertions(+), 9 deletions(-) diff --git a/include/AssetManager.h b/include/AssetManager.h index 07a9d38..a21bfaa 100644 --- a/include/AssetManager.h +++ b/include/AssetManager.h @@ -4,6 +4,7 @@ #include "Renderer.h" #include "SDL_mixer.h" #include "SDL_render.h" +#include "SDL_ttf.h" #include "reusable_ids.h" #include @@ -15,6 +16,7 @@ typedef enum { ASSET_TYPE_IMAGE, ASSET_TYPE_AUDIO_FX, ASSET_TYPE_MUSIC, + ASSET_TYPE_FONT, ASSET_TYPE_COUNT } AssetType; @@ -25,6 +27,7 @@ AssetID load_asset_to_manager(AssetManager *am, const char *path, AssetType type, Renderer *renderer); void remove_asset_from_manager(AssetManager *am, AssetID *id_ptr); SDL_Texture *get_texture(AssetManager *am, AssetID id); +TTF_Font *get_font(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); diff --git a/include/GameEngine.h b/include/GameEngine.h index 7ed36f1..b9ee55a 100644 --- a/include/GameEngine.h +++ b/include/GameEngine.h @@ -12,15 +12,18 @@ extern "C" { #endif // !__cplusplus -bool init_game(const char *game_name, uint32_t window_width, - uint32_t window_height, SDL_Color window_background_color, - bool full_screen, uint8_t audio_tracks); +bool init_engine(const char *game_name, uint32_t window_width, + uint32_t window_height, SDL_Color window_background_color, + bool full_screen, uint8_t audio_tracks); 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 render_text_with_font_asset(AssetID id, const char *text, float x, + float y); +void set_font_asset_size(AssetID id, uint32_t size); int8_t play_audio_asset(AssetID id, int16_t loops, bool fade_in, uint32_t fade_length_in_ms); void pause_audio_asset_on_track(AssetID id, uint8_t track); @@ -54,7 +57,7 @@ void close_asset(AssetID *id); void handle_events(); void update(); void render(); -void close_game(); +void close_engine(); #ifdef __cplusplus } diff --git a/include/Renderer.h b/include/Renderer.h index 0f2c569..2f976c3 100644 --- a/include/Renderer.h +++ b/include/Renderer.h @@ -3,6 +3,7 @@ #include "SDL.h" #include "SDL_render.h" +#include "SDL_surface.h" #include "SDL_video.h" #include @@ -16,6 +17,8 @@ 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_surface(const Renderer *renderer, SDL_Surface *surface, float x, + float y, float w, float h); void render_texture(const Renderer *renderer, SDL_Texture *texture, float x, float y, float w, float h); void swap_buffers(const Renderer *renderer); diff --git a/src/AssetManager.c b/src/AssetManager.c index 8c83b27..0a9290a 100644 --- a/src/AssetManager.c +++ b/src/AssetManager.c @@ -4,6 +4,7 @@ #include "SDL_image.h" #include "SDL_mixer.h" #include "SDL_render.h" +#include "SDL_ttf.h" #include "constants.h" #include "reusable_ids.h" #include @@ -20,6 +21,7 @@ typedef struct asset { SDL_Texture *texture; Mix_Chunk *chunk; Mix_Music *music; + TTF_Font *font; } data; } Asset; @@ -217,6 +219,14 @@ AssetID load_asset_to_manager(AssetManager *am, const char *path, loaded = false; } + break; + case ASSET_TYPE_FONT: + asset.data.font = TTF_OpenFont(path, 32); + + if (!(asset.data.font)) { + loaded = false; + } + break; default: loaded = false; @@ -259,6 +269,9 @@ AssetID load_asset_to_manager(AssetManager *am, const char *path, case ASSET_TYPE_MUSIC: asset.data.music = NULL; break; + case ASSET_TYPE_FONT: + asset.data.font = NULL; + break; default: break; } @@ -300,6 +313,10 @@ void remove_asset_from_manager(AssetManager *am, AssetID *id_ptr) { Mix_FreeMusic(am->assets[id].data.music); am->assets[id].data.music = NULL; break; + case ASSET_TYPE_FONT: + TTF_CloseFont(am->assets[id].data.font); + am->assets[id].data.font = NULL; + break; default: break; } @@ -317,6 +334,14 @@ SDL_Texture *get_texture(AssetManager *am, AssetID id) { return am->assets[id].data.texture; } +TTF_Font *get_font(AssetManager *am, AssetID id) { + if (id < 0 || am->assets[id].type != ASSET_TYPE_FONT) { + return NULL; + } + + return am->assets[id].data.font; +} + Mix_Chunk *get_audio_chunk(AssetManager *am, AssetID id) { if (id < 0 || am->assets[id].type != ASSET_TYPE_AUDIO_FX) { return NULL; @@ -360,6 +385,10 @@ void destroy_asset_manager(AssetManager **am) { Mix_FreeMusic((*am)->assets[i].data.music); (*am)->assets[i].data.music = NULL; break; + case ASSET_TYPE_FONT: + TTF_CloseFont((*am)->assets[i].data.font); + (*am)->assets[i].data.font = NULL; + break; default: break; } diff --git a/src/GameEngine.c b/src/GameEngine.c index 02c24b5..9d5d4ea 100644 --- a/src/GameEngine.c +++ b/src/GameEngine.c @@ -9,7 +9,9 @@ #include "SDL_mixer.h" #include "SDL_pixels.h" #include "SDL_render.h" +#include "SDL_surface.h" #include "SDL_timer.h" +#include "SDL_ttf.h" #include "Window.h" #include "constants.h" #include "engine_build_config.h" @@ -33,9 +35,9 @@ INTERNAL struct game_engine { AssetManager *asset_manager; } GameEngine; -bool init_game(const char *game_name, uint32_t window_width, - uint32_t window_height, SDL_Color window_background_color, - bool full_screen, uint8_t audio_tracks) { +bool init_engine(const char *game_name, uint32_t window_width, + uint32_t window_height, SDL_Color window_background_color, + bool full_screen, uint8_t audio_tracks) { bool initialisation_complete = true; if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { @@ -54,6 +56,13 @@ bool init_game(const char *game_name, uint32_t window_width, initialisation_complete = false; } + if (TTF_Init() < 0) { +#ifdef DEBUG_ENGINE + printf("Failed to initialise SDL_ttf. Error: %s\n", TTF_GetError()); +#endif /* DEBUG_ENGINE */ + initialisation_complete = false; + } + // We're only interested in initialising SDL_mixer with WAVE files, so no // need to pass any flags if (Mix_Init(0) != 0) { @@ -99,7 +108,7 @@ bool init_game(const char *game_name, uint32_t window_width, } if (!initialisation_complete) { - close_game(); + close_engine(); return false; } @@ -157,6 +166,44 @@ void render_texture_asset(AssetID id, float x, float y, float w, float h) { render_texture(GameEngine.window.renderer, texture, x, y, w, h); } +void render_text_with_font_asset(AssetID id, const char *text, float x, + float y) { + if (id < 0) { + return; + } + + TTF_Font *font = get_font(GameEngine.asset_manager, id); + if (!font) { + return; + } + + SDL_Surface *surface = + TTF_RenderText_Solid(font, text, (SDL_Color){0, 0, 0, 255}); + + // Get the width and height, in pixels, of the text rendered using the font + int32_t w = 0; + int32_t h = 0; + TTF_SizeText(font, text, &w, &h); + + render_surface(GameEngine.window.renderer, surface, x, y, w, h); + + SDL_FreeSurface(surface); + surface = NULL; +} + +void set_font_asset_size(AssetID id, uint32_t size) { + if (id < 0) { + return; + } + + TTF_Font *font = get_font(GameEngine.asset_manager, id); + if (!font) { + return; + } + + TTF_SetFontSize(font, size); +} + int8_t play_audio_asset(AssetID id, int16_t loops, bool fade_in, uint32_t fade_length_in_ms) { if (id < 0) { @@ -530,7 +577,7 @@ void render() { swap_render_buffers(&(GameEngine.window)); } -void close_game() { +void close_engine() { destroy_asset_manager(&(GameEngine.asset_manager)); destroy_object_store(&(GameEngine.object_store)); @@ -547,6 +594,8 @@ void close_game() { Mix_Quit(); + TTF_Quit(); + IMG_Quit(); SDL_Quit(); diff --git a/src/Renderer.c b/src/Renderer.c index fc2e097..72082fe 100644 --- a/src/Renderer.c +++ b/src/Renderer.c @@ -43,6 +43,21 @@ void render_clear(const Renderer *renderer, SDL_Color color) { SDL_RenderClear(renderer->SDL_base_renderer); } +void render_surface(const Renderer *renderer, SDL_Surface *surface, float x, + float y, float w, float h) { + SDL_Texture *texture = + SDL_CreateTextureFromSurface(renderer->SDL_base_renderer, surface); + + if (!texture) { + return; + } + + render_texture(renderer, texture, x, y, w, h); + + SDL_DestroyTexture(texture); + texture = NULL; +} + void render_texture(const Renderer *renderer, SDL_Texture *texture, float x, float y, float w, float h) { if (!renderer || !texture) {