From 6c1591a92dd55fcd71c9557e2c837abb89057f5f Mon Sep 17 00:00:00 2001 From: Linus Probert Date: Wed, 31 Jan 2018 20:59:55 +0100 Subject: [PATCH] Some rewrites and lots of nice gui labels --- src/gui.c | 153 +++++++++++++++++++++++++++++++++++---------------- src/gui.h | 15 +++-- src/main.c | 9 +-- src/sprite.c | 39 ++++++++++--- src/sprite.h | 2 + 5 files changed, 152 insertions(+), 66 deletions(-) diff --git a/src/gui.c b/src/gui.c index 2c82323..8f7fc24 100644 --- a/src/gui.c +++ b/src/gui.c @@ -6,6 +6,7 @@ #include "gui.h" #include "util.h" +#include "map.h" #define DEFAULT_LOG { NULL, 50, 0, 200 } #define POS_Y_XPBAR 96 @@ -53,11 +54,31 @@ gui_malloc_log(void) log_data.log[i] = NULL; } +static Sprite* +create_xp_sprite(Texture *t, SDL_Rect clip, Position pos) +{ + Sprite *s = sprite_create(); + sprite_set_texture(s, t, 0); + s->fixed = true; + s->clip = clip; + s->pos = pos; + return s; +} + +static Sprite* +create_label_sprite(Position pos) +{ + Sprite *s = sprite_create(); + s->fixed = true; + s->pos = pos; + sprite_load_text_texture(s, "assets/GUI/SDS_8x8.ttf", 0, LABEL_FONT_SIZE); + return s; +} + static void init_sprites(Gui *gui, SDL_Renderer *renderer) { Texture *t; - Sprite *s; unsigned int i; t = add_texture(gui, "assets/GUI/GUI0.png", renderer); @@ -67,37 +88,33 @@ init_sprites(Gui *gui, SDL_Renderer *renderer) */ // Left end - s = sprite_create(); - sprite_set_texture(s, t, 0); - s->fixed = true; - s->clip = (SDL_Rect) { 6 * 16, 0, 16, 16 }; - s->pos = (Position) { 16 , POS_Y_XPBAR }; - linkedlist_append(&gui->sprites, s); + linkedlist_append(&gui->sprites, create_xp_sprite( + t, + (SDL_Rect) { 6 * 16, 0, 16, 16 }, + (Position) { 16, POS_Y_XPBAR } + )); // Right end - s = sprite_create(); - sprite_set_texture(s, t, 0); - s->fixed = true; - s->clip = (SDL_Rect) { 8 * 16, 0, 16, 16 }; - s->pos = (Position) { 16 + (16 * 7), POS_Y_XPBAR }; - linkedlist_append(&gui->sprites, s); + linkedlist_append(&gui->sprites, create_xp_sprite( + t, + (SDL_Rect) { 8 * 16, 0, 16, 16 }, + (Position) { 16 + (16 * 7), POS_Y_XPBAR } + )); for (i = 1; i < 7; ++i) { - s = sprite_create(); - sprite_set_texture(s, t, 0); - s->fixed = true; - s->clip = (SDL_Rect) { 7 * 16, 0, 16, 16 }; - s->pos = (Position) { 16 + (i * 16), POS_Y_XPBAR }; - linkedlist_append(&gui->sprites, s); + linkedlist_append(&gui->sprites, create_xp_sprite( + t, + (SDL_Rect) { 7 * 16, 0, 16, 16 }, + (Position) { 16 + (i * 16), POS_Y_XPBAR } + )); } for (i = 0; i < 8; ++i) { - s = sprite_create(); - sprite_set_texture(s, t, 0); - s->fixed = true; - s->clip = (SDL_Rect) { 6 * 16, 4 * 16, 16, 16 }; - s->pos = (Position) { 16 + (i * 16), POS_Y_XPBAR }; - linkedlist_append(&gui->xp_bar, s); + linkedlist_append(&gui->xp_bar, create_xp_sprite( + t, + (SDL_Rect) { 6 * 16, 4 * 16, 16, 16 }, + (Position) { 16 + (i * 16), POS_Y_XPBAR } + )); } } @@ -119,6 +136,11 @@ gui_create(SDL_Renderer *renderer) gui->log_lines[i] = t; } + gui->labels[CURRENT_XP_LABEL] = create_label_sprite((Position) { 16, 116 }); + gui->labels[LEVEL_LABEL] = create_label_sprite((Position) { 16, 128 }); + gui->labels[DUNGEON_LEVEL_LABEL] = create_label_sprite((Position) { 16, 156 }); + gui->labels[GOLD_LABEL] = create_label_sprite((Position) { 16, 142 }); + gui_malloc_log(); init_sprites(gui, renderer); @@ -180,47 +202,80 @@ gui_set_current_health(Gui *gui, int current) } void -gui_set_current_xp(Gui *gui, ExperienceData data) +gui_update_player_stats(Gui *gui, Player *player, Map *map, SDL_Renderer *renderer) { + // TODO(Linus): Perhaps split this up a bit? + // some static functions maybe? + static unsigned int last_level = 0; + static int last_xp = -1; + static double last_gold = -1; + static unsigned int dungeon_level = 0; + + static SDL_Color color = { 255, 255, 255, 255 }; + unsigned int xp_from_levelup, xp_required_from_last_level; float xp_step, xp_current_step; unsigned int full_xp_blocks, partial_xp_block; LinkedList *xp_bars; unsigned int i; + char buffer[200]; - xp_from_levelup = data.current - data.previousLevel; - xp_required_from_last_level = data.nextLevel - data.previousLevel; - xp_step = ((float) xp_required_from_last_level) / 32; // 4 * 8 - xp_current_step = xp_from_levelup / xp_step; + ExperienceData data = player_get_xp_data(player); - partial_xp_block = ((unsigned int) xp_current_step) % 4; - full_xp_blocks = (unsigned int)((xp_current_step - partial_xp_block) / 4); + if (last_xp != data.current) { + xp_from_levelup = data.current - data.previousLevel; + xp_required_from_last_level = data.nextLevel - data.previousLevel; + xp_step = ((float)xp_required_from_last_level) / 32; // 4 * 8 + xp_current_step = xp_from_levelup / xp_step; - xp_bars = gui->xp_bar; - i = 0; - while (xp_bars != NULL) { - Sprite *s = xp_bars->data; - s->hidden = false; - xp_bars = xp_bars->next; + partial_xp_block = ((unsigned int)xp_current_step) % 4; + full_xp_blocks = (unsigned int)((xp_current_step - partial_xp_block) / 4); - if (i < full_xp_blocks) { - s->clip.x = 6 * 16; - } else if (i == full_xp_blocks && partial_xp_block != 0) { - s->clip.x = (6 * 16) + (16 * (4 - partial_xp_block)); - } else { - s->hidden = true; + xp_bars = gui->xp_bar; + i = 0; + while (xp_bars != NULL) { + Sprite *s = xp_bars->data; + s->hidden = false; + xp_bars = xp_bars->next; + + if (i < full_xp_blocks) { + s->clip.x = 6 * 16; + } + else if (i == full_xp_blocks && partial_xp_block != 0) { + s->clip.x = (6 * 16) + (16 * (4 - partial_xp_block)); + } + else { + s->hidden = true; + } + + ++i; } + } - ++i; + if (dungeon_level != map->level) { + m_sprintf(buffer, 200, "Dungeon level: %d", map->level); + texture_load_from_text(gui->labels[DUNGEON_LEVEL_LABEL]->textures[0], buffer, color, renderer); + dungeon_level = (unsigned int) map->level; + } + + if (last_gold != player->gold) { + m_sprintf(buffer, 200, "Gold: %.2f", player->gold); + texture_load_from_text(gui->labels[GOLD_LABEL]->textures[0], buffer, color, renderer); + last_gold = player->gold; + } + + if (last_xp != data.current) { + m_sprintf(buffer, 200, "XP: %u / %u", data.current, data.nextLevel); + texture_load_from_text(gui->labels[CURRENT_XP_LABEL]->textures[0], buffer, color, renderer); + last_xp = data.current; } if (last_level != data.level) { - // TODO(Linus): Update the indicators + m_sprintf(buffer, 200, "Level: %u", data.level); + texture_load_from_text(gui->labels[LEVEL_LABEL]->textures[0], buffer, color, renderer); last_level = data.level; } - - } static void @@ -282,6 +337,8 @@ gui_render_panel(Gui *gui, unsigned int width, unsigned int height, Camera *cam) item = item->next; } + for (int i = 0; i < LABEL_COUNT; ++i) + sprite_render(gui->labels[i], cam); } void diff --git a/src/gui.h b/src/gui.h index e0214d1..6448a0b 100644 --- a/src/gui.h +++ b/src/gui.h @@ -3,6 +3,7 @@ #define LOG_LINES_COUNT 15 #define LOG_FONT_SIZE 8 +#define LABEL_FONT_SIZE 8 #include "linkedlist.h" #include "hashtable.h" @@ -10,11 +11,20 @@ #include "camera.h" #include "player.h" +typedef enum Label_e { + LEVEL_LABEL, + CURRENT_XP_LABEL, + GOLD_LABEL, + DUNGEON_LEVEL_LABEL, + LABEL_COUNT +} LabelIndex; + typedef struct { LinkedList *sprites; LinkedList *health; LinkedList *xp_bar; Hashtable *textures; + Sprite *labels[LABEL_COUNT]; Texture *log_lines[LOG_LINES_COUNT]; } Gui; @@ -28,10 +38,7 @@ void gui_set_current_health(Gui*, int current); void -gui_set_current_xp(Gui*, ExperienceData); - -void -gui_set_xp_data(Gui*, ExperienceData); +gui_update_player_stats(Gui*, Player*, Map*, SDL_Renderer*); void gui_render_panel(Gui*, unsigned int width, unsigned int height, Camera*); diff --git a/src/main.c b/src/main.c index 7f18a37..842c437 100644 --- a/src/main.c +++ b/src/main.c @@ -203,7 +203,6 @@ run_game(void) { static unsigned int player_max_hp = 0; static unsigned int player_current_hp = 0; - static unsigned int player_current_xp = 0; SDL_RenderSetViewport(gRenderer, NULL); map_clear_dead_monsters(gMap); @@ -213,6 +212,7 @@ run_game(void) &gPlayer->sprite->pos); roommatrix_build_lightmap(gRoomMatrix); + gui_update_player_stats(gGui, gPlayer, gMap, gRenderer); if (player_max_hp != (unsigned int) gPlayer->stats.maxhp) { gui_set_max_health(gGui, gPlayer->stats.maxhp, gRenderer); @@ -222,11 +222,8 @@ run_game(void) gui_set_current_health(gGui, gPlayer->stats.hp); player_current_hp = gPlayer->stats.hp; } - if (player_current_xp != gPlayer->xp) { - gui_set_current_xp(gGui, player_get_xp_data(gPlayer)); - player_current_xp = gPlayer->xp; - } - if (gPlayer->steps == gPlayer->stats.speed) { + + if (gPlayer->steps >= gPlayer->stats.speed) { player_reset_steps(gPlayer); roommatrix_update_with_player(gRoomMatrix, gPlayer); map_move_monsters(gMap, gRoomMatrix); diff --git a/src/sprite.c b/src/sprite.c index 945af6c..562cb02 100644 --- a/src/sprite.c +++ b/src/sprite.c @@ -2,13 +2,13 @@ #include "sprite.h" #include "util.h" -static -Sprite* sprite_create_default(void) +static Sprite* +sprite_create_default(void) { Sprite *s = ec_malloc(sizeof(Sprite)); s->textures[0] = NULL; s->textures[1] = NULL; - s->clip = (SDL_Rect) { 0, 0, 16, 16 }; + s->clip = (SDL_Rect) { 0, 0, 0, 0 }; s->destroyTextures = false; s->pos = (Position) { 0, 0 }; s->renderTimer = timer_create(); @@ -19,7 +19,8 @@ Sprite* sprite_create_default(void) return s; } -Sprite* sprite_create() +Sprite* +sprite_create() { return sprite_create_default(); } @@ -43,6 +44,21 @@ sprite_load_texture(Sprite *sprite, sprite->destroyTextures = true; } +void sprite_load_text_texture(Sprite *sprite, char * path, int index, int size) +{ + if (index > 1) + fatal("in sprite_load_texture() index out of bounds"); + + if (sprite->destroyTextures && sprite->textures[index] != NULL) { + texture_destroy(sprite->textures[index]); + sprite->textures[index] = NULL; + } + + sprite->textures[index] = texture_create(); + texture_load_font(sprite->textures[index], path, size); + sprite->destroyTextures = true; +} + void sprite_set_texture(Sprite *s, Texture *t, int index) { @@ -76,10 +92,17 @@ void sprite_render(Sprite *s, Camera *cam) else cameraPos = s->pos; - texture_render_clip(s->textures[s->texture_index], - &cameraPos, - &s->clip, - cam); + if (s->clip.w && s->clip.h) { + texture_render_clip(s->textures[s->texture_index], + &cameraPos, + &s->clip, + cam); + } + else { + texture_render(s->textures[s->texture_index], + &cameraPos, + cam); + } } void sprite_destroy(Sprite *sprite) diff --git a/src/sprite.h b/src/sprite.h index 3275dfa..953fe50 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -24,6 +24,8 @@ Sprite* sprite_create(void); void sprite_load_texture(Sprite *, char *path, int index, SDL_Renderer *); +void sprite_load_text_texture(Sprite *, char *path, int index, int size); + void sprite_set_texture(Sprite *, Texture *, int index); void sprite_render(Sprite*, Camera*);