diff --git a/game.c b/game.c index 7131078..4587cde 100644 --- a/game.c +++ b/game.c @@ -125,6 +125,7 @@ static unsigned level; static bool dead; static unsigned asteroid_count; static uint8_t counter; +static unsigned score; static unsigned ship_entity_id; static unsigned ship_shape_id; @@ -355,6 +356,7 @@ static void destroy_asteroid(entity_t *a, vec2_t shot_vel) { a->dead = true; --asteroid_count; + ++score; float r; if (a->radius == ASTEROID_HUGE) { @@ -491,6 +493,7 @@ static void win() static void reset() { level = INIT_LEVEL; + score = 0; create_field(); } @@ -555,12 +558,14 @@ void game_draw() shapes[i].connect); } + text_draw_score(aspect, score); + if (dead && !(counter & COUNTER_MASK)) - text_draw("GAME OVER"); + text_draw_centre("GAME OVER"); if (!dead && asteroid_count == 0) { draw_arrow(); if (!(counter & COUNTER_MASK)) - text_draw("CLEAR"); + text_draw_centre("CLEAR"); } } diff --git a/text.c b/text.c index 4494f4c..07c0f1a 100644 --- a/text.c +++ b/text.c @@ -13,6 +13,8 @@ #define LETTER_WIDTH 3 #define SPACE_WIDTH 1 +#define MAX_SCORE_CHARS 4 + typedef struct { unsigned line_count; unsigned line_lens[MAX_LINES]; @@ -26,6 +28,93 @@ static const mat3_t text_transform = { }; static const glyph_t font[] = { + ['0'] = { + .line_count = 1, + .line_lens = { 5 }, + .lines = { + { { -1, 4 }, { -1, -4 }, { 1, -4 }, { 1, 4 }, { -1, 4 } }, + }, + }, + ['1'] = { + .line_count = 2, + .line_lens = { 3, 2 }, + .lines = { + { { -1, 4 }, { 0, 4 }, { 0, -4 } }, + { { -1, -4 }, { 1, -4 } }, + }, + }, + ['2'] = { + .line_count = 1, + .line_lens = { 6 }, + .lines = { + { + { -1, 4 }, { 1, 4 }, { 1, -2 }, + { -1, -2 }, { -1, -4 }, { 1, -4 }, + }, + }, + }, + ['3'] = { + .line_count = 1, + .line_lens = { 6 }, + .lines = { + { + { -1, 4 }, { 1, 4 }, { 0, -2 }, + { 1, -2 }, { 1, -4 }, { -1, -4 }, + }, + }, + }, + ['4'] = { + .line_count = 1, + .line_lens = { 4 }, + .lines = { + { { 1, -2 }, { -1, -2 }, { 1, 4 }, { 1, -4 } } + }, + }, + ['5'] = { + .line_count = 1, + .line_lens = { 6 }, + .lines = { + { + { 1, 4 }, { -1, 4 }, { -1, -2 }, + { 1, -2 }, { 1, -4 }, { -1, -4 }, + }, + }, + }, + ['6'] = { + .line_count = 1, + .line_lens = { 6 }, + .lines = { + { + { 1, 4 }, { -1, 4 }, { -1, -4 }, + { 1, -4 }, { 1, -2 }, { -1, -2 }, + }, + }, + }, + ['7'] = { + .line_count = 1, + .line_lens = { 3 }, + .lines = { + { { -1, 4 }, { 1, 4 }, { 0, -4 } }, + }, + }, + ['8'] = { + .line_count = 2, + .line_lens = { 5, 2 }, + .lines = { + { { -1, 4 }, { -1, -4 }, { 1, -4 }, { 1, 4 }, { -1, 4 } }, + { { -1, -2 }, { 1, -2 } }, + }, + }, + ['9'] = { + .line_count = 1, + .line_lens = { 6 }, + .lines = { + { + { 1, -2 }, { -1, -2 }, { -1, 4 }, + { 1, 4 }, { 1, -4 }, { -1, -4 }, + }, + }, + }, ['A'] = { .line_count = 2, .line_lens = { 3, 2 }, @@ -96,7 +185,29 @@ static const glyph_t font[] = { }, }; -void text_draw(const char *s) +static void draw_glyph(unsigned c, vec2_t pos) +{ + assert(c < NELEMS(font) && font[c].line_count != 0); + const glyph_t *g = font + c; + + const mat3_t m = mat3_mul_mat3(mat3_translation(pos), text_transform); + for (unsigned i = 0; i < g->line_count; ++i) + renderer_draw(g->lines[i], g->line_lens[i], m, false); +} + +static void draw_text(const char *s, vec2_t pos) +{ + for (const char *p = s; *p != '\0'; ++p) { + if (*p == ' ') { + pos.x += TEXT_SCALE * SPACE_WIDTH; + } else { + draw_glyph((unsigned)*p, pos); + pos.x += TEXT_SCALE * LETTER_WIDTH; + } + } +} + +void text_draw_centre(const char *s) { int width = 0; for (const char *p = s; *p != '\0'; ++p) @@ -109,23 +220,34 @@ void text_draw(const char *s) }; renderer_clear_rect((vec2_t) { 0, 0 }, bg_size); - int x = -width / 2 + 1; - for (const char *p = s; *p != '\0'; ++p) { - if (*p == ' ') { - x += SPACE_WIDTH; - } else { - const unsigned c = (unsigned)*p; - assert(c < NELEMS(font) && font[c].line_count != 0); - const glyph_t *g = font + c; - - const vec2_t t = { .x = x }; - const mat3_t m - = mat3_mul_mat3(text_transform, mat3_translation(t)); - - for (unsigned i = 0; i < g->line_count; ++i) - renderer_draw(g->lines[i], g->line_lens[i], m, false); - - x += LETTER_WIDTH; - } - } + const vec2_t pos = { TEXT_SCALE * (-width / 2.0f + 1), 0 }; + draw_text(s, pos); +} + +void text_draw_score(float aspect, unsigned score) +{ + char buf[MAX_SCORE_CHARS + 1]; + buf[MAX_SCORE_CHARS] = '\0'; + for (unsigned i = 0; i < MAX_SCORE_CHARS; ++i) { + const unsigned v = score % 10; + score /= 10; + buf[MAX_SCORE_CHARS - 1 - i] = '0' + v; + } + + const int width = LETTER_WIDTH * MAX_SCORE_CHARS - 1; + const vec2_t bg_centre = { + .x = TEXT_SCALE * (width / 2.0f + 2) - aspect, + .y = 1.0f - TEXT_SCALE * (TEXT_HEIGHT / 2.0f + 2), + }; + const vec2_t bg_size = { + .x = TEXT_SCALE * (width + 2), + .y = TEXT_SCALE * (TEXT_HEIGHT + 2), + }; + renderer_clear_rect(bg_centre, bg_size); + + const vec2_t text_pos = { + .x = TEXT_SCALE * 3 - aspect, + .y = bg_centre.y, + }; + draw_text(buf, text_pos); } diff --git a/text.h b/text.h index 6f50f8e..0a9f314 100644 --- a/text.h +++ b/text.h @@ -1,6 +1,7 @@ #ifndef TEXT_H #define TEXT_H -void text_draw(const char *s); +void text_draw_centre(const char *s); +void text_draw_score(float aspect, unsigned score); #endif