From 3e6976d2ccca9cbb3d8d6194eec2bc799b4a5d99 Mon Sep 17 00:00:00 2001 From: Linus Probert Date: Wed, 9 May 2018 00:21:38 +0200 Subject: [PATCH] Adds texture creation of gui frames to reduce render time Also enables leakchecking and removes leaks from hashtable tests and some other leaks that were obvious. There are some X11 leaks still present but I don't think these are caused by me. --- .clang_complete | 5 ++ CMakeLists.txt | 14 ++++- src/gui.c | 124 ++++++++++++++++++++++++++++++++--------- src/gui.h | 8 ++- src/main.c | 11 ++-- src/player.c | 2 + src/skillbar.c | 1 + src/texture.c | 12 +++- test/check_hashtable.c | 6 ++ 9 files changed, 143 insertions(+), 40 deletions(-) create mode 100644 .clang_complete diff --git a/.clang_complete b/.clang_complete new file mode 100644 index 0000000..17b71c1 --- /dev/null +++ b/.clang_complete @@ -0,0 +1,5 @@ +-DDEBUG +-I./build/config.h +-I/usr/include/SDL2/ +-I/usr/include/lua5.2/ +-I/usr/include/physfs.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 76f7e16..cad134f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,8 +25,10 @@ configure_file( "${PROJECT_BINARY_DIR}/config.h" ) -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") +if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang") set(CLANG 1) +elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + set(GCC 1) endif() # Deal with travis compile issue @@ -35,7 +37,7 @@ if (CCACHE_FOUND AND CLANG) endif() -IF ( WIN32 ) +IF ( MSVC ) MESSAGE ( STATUS "Setting MSVC MT switches") SET ( CMAKE_C_FLAGS_DEBUG @@ -47,7 +49,13 @@ IF ( WIN32 ) "${CMAKE_CXX_FLAGS_RELEASE} /MT" CACHE STRING "MSVC MT flags " FORCE ) - ENDIF ( WIN32 ) +ENDIF ( MSVC ) +IF ( GCC OR CLANG ) + SET ( + CMAKE_C_FLAGS_DEBUG + "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address -fno-omit-frame-pointer" + ) +ENDIF ( GCC OR CLANG ) if (NOT PHYSFS_FOUND) add_subdirectory(physfs-3.0.1) diff --git a/src/gui.c b/src/gui.c index 031e5a8..818c86f 100644 --- a/src/gui.c +++ b/src/gui.c @@ -57,6 +57,9 @@ static struct GuiEventMsgData_t { unsigned int strlen; } event_messages = DEFAULT_EVENT_MESSAGES; +static Sprite* +gui_create_frame(unsigned int width, unsigned int height, Camera *cam); + static void gui_malloc_log(void) { @@ -105,7 +108,7 @@ create_label_sprite(Position pos) } static void -init_sprites(Gui *gui) +init_sprites(Gui *gui, Camera *cam) { Texture *t; unsigned int i; @@ -170,10 +173,17 @@ init_sprites(Gui *gui) s->clip = CLIP16(0, 0); s->pos = (Position) { 16, POS_Y_COLLECTABLES + 32 }; linkedlist_append(&gui->sprites, s); + + gui->rightFrame = gui_create_frame(RIGHT_GUI_WIDTH/16, + RIGHT_GUI_HEIGHT/16, + cam); + gui->bottomFrame = gui_create_frame(BOTTOM_GUI_WIDTH/16, + BOTTOM_GUI_HEIGHT/16, + cam); } Gui* -gui_create(void) +gui_create(Camera *cam) { Texture *t; unsigned int i; @@ -195,15 +205,31 @@ gui_create(void) gui->labels[CURRENT_XP_LABEL] = create_label_sprite((Position) { 16, POS_Y_XPBAR + 18 }); gui->labels[LEVEL_LABEL] = create_label_sprite((Position) { 16, POS_Y_XPBAR + 18 + 14 }); - gui->labels[DUNGEON_LEVEL_LABEL] = create_label_sprite((Position) { 16, POS_Y_XPBAR + 18 + (2*14) }); - gui->labels[HEALTH_POTION_LABEL] = create_label_sprite((Position) { 32, POS_Y_COLLECTABLES + 5 }); - gui->labels[GOLD_LABEL] = create_label_sprite((Position) { 32, POS_Y_COLLECTABLES + 16 + 5 }); - gui->labels[DAGGER_LABEL] = create_label_sprite((Position) { 32, POS_Y_COLLECTABLES + 32 + 5 }); + gui->labels[DUNGEON_LEVEL_LABEL] = + create_label_sprite((Position) { + 16, + POS_Y_XPBAR + 18 + (2*14) + }); + gui->labels[HEALTH_POTION_LABEL] = + create_label_sprite((Position) { + 32, + POS_Y_COLLECTABLES + 5 + }); + gui->labels[GOLD_LABEL] = + create_label_sprite((Position) { + 32, + POS_Y_COLLECTABLES + 16 + 5 + }); + gui->labels[DAGGER_LABEL] = + create_label_sprite((Position) { + 32, + POS_Y_COLLECTABLES + 32 + 5 + }); gui_malloc_log(); gui_malloc_eventmessages(); - init_sprites(gui); + init_sprites(gui, cam); return gui; } @@ -376,47 +402,90 @@ gui_update_player_stats(Gui *gui, Player *player, Map *map, SDL_Renderer *render } } -static void -gui_render_frame(unsigned int width, unsigned int height, Camera *cam) +static Sprite* +gui_create_frame(unsigned int width, unsigned int height, Camera *cam) { - Texture *texture = texturecache_get("GUI/GUI0.png"); - unsigned int i, j; + Sprite *frame = sprite_create(); + Texture *texture = texture_create(); + texture->dim = (Dimension) { + width * 16, + height * 16 + }; + frame->textures[0] = texture; + frame->destroyTextures = true; + frame->pos = (Position) { 0, 0 }; + frame->dim = (Dimension) { width*16, height*16 }; + texture_create_blank(texture, + SDL_TEXTUREACCESS_TARGET, + cam->renderer); + Texture *source = texturecache_get("GUI/GUI0.png"); + + SDL_SetRenderTarget(cam->renderer, texture->texture); + SDL_RenderClear(cam->renderer); SDL_Rect box = { 0, 0, 16, 16 }; - + unsigned int i, j; for (i = 0; i < width; ++i) { for (j = 0; j < height; ++j) { box.x = i * 16; box.y = j * 16; if (i == 0 && j == 0) { - texture_render_clip(texture, &box, &frame_top_left, cam); + texture_render_clip(source, + &box, + &frame_top_left, + cam); } else if (i == (width - 1) && j == 0) { - texture_render_clip(texture, &box, &frame_top_right, cam); + texture_render_clip(source, + &box, + &frame_top_right, + cam); } else if (i == 0 && j == (height - 1)) { - texture_render_clip(texture, &box, &frame_bottom_left, cam); + texture_render_clip(source, + &box, + &frame_bottom_left, + cam); } else if (i == (width - 1) && j == (height - 1)) { - texture_render_clip(texture, &box, &frame_bottom_right, cam); + texture_render_clip(source, + &box, + &frame_bottom_right, + cam); } else if (i == 0) { - texture_render_clip(texture, &box, &frame_left, cam); + texture_render_clip(source, + &box, + &frame_left, + cam); } else if (i == (width - 1)) { - texture_render_clip(texture, &box, &frame_right, cam); + texture_render_clip(source, + &box, + &frame_right, + cam); } else if (j == 0) { - texture_render_clip(texture, &box, &frame_top, cam); + texture_render_clip(source, + &box, + &frame_top, + cam); } else if (j == (height - 1)) { - texture_render_clip(texture, &box, &frame_bottom, cam); + texture_render_clip(source, + &box, + &frame_bottom, + cam); } else { - texture_render_clip(texture, &box, &frame_center, cam); + texture_render_clip(source, + &box, + &frame_center, + cam); } } } + SDL_SetRenderTarget(cam->renderer, NULL); + return frame; } void -gui_render_panel(Gui *gui, unsigned int width, unsigned int height, Camera *cam) +gui_render_panel(Gui *gui, Camera *cam) { - gui_render_frame(width/16, height/16, cam); - + sprite_render(gui->rightFrame, cam); LinkedList *item = gui->health; while (item != NULL) { Sprite *s = item->data; @@ -490,7 +559,7 @@ gui_event_message(const char *fmt, ...) } void -gui_render_log(Gui *gui, unsigned int width, unsigned int height, Camera *cam) +gui_render_log(Gui *gui, Camera *cam) { static SDL_Color color = { 255, 255, 255, 255 }; @@ -500,7 +569,7 @@ gui_render_log(Gui *gui, unsigned int width, unsigned int height, Camera *cam) render_count = LOG_LINES_COUNT > log_data.count ? log_data.count : LOG_LINES_COUNT; - gui_render_frame(width/16, height/16, cam); + sprite_render(gui->bottomFrame, cam); for (i = 0; i < render_count; ++i) { Texture *t; @@ -596,6 +665,9 @@ gui_destroy(Gui *gui) timer_destroy(gui->event_message_timer); texture_destroy(gui->event_message); + sprite_destroy(gui->bottomFrame); + sprite_destroy(gui->rightFrame); + while (gui->sprites != NULL) sprite_destroy(linkedlist_pop(&gui->sprites)); while (gui->health != NULL) diff --git a/src/gui.h b/src/gui.h index c211269..91d5791 100644 --- a/src/gui.h +++ b/src/gui.h @@ -46,6 +46,8 @@ typedef struct { LinkedList *sprites; LinkedList *health; LinkedList *xp_bar; + Sprite *bottomFrame; + Sprite *rightFrame; Sprite *labels[LABEL_COUNT]; Texture *log_lines[LOG_LINES_COUNT]; Texture *event_message; @@ -53,16 +55,16 @@ typedef struct { } Gui; Gui* -gui_create(void); +gui_create(Camera *); void gui_update_player_stats(Gui*, Player*, Map*, SDL_Renderer*); void -gui_render_panel(Gui*, unsigned int width, unsigned int height, Camera*); +gui_render_panel(Gui*, Camera*); void -gui_render_log(Gui*, unsigned int width, unsigned int height, Camera*); +gui_render_log(Gui*, Camera*); void gui_render_event_message(Gui*, Camera*); diff --git a/src/main.c b/src/main.c index 0fa0fd4..cedff3a 100644 --- a/src/main.c +++ b/src/main.c @@ -139,7 +139,8 @@ bool initSDL(void) return false; } - gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED); + gRenderer = SDL_CreateRenderer(gWindow, -1, + SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE); if (gRenderer == NULL) { error("Unable to create renderer: %s", SDL_GetError()); @@ -189,7 +190,7 @@ initGame(void) texturecache_init(gRenderer); gCamera.renderer = gRenderer; gRoomMatrix = roommatrix_create(); - gGui = gui_create(); + gGui = gui_create(&gCamera); gSkillBar = skillbar_create(gRenderer); item_builder_init(gRenderer); gPointer = pointer_create(gRenderer); @@ -511,15 +512,13 @@ run_game(void) gui_render_event_message(gGui, &gCamera); SDL_RenderSetViewport(gRenderer, &rightGuiViewport); - gui_render_panel(gGui, RIGHT_GUI_WIDTH, - RIGHT_GUI_HEIGHT, &gCamera); + gui_render_panel(gGui, &gCamera); SDL_RenderSetViewport(gRenderer, &skillBarViewport); skillbar_render(gSkillBar, gPlayer, &gCamera); SDL_RenderSetViewport(gRenderer, &bottomGuiViewport); - gui_render_log(gGui, BOTTOM_GUI_WIDTH, - BOTTOM_GUI_HEIGHT, &gCamera); + gui_render_log(gGui, &gCamera); SDL_RenderSetViewport(gRenderer, NULL); particle_engine_render_global(&gCamera); diff --git a/src/player.c b/src/player.c index 9b7ced3..3b44f77 100644 --- a/src/player.c +++ b/src/player.c @@ -536,6 +536,8 @@ player_destroy(Player *player) actiontext_destroy(player->hitText); actiontext_destroy(player->missText); + timer_destroy(player->animationTimer); + for (size_t i = 0; i < PLAYER_SKILL_COUNT; ++i) { if (player->skills[i]) skill_destroy(player->skills[i]); diff --git a/src/skillbar.c b/src/skillbar.c index 95c6eeb..fbaa614 100644 --- a/src/skillbar.c +++ b/src/skillbar.c @@ -279,5 +279,6 @@ skillbar_destroy(SkillBar *bar) if (bar->countdowns[i]) sprite_destroy(bar->countdowns[i]); timer_destroy(bar->activationTimer); + timer_destroy(bar->skillSparkleTimer); free(bar); } diff --git a/src/texture.c b/src/texture.c index dd7131c..63691ae 100644 --- a/src/texture.c +++ b/src/texture.c @@ -50,6 +50,7 @@ texture_create_blank(Texture *t, access, t->dim.width, t->dim.height); + assert(t->texture != NULL); t->textureAccessType = access; } @@ -162,9 +163,16 @@ texture_load_from_text(Texture *t, } void -texture_load_from_text_shaded(Texture *t, const char * text, SDL_Color fg, SDL_Color bg, SDL_Renderer *renderer) +texture_load_from_text_shaded(Texture *t, + const char *text, + SDL_Color fg, + SDL_Color bg, + SDL_Renderer *renderer) { - SDL_Surface *surface = TTF_RenderText_Shaded( t->font, text, fg, bg ); + SDL_Surface *surface = TTF_RenderText_Shaded( t->font, + text, + fg, + bg ); if (surface == NULL) { error("Unable to create texture from rendered text: %s", diff --git a/test/check_hashtable.c b/test/check_hashtable.c index 1c1c70c..38468c5 100644 --- a/test/check_hashtable.c +++ b/test/check_hashtable.c @@ -113,6 +113,8 @@ START_TEST(test_hashtable_foreach) for (int i = 0; i < 10; i++) { ck_assert(checklist[i]); } + + ht_destroy(table); } END_TEST @@ -133,6 +135,10 @@ START_TEST(test_hashtable_remove) getVal = ht_remove(table, key2); ck_assert(strcmp(value2, getVal) == 0); ck_assert(ht_get(table, key2) == NULL); + ht_remove(table, key1); + ht_remove(table, key3); + + ht_destroy(table); } END_TEST