Some rewrites and lots of nice gui labels

This commit is contained in:
Linus Probert 2018-01-31 20:59:55 +01:00
parent a0b86eb06d
commit 6c1591a92d
5 changed files with 152 additions and 66 deletions

153
src/gui.c
View File

@ -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

View File

@ -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*);

View File

@ -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);

View File

@ -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)

View File

@ -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*);