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.
This commit is contained in:
Linus Probert 2018-05-09 00:21:38 +02:00
parent 2122300f6e
commit 3e6976d2cc
9 changed files with 143 additions and 40 deletions

5
.clang_complete Normal file
View File

@ -0,0 +1,5 @@
-DDEBUG
-I./build/config.h
-I/usr/include/SDL2/
-I/usr/include/lua5.2/
-I/usr/include/physfs.h

View File

@ -25,8 +25,10 @@ configure_file(
"${PROJECT_BINARY_DIR}/config.h" "${PROJECT_BINARY_DIR}/config.h"
) )
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang")
set(CLANG 1) set(CLANG 1)
elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
set(GCC 1)
endif() endif()
# Deal with travis compile issue # Deal with travis compile issue
@ -35,7 +37,7 @@ if (CCACHE_FOUND AND CLANG)
endif() endif()
IF ( WIN32 ) IF ( MSVC )
MESSAGE ( STATUS "Setting MSVC MT switches") MESSAGE ( STATUS "Setting MSVC MT switches")
SET ( SET (
CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG
@ -47,7 +49,13 @@ IF ( WIN32 )
"${CMAKE_CXX_FLAGS_RELEASE} /MT" "${CMAKE_CXX_FLAGS_RELEASE} /MT"
CACHE STRING "MSVC MT flags " FORCE 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) if (NOT PHYSFS_FOUND)
add_subdirectory(physfs-3.0.1) add_subdirectory(physfs-3.0.1)

124
src/gui.c
View File

@ -57,6 +57,9 @@ static struct GuiEventMsgData_t {
unsigned int strlen; unsigned int strlen;
} event_messages = DEFAULT_EVENT_MESSAGES; } event_messages = DEFAULT_EVENT_MESSAGES;
static Sprite*
gui_create_frame(unsigned int width, unsigned int height, Camera *cam);
static void static void
gui_malloc_log(void) gui_malloc_log(void)
{ {
@ -105,7 +108,7 @@ create_label_sprite(Position pos)
} }
static void static void
init_sprites(Gui *gui) init_sprites(Gui *gui, Camera *cam)
{ {
Texture *t; Texture *t;
unsigned int i; unsigned int i;
@ -170,10 +173,17 @@ init_sprites(Gui *gui)
s->clip = CLIP16(0, 0); s->clip = CLIP16(0, 0);
s->pos = (Position) { 16, POS_Y_COLLECTABLES + 32 }; s->pos = (Position) { 16, POS_Y_COLLECTABLES + 32 };
linkedlist_append(&gui->sprites, s); 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*
gui_create(void) gui_create(Camera *cam)
{ {
Texture *t; Texture *t;
unsigned int i; 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[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[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[DUNGEON_LEVEL_LABEL] =
gui->labels[HEALTH_POTION_LABEL] = create_label_sprite((Position) { 32, POS_Y_COLLECTABLES + 5 }); create_label_sprite((Position) {
gui->labels[GOLD_LABEL] = create_label_sprite((Position) { 32, POS_Y_COLLECTABLES + 16 + 5 }); 16,
gui->labels[DAGGER_LABEL] = create_label_sprite((Position) { 32, POS_Y_COLLECTABLES + 32 + 5 }); 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_log();
gui_malloc_eventmessages(); gui_malloc_eventmessages();
init_sprites(gui); init_sprites(gui, cam);
return gui; return gui;
} }
@ -376,47 +402,90 @@ gui_update_player_stats(Gui *gui, Player *player, Map *map, SDL_Renderer *render
} }
} }
static void static Sprite*
gui_render_frame(unsigned int width, unsigned int height, Camera *cam) gui_create_frame(unsigned int width, unsigned int height, Camera *cam)
{ {
Texture *texture = texturecache_get("GUI/GUI0.png"); Sprite *frame = sprite_create();
unsigned int i, j; 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 }; SDL_Rect box = { 0, 0, 16, 16 };
unsigned int i, j;
for (i = 0; i < width; ++i) { for (i = 0; i < width; ++i) {
for (j = 0; j < height; ++j) { for (j = 0; j < height; ++j) {
box.x = i * 16; box.x = i * 16;
box.y = j * 16; box.y = j * 16;
if (i == 0 && j == 0) { 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) { } 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)) { } 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)) { } 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) { } 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)) { } 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) { } 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)) { } else if (j == (height - 1)) {
texture_render_clip(texture, &box, &frame_bottom, cam); texture_render_clip(source,
&box,
&frame_bottom,
cam);
} else { } 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 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; LinkedList *item = gui->health;
while (item != NULL) { while (item != NULL) {
Sprite *s = item->data; Sprite *s = item->data;
@ -490,7 +559,7 @@ gui_event_message(const char *fmt, ...)
} }
void 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 }; 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; 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) { for (i = 0; i < render_count; ++i) {
Texture *t; Texture *t;
@ -596,6 +665,9 @@ gui_destroy(Gui *gui)
timer_destroy(gui->event_message_timer); timer_destroy(gui->event_message_timer);
texture_destroy(gui->event_message); texture_destroy(gui->event_message);
sprite_destroy(gui->bottomFrame);
sprite_destroy(gui->rightFrame);
while (gui->sprites != NULL) while (gui->sprites != NULL)
sprite_destroy(linkedlist_pop(&gui->sprites)); sprite_destroy(linkedlist_pop(&gui->sprites));
while (gui->health != NULL) while (gui->health != NULL)

View File

@ -46,6 +46,8 @@ typedef struct {
LinkedList *sprites; LinkedList *sprites;
LinkedList *health; LinkedList *health;
LinkedList *xp_bar; LinkedList *xp_bar;
Sprite *bottomFrame;
Sprite *rightFrame;
Sprite *labels[LABEL_COUNT]; Sprite *labels[LABEL_COUNT];
Texture *log_lines[LOG_LINES_COUNT]; Texture *log_lines[LOG_LINES_COUNT];
Texture *event_message; Texture *event_message;
@ -53,16 +55,16 @@ typedef struct {
} Gui; } Gui;
Gui* Gui*
gui_create(void); gui_create(Camera *);
void void
gui_update_player_stats(Gui*, Player*, Map*, SDL_Renderer*); gui_update_player_stats(Gui*, Player*, Map*, SDL_Renderer*);
void void
gui_render_panel(Gui*, unsigned int width, unsigned int height, Camera*); gui_render_panel(Gui*, Camera*);
void void
gui_render_log(Gui*, unsigned int width, unsigned int height, Camera*); gui_render_log(Gui*, Camera*);
void void
gui_render_event_message(Gui*, Camera*); gui_render_event_message(Gui*, Camera*);

View File

@ -139,7 +139,8 @@ bool initSDL(void)
return false; return false;
} }
gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED); gRenderer = SDL_CreateRenderer(gWindow, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
if (gRenderer == NULL) if (gRenderer == NULL)
{ {
error("Unable to create renderer: %s", SDL_GetError()); error("Unable to create renderer: %s", SDL_GetError());
@ -189,7 +190,7 @@ initGame(void)
texturecache_init(gRenderer); texturecache_init(gRenderer);
gCamera.renderer = gRenderer; gCamera.renderer = gRenderer;
gRoomMatrix = roommatrix_create(); gRoomMatrix = roommatrix_create();
gGui = gui_create(); gGui = gui_create(&gCamera);
gSkillBar = skillbar_create(gRenderer); gSkillBar = skillbar_create(gRenderer);
item_builder_init(gRenderer); item_builder_init(gRenderer);
gPointer = pointer_create(gRenderer); gPointer = pointer_create(gRenderer);
@ -511,15 +512,13 @@ run_game(void)
gui_render_event_message(gGui, &gCamera); gui_render_event_message(gGui, &gCamera);
SDL_RenderSetViewport(gRenderer, &rightGuiViewport); SDL_RenderSetViewport(gRenderer, &rightGuiViewport);
gui_render_panel(gGui, RIGHT_GUI_WIDTH, gui_render_panel(gGui, &gCamera);
RIGHT_GUI_HEIGHT, &gCamera);
SDL_RenderSetViewport(gRenderer, &skillBarViewport); SDL_RenderSetViewport(gRenderer, &skillBarViewport);
skillbar_render(gSkillBar, gPlayer, &gCamera); skillbar_render(gSkillBar, gPlayer, &gCamera);
SDL_RenderSetViewport(gRenderer, &bottomGuiViewport); SDL_RenderSetViewport(gRenderer, &bottomGuiViewport);
gui_render_log(gGui, BOTTOM_GUI_WIDTH, gui_render_log(gGui, &gCamera);
BOTTOM_GUI_HEIGHT, &gCamera);
SDL_RenderSetViewport(gRenderer, NULL); SDL_RenderSetViewport(gRenderer, NULL);
particle_engine_render_global(&gCamera); particle_engine_render_global(&gCamera);

View File

@ -536,6 +536,8 @@ player_destroy(Player *player)
actiontext_destroy(player->hitText); actiontext_destroy(player->hitText);
actiontext_destroy(player->missText); actiontext_destroy(player->missText);
timer_destroy(player->animationTimer);
for (size_t i = 0; i < PLAYER_SKILL_COUNT; ++i) { for (size_t i = 0; i < PLAYER_SKILL_COUNT; ++i) {
if (player->skills[i]) if (player->skills[i])
skill_destroy(player->skills[i]); skill_destroy(player->skills[i]);

View File

@ -279,5 +279,6 @@ skillbar_destroy(SkillBar *bar)
if (bar->countdowns[i]) if (bar->countdowns[i])
sprite_destroy(bar->countdowns[i]); sprite_destroy(bar->countdowns[i]);
timer_destroy(bar->activationTimer); timer_destroy(bar->activationTimer);
timer_destroy(bar->skillSparkleTimer);
free(bar); free(bar);
} }

View File

@ -50,6 +50,7 @@ texture_create_blank(Texture *t,
access, access,
t->dim.width, t->dim.width,
t->dim.height); t->dim.height);
assert(t->texture != NULL);
t->textureAccessType = access; t->textureAccessType = access;
} }
@ -162,9 +163,16 @@ texture_load_from_text(Texture *t,
} }
void 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) if (surface == NULL)
{ {
error("Unable to create texture from rendered text: %s", error("Unable to create texture from rendered text: %s",

View File

@ -113,6 +113,8 @@ START_TEST(test_hashtable_foreach)
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
ck_assert(checklist[i]); ck_assert(checklist[i]);
} }
ht_destroy(table);
} }
END_TEST END_TEST
@ -133,6 +135,10 @@ START_TEST(test_hashtable_remove)
getVal = ht_remove(table, key2); getVal = ht_remove(table, key2);
ck_assert(strcmp(value2, getVal) == 0); ck_assert(strcmp(value2, getVal) == 0);
ck_assert(ht_get(table, key2) == NULL); ck_assert(ht_get(table, key2) == NULL);
ht_remove(table, key1);
ht_remove(table, key3);
ht_destroy(table);
} }
END_TEST END_TEST