Added nice info messages across the screen

This commit is contained in:
Linus Probert 2018-03-07 16:02:56 +01:00
parent cc2b659020
commit 5e0bbe423d
6 changed files with 150 additions and 10 deletions

121
src/gui.c
View File

@ -28,6 +28,7 @@
#include "texturecache.h" #include "texturecache.h"
#define DEFAULT_LOG { NULL, 50, 0, 200 } #define DEFAULT_LOG { NULL, 50, 0, 200 }
#define DEFAULT_EVENT_MESSAGES { NULL, 5, 0, 200 }
#define POS_Y_COLLECTABLES 64 #define POS_Y_COLLECTABLES 64
#define POS_Y_XPBAR 112 #define POS_Y_XPBAR 112
@ -49,6 +50,13 @@ static struct LogData_t {
unsigned int strlen; unsigned int strlen;
} log_data = DEFAULT_LOG; } log_data = DEFAULT_LOG;
static struct GuiEventMsgData_t {
char **messages;
unsigned int len;
unsigned int count;
unsigned int strlen;
} event_messages = DEFAULT_EVENT_MESSAGES;
static void static void
gui_malloc_log(void) gui_malloc_log(void)
{ {
@ -62,6 +70,19 @@ gui_malloc_log(void)
log_data.log[i] = NULL; log_data.log[i] = NULL;
} }
static void
gui_malloc_eventmessages(void)
{
if (event_messages.messages != NULL)
return;
unsigned int i;
event_messages.messages = ec_malloc(event_messages.len * sizeof(char*));
for (i = 0; i < event_messages.len; ++i)
event_messages.messages[i] = NULL;
}
static Sprite* static Sprite*
create_xp_sprite(Texture *t, SDL_Rect clip, Position pos) create_xp_sprite(Texture *t, SDL_Rect clip, Position pos)
{ {
@ -160,6 +181,10 @@ gui_create(void)
gui->log_lines[i] = t; gui->log_lines[i] = t;
} }
gui->event_message = texture_create();
texture_load_font(gui->event_message, "GUI/SDS_8x8.ttf", EVENT_MESSAGE_FONT_SIZE);
gui->event_message_timer = timer_create();
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] = create_label_sprite((Position) { 16, POS_Y_XPBAR + 18 + (2*14) });
@ -167,6 +192,7 @@ gui_create(void)
gui->labels[GOLD_LABEL] = create_label_sprite((Position) { 32, POS_Y_COLLECTABLES + 16 + 5 }); gui->labels[GOLD_LABEL] = create_label_sprite((Position) { 32, POS_Y_COLLECTABLES + 16 + 5 });
gui_malloc_log(); gui_malloc_log();
gui_malloc_eventmessages();
init_sprites(gui); init_sprites(gui);
@ -406,17 +432,13 @@ gui_log(const char *fmt, ...)
char tstamp[10]; char tstamp[10];
va_list args; va_list args;
va_start(args, fmt);
#ifndef _MSC_VER
vsprintf(buffer, fmt, args);
#else // _MSC_VER
vsprintf_s(buffer, log_data.strlen, fmt, args);
#endif // _MSC_VER
va_end(args);
new_message = ec_malloc(log_data.strlen * sizeof(char)); new_message = ec_malloc(log_data.strlen * sizeof(char));
timestamp(tstamp, 10); timestamp(tstamp, 10);
va_start(args, fmt);
m_vsprintf(buffer, 200, fmt, args);
va_end(args);
m_sprintf(new_message, log_data.strlen, "%s > %s", tstamp, buffer); m_sprintf(new_message, log_data.strlen, "%s > %s", tstamp, buffer);
log_data.count++; log_data.count++;
@ -431,6 +453,25 @@ gui_log(const char *fmt, ...)
log_data.log[0] = new_message; log_data.log[0] = new_message;
} }
void
gui_event_message(const char *fmt, ...)
{
char *new_message = ec_malloc(sizeof(char) * event_messages.strlen);
va_list args;
va_start(args, fmt);
m_vsprintf(new_message, event_messages.strlen, fmt, args);
va_end(args);
if (event_messages.count == event_messages.len) {
error("To many event messages");
free(new_message);
return;
}
event_messages.messages[event_messages.count] = new_message;
event_messages.count++;
}
void void
gui_render_log(Gui *gui, unsigned int width, unsigned int height, Camera *cam) gui_render_log(Gui *gui, unsigned int width, unsigned int height, Camera *cam)
{ {
@ -455,6 +496,53 @@ gui_render_log(Gui *gui, unsigned int width, unsigned int height, Camera *cam)
} }
} }
void
gui_render_event_message(Gui *gui, Camera *cam)
{
static SDL_Color color = { 255, 255, 255, 255 };
static SDL_Rect box = { 0, 0, 150, 50 };
if (timer_started(gui->event_message_timer)
&& timer_get_ticks(gui->event_message_timer) < EVENT_MESSAGE_DISPLAY_TIME)
{
texture_render(gui->event_message, &box, cam);
return;
}
if (event_messages.count > 0) {
texture_load_from_text(gui->event_message,
event_messages.messages[0],
color,
cam->renderer);
box.x = (GAME_VIEW_WIDTH/2) - (gui->event_message->dim.width/2);
box.y = (GAME_VIEW_HEIGHT/2) - (gui->event_message->dim.height/2);
box.w = gui->event_message->dim.width;
box.h = gui->event_message->dim.height;
free(event_messages.messages[0]);
for (size_t i = 1; i < event_messages.count; ++i) {
event_messages.messages[i-1] = event_messages.messages[i];
}
event_messages.count--;
texture_render(gui->event_message, &box, cam);
timer_start(gui->event_message_timer);
}
}
void
gui_clear_message_log(void)
{
for (size_t i = 0; i < event_messages.count; ++i)
free(event_messages.messages[i]);
event_messages.count = 0;
for (size_t i = 0; i < log_data.count; ++i)
free(log_data.log[i]);
log_data.count = 0;
}
static void static void
destroy_log(void) destroy_log(void)
{ {
@ -469,10 +557,27 @@ destroy_log(void)
log_data.log = NULL; log_data.log = NULL;
} }
static void
destroy_event_messages(void)
{
if (event_messages.messages == NULL)
return;
for (unsigned int i = 0; i < event_messages.count; ++i)
free(event_messages.messages[i]);
free(event_messages.messages);
event_messages.messages = NULL;
}
void void
gui_destroy(Gui *gui) gui_destroy(Gui *gui)
{ {
destroy_log(); destroy_log();
destroy_event_messages();
timer_destroy(gui->event_message_timer);
texture_destroy(gui->event_message);
while (gui->sprites != NULL) while (gui->sprites != NULL)
sprite_destroy(linkedlist_pop(&gui->sprites)); sprite_destroy(linkedlist_pop(&gui->sprites));

View File

@ -23,10 +23,14 @@
#define LOG_FONT_SIZE 8 #define LOG_FONT_SIZE 8
#define LABEL_FONT_SIZE 8 #define LABEL_FONT_SIZE 8
#define EVENT_MESSAGE_DISPLAY_TIME 2500
#define EVENT_MESSAGE_FONT_SIZE 20
#include "linkedlist.h" #include "linkedlist.h"
#include "sprite.h" #include "sprite.h"
#include "camera.h" #include "camera.h"
#include "player.h" #include "player.h"
#include "timer.h"
typedef enum Label_e { typedef enum Label_e {
LEVEL_LABEL, LEVEL_LABEL,
@ -43,6 +47,8 @@ typedef struct {
LinkedList *xp_bar; LinkedList *xp_bar;
Sprite *labels[LABEL_COUNT]; Sprite *labels[LABEL_COUNT];
Texture *log_lines[LOG_LINES_COUNT]; Texture *log_lines[LOG_LINES_COUNT];
Texture *event_message;
Timer *event_message_timer;
} Gui; } Gui;
Gui* Gui*
@ -57,9 +63,18 @@ gui_render_panel(Gui*, unsigned int width, unsigned int height, Camera*);
void void
gui_render_log(Gui*, unsigned int width, unsigned int height, Camera*); gui_render_log(Gui*, unsigned int width, unsigned int height, Camera*);
void
gui_render_event_message(Gui*, Camera*);
void void
gui_log(const char *fmt, ...); gui_log(const char *fmt, ...);
void
gui_event_message(const char *fmt, ...);
void
gui_clear_message_log(void);
void void
gui_destroy(Gui*); gui_destroy(Gui*);

View File

@ -205,6 +205,9 @@ startGame(void *unused)
gPlayer = player_create(WARRIOR, gRenderer); gPlayer = player_create(WARRIOR, gRenderer);
mixer_play_music(GAME_MUSIC0 + get_random(2)); mixer_play_music(GAME_MUSIC0 + get_random(2));
resetGame(); resetGame();
gui_clear_message_log();
gui_log("The Dungeon Crawl begins!");
gui_event_message("Welcome to the dungeon!");
} }
static void static void
@ -483,6 +486,7 @@ run_game(void)
roommatrix_render_mouse_square(gRoomMatrix, &gCamera); roommatrix_render_mouse_square(gRoomMatrix, &gCamera);
roommatrix_render_lightmap(gRoomMatrix, &gCamera); roommatrix_render_lightmap(gRoomMatrix, &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, RIGHT_GUI_WIDTH,
@ -511,6 +515,7 @@ run_game(void)
if (gGameState == PLAYING && is_player_dead()) { if (gGameState == PLAYING && is_player_dead()) {
gui_log("The dungeon consumed you"); gui_log("The dungeon consumed you");
gui_event_message("You died!");
mixer_play_effect(SPLAT); mixer_play_effect(SPLAT);
gGameState = GAME_OVER; gGameState = GAME_OVER;
} }
@ -554,8 +559,6 @@ void run(void)
bool quit = false; bool quit = false;
Timer* fpsTimer = timer_create(); Timer* fpsTimer = timer_create();
gui_log("The Dungeon Crawl begins!");
while (!quit) while (!quit)
{ {
timer_start(fpsTimer); timer_start(fpsTimer);

View File

@ -74,6 +74,7 @@ player_gain_xp(Player *player, unsigned int xp_gain)
if (player->xp >= next_level_threshold(player->stats.lvl)) { if (player->xp >= next_level_threshold(player->stats.lvl)) {
player_levelup(player); player_levelup(player);
gui_log("You have reached level %u", player->stats.lvl); gui_log("You have reached level %u", player->stats.lvl);
gui_event_message("You reached level %u", player->stats.lvl);
} }
} }

View File

@ -72,6 +72,17 @@ m_sprintf(char * dest, size_t destsz, const char * format, ...)
va_end(args); va_end(args);
} }
void
m_vsprintf(char *dest, size_t sz, const char *fmt, va_list args)
{
#ifndef _MSC_VER
UNUSED (sz);
vsprintf(dest, fmt, args);
#else // _MSC_VER
vsprintf_s(dest, sz, fmt, args);
#endif // _MSC_VER
}
void void
debug(const char *fmt, ...) debug(const char *fmt, ...)
{ {

View File

@ -19,6 +19,8 @@
#ifndef UTIL_H_ #ifndef UTIL_H_
#define UTIL_H_ #define UTIL_H_
#include <stdarg.h>
void void
fatal(const char *fmt, ...); fatal(const char *fmt, ...);
@ -43,6 +45,9 @@ m_strncat(char *dest, size_t destsz, char *src, size_t srcsz);
void void
m_sprintf(char *dest, size_t destsz, const char *format, ...); m_sprintf(char *dest, size_t destsz, const char *format, ...);
void
m_vsprintf(char *dest, size_t sz, const char *fmt, va_list args);
void void
timestamp(char *tstamp, size_t sz); timestamp(char *tstamp, size_t sz);