diff --git a/src/hiscore.c b/src/hiscore.c index c9169d9..df916e8 100644 --- a/src/hiscore.c +++ b/src/hiscore.c @@ -44,18 +44,29 @@ DbQuery MIGRATE_COMMANDS[] = { }; static int -load_hiscore_cb(void *unused, int count, char **values, char **colNames); +load_hiscore_cb(void *, int count, char **values, char **colNames); static -DbQuery GET_COMMANDS[] = { - { - "SELECT datetime(time, 'localtime') as time, gold, playerLevel, dungeonLevel " - "FROM hiscore " - "ORDER BY gold DESC " - "LIMIT 10", - load_hiscore_cb, NULL - }, - { NULL } +DbQuery GET_TOP_10_COMMAND = { + "SELECT datetime(time, 'localtime') as time, gold, playerLevel, dungeonLevel " + "FROM hiscore " + "ORDER BY gold DESC " + "LIMIT 10", + load_hiscore_cb, + NULL +}; + +static int +load_top_gold_cb(void *, int count, char **values, char **colNames); + +static +DbQuery GET_TOP_GOLD_COMMAND = { + "SELECT gold " + "FROM hiscore " + "ORDER BY gold DESC " + "LIMIT 1", + load_top_gold_cb, + NULL }; static sqlite3 *db = NULL; @@ -152,18 +163,36 @@ LinkedList * hiscore_get_top10(void) { LinkedList *scores = linkedlist_create(); - for (unsigned int i = 0;; ++i) { - DbQuery *query = &GET_COMMANDS[i]; - query->cb_arg = &scores; - if (query->stmt == NULL) - break; - - db_execute(db, query); - } + DbQuery *query = &GET_TOP_10_COMMAND; + query->cb_arg = &scores; + db_execute(db, query); return scores; } + +static int +load_top_gold_cb(void *result, int count, char **values, char **colNames) +{ + UNUSED(count); + UNUSED(colNames); + + double *gold = result; + *gold = atof(values[0]); + return 0; +} + +double +hiscore_get_top_gold(void) +{ + double result; + DbQuery *query = &GET_TOP_GOLD_COMMAND; + query->cb_arg = &result; + db_execute(db, query); + + return result; +} + void hiscore_close(void) { diff --git a/src/hiscore.h b/src/hiscore.h index a70f97c..5bf1844 100644 --- a/src/hiscore.h +++ b/src/hiscore.h @@ -38,6 +38,9 @@ hiscore_register(Player *p, unsigned int dungeonLevel); LinkedList * hiscore_get_top10(void); +double +hiscore_get_top_gold(void); + void hiscore_close(void); diff --git a/src/main.c b/src/main.c index 192a9f8..38b1146 100644 --- a/src/main.c +++ b/src/main.c @@ -70,6 +70,7 @@ static Menu *inGameMenu = NULL; static Timer *menuTimer = NULL; static Camera *gCamera = NULL; static Screen *creditsScreen = NULL; +static Screen *scoreScreen = NULL; static unsigned int cLevel = 1; static float deltaTime = 1.0; static double renderScale = 1.0; @@ -321,11 +322,19 @@ viewCredits(void *unused) gGameState = CREDITS; } +static void +viewScoreScreen(void *unused) +{ + UNUSED(unused); + gGameState = SCORE_SCREEN; +} + static void initMainMenu(void) { struct MENU_ITEM menu_items[] = { { "PLAY", startGame }, + { "SCORES", viewScoreScreen }, { "CREDITS", viewCredits }, { "QUIT", exitGame }, }; @@ -335,9 +344,10 @@ initMainMenu(void) gMap = map_lua_generator_single_room__run(cLevel, gRenderer); - createMenu(&mainMenu, menu_items, 3); + createMenu(&mainMenu, menu_items, 4); mixer_play_music(MENU_MUSIC); creditsScreen = screen_create_credits(gRenderer); + scoreScreen = screen_create_hiscore(gRenderer); } static void @@ -362,6 +372,10 @@ resetGame(void) screen_destroy(creditsScreen); creditsScreen = NULL; + if (scoreScreen) + screen_destroy(scoreScreen); + scoreScreen = NULL; + if (!inGameMenu) initInGameMenu(); @@ -414,6 +428,8 @@ handle_main_input(void) if (gGameState == CREDITS && input_key_is_pressed(&input, KEY_ESC)) gGameState = MENU; + else if (gGameState == SCORE_SCREEN && input_key_is_pressed(&input, KEY_ESC)) + gGameState = MENU; else if (gGameState == MENU && input_key_is_pressed(&input, KEY_ESC)) gGameState = QUIT; @@ -602,12 +618,19 @@ run_game(void) if (gGameState == PLAYING && is_player_dead()) { camera_shake(VECTOR2D_RIGHT, 800); gui_log("The dungeon consumed you"); + gui_log("You earned %.2f gold", gPlayer->gold); gui_event_message("You died!"); + gui_event_message("You earned %.2f gold", gPlayer->gold); + if (hiscore_get_top_gold() < gPlayer->gold) { + gui_event_message("NEW HIGHSCORE"); + gui_log("NEW HIGHSCORE"); + } gui_event_message("Press ESC to open menu"); mixer_play_effect(SPLAT); gGameState = GAME_OVER; createInGameGameOverMenu(); hiscore_register(gPlayer, cLevel); + } else { check_next_level(); } @@ -628,7 +651,7 @@ run_menu(void) } menu_update(mainMenu, &input); - if (gGameState != MENU && gGameState != CREDITS) + if (gGameState != MENU && gGameState != CREDITS && gGameState != SCORE_SCREEN) return; SDL_SetRenderDrawColor(gRenderer, 0, 0, 0, 0); @@ -645,6 +668,8 @@ run_menu(void) menu_render(mainMenu, gCamera); else if (gGameState == CREDITS) screen_render(creditsScreen, gCamera); + else if (gGameState == SCORE_SCREEN) + screen_render(scoreScreen, gCamera); pointer_render(gPointer, gCamera); @@ -676,6 +701,7 @@ void run(void) break; case MENU: case CREDITS: + case SCORE_SCREEN: run_menu(); break; case QUIT: @@ -714,6 +740,8 @@ void close(void) menu_destroy(mainMenu); if (creditsScreen) screen_destroy(creditsScreen); + if (scoreScreen) + screen_destroy(scoreScreen); if (inGameMenu) menu_destroy(inGameMenu); diff --git a/src/screen.c b/src/screen.c index ce7850c..b5ac28e 100644 --- a/src/screen.c +++ b/src/screen.c @@ -18,6 +18,7 @@ #include "screen.h" #include "util.h" +#include "hiscore.h" static Screen * screen_create(void) @@ -29,11 +30,23 @@ screen_create(void) } static Sprite * -create_text_sprite(const char *msg, int x, int y, SDL_Renderer *renderer) +credit_txt(const char *msg, SDL_Color color, int x, int y, SDL_Renderer *renderer) { Sprite *s = sprite_create(); sprite_load_text_texture(s, "GUI/SDS_8x8.ttf", 0, 14, 1); - texture_load_from_text(s->textures[0], msg, C_WHITE, C_BLACK, renderer); + texture_load_from_text(s->textures[0], msg, color, C_BLACK, renderer); + s->pos = (Position) { x, y }; + s->fixed = true; + s->dim = s->textures[0]->dim; + return s; +} + +static Sprite * +score_txt(const char *msg, SDL_Color color, int x, int y, SDL_Renderer *renderer) +{ + Sprite *s = sprite_create(); + sprite_load_text_texture(s, "GUI/SDS_8x8.ttf", 0, 10, 1); + texture_load_from_text(s->textures[0], msg, color, C_BLACK, renderer); s->pos = (Position) { x, y }; s->fixed = true; s->dim = s->textures[0]->dim; @@ -48,37 +61,106 @@ screen_create_credits(SDL_Renderer *renderer) unsigned int columnOffset = 160; Screen *screen = screen_create(); - linkedlist_push(&screen->sprites, create_text_sprite("- Game -", x, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("- Game -", C_BLUE, x, y, renderer)); y += 30; - linkedlist_push(&screen->sprites, create_text_sprite("Code:", x, y, renderer)); - linkedlist_push(&screen->sprites, create_text_sprite("Linus Probert", x + columnOffset, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("Code:", C_YELLOW, x, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("Linus Probert", C_WHITE, x + columnOffset, y, renderer)); y += 20; - linkedlist_push(&screen->sprites, create_text_sprite("liquidityc.github.io", x + columnOffset, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("liquidityc.github.io", C_WHITE, x + columnOffset, y, renderer)); y += 20; - linkedlist_push(&screen->sprites, create_text_sprite("@LiquidityC", x + columnOffset, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("@LiquidityC", C_WHITE, x + columnOffset, y, renderer)); y += 60; - linkedlist_push(&screen->sprites, create_text_sprite(" - Graphics -", x, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt(" - Graphics -", C_BLUE, x, y, renderer)); y += 30; - linkedlist_push(&screen->sprites, create_text_sprite("Palette:", x, y, renderer)); - linkedlist_push(&screen->sprites, create_text_sprite("DawnBringer", x + columnOffset, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("Palette:", C_YELLOW, x, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("DawnBringer", C_WHITE, x + columnOffset, y, renderer)); y += 60; - linkedlist_push(&screen->sprites, create_text_sprite(" - Music and Sound -", x, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt(" - Music and Sound -", C_BLUE, x, y, renderer)); y += 30; - linkedlist_push(&screen->sprites, create_text_sprite("Music:", x, y, renderer)); - linkedlist_push(&screen->sprites, create_text_sprite("Eric Matyas", x + columnOffset, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("Music:", C_YELLOW, x, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("Eric Matyas", C_WHITE, x + columnOffset, y, renderer)); y += 20; - linkedlist_push(&screen->sprites, create_text_sprite("www.soundimage.org", x + columnOffset, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("www.soundimage.org", C_WHITE, x + columnOffset, y, renderer)); y += 30; - linkedlist_push(&screen->sprites, create_text_sprite("Sound:", x, y, renderer)); - linkedlist_push(&screen->sprites, create_text_sprite("Eric Matyas", x + columnOffset, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("Sound:", C_YELLOW, x, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("Eric Matyas", C_WHITE, x + columnOffset, y, renderer)); y += 20; - linkedlist_push(&screen->sprites, create_text_sprite("www.soundimage.org", x + columnOffset, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("www.soundimage.org", C_WHITE, x + columnOffset, y, renderer)); y += 30; - linkedlist_push(&screen->sprites, create_text_sprite("ArtisticDuded", x + columnOffset, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("ArtisticDuded", C_WHITE, x + columnOffset, y, renderer)); y += 20; - linkedlist_push(&screen->sprites, create_text_sprite("opengameart.org/users/artisticdude", x + columnOffset, y, renderer)); + linkedlist_push(&screen->sprites, credit_txt("opengameart.org/users/artisticdude", C_WHITE, x + columnOffset, y, renderer)); + return screen; +} + +Screen * +screen_create_hiscore(SDL_Renderer *renderer) +{ + Screen *screen = screen_create(); + int y = 40; + int dateCol = 50; + int goldCol = 250; + int lvlCol = 400; + int dlvlCol = 550; + + linkedlist_push(&screen->sprites, score_txt("Date", + C_GREEN, + dateCol, + y, + renderer)); + linkedlist_push(&screen->sprites, score_txt("Gold", + C_GREEN, + goldCol, + y, + renderer)); + linkedlist_push(&screen->sprites, score_txt("Level", + C_GREEN, + lvlCol, + y, + renderer)); + linkedlist_push(&screen->sprites, score_txt("Depth", + C_GREEN, + dlvlCol, + y, + renderer)); + + LinkedList *scores = hiscore_get_top10(); + while (scores) { + y += 30; + HiScore *score = linkedlist_pop(&scores); + char content[80]; + m_sprintf(content, 80, "%s", score->timestamp); + linkedlist_push(&screen->sprites, + score_txt(content, + C_WHITE, + dateCol, + y, + renderer)); + m_sprintf(content, 80, "%.2lf", score->gold); + linkedlist_push(&screen->sprites, + score_txt(content, + C_YELLOW, + goldCol, + y, + renderer)); + m_sprintf(content, 80, "%d", score->playerLevel); + linkedlist_push(&screen->sprites, + score_txt(content, + C_BLUE, + lvlCol, + y, + renderer)); + m_sprintf(content, 80, "%d", score->dungeonLevel); + linkedlist_push(&screen->sprites, + score_txt(content, + C_RED, + dlvlCol, + y, + renderer)); + hiscore_destroy(score); + } return screen; } diff --git a/src/screen.h b/src/screen.h index fbccdd7..3721c11 100644 --- a/src/screen.h +++ b/src/screen.h @@ -30,6 +30,9 @@ typedef struct Screen { Screen * screen_create_credits(SDL_Renderer*); +Screen * +screen_create_hiscore(SDL_Renderer*); + void screen_render(Screen *screen, Camera *cam);