Create text module for displaying messages
This commit is contained in:
117
text.c
Normal file
117
text.c
Normal file
@@ -0,0 +1,117 @@
|
||||
#include "text.h"
|
||||
|
||||
#include "renderer.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
#define MAX_LINES 2
|
||||
|
||||
#define TEXT_HEIGHT 8
|
||||
#define TEXT_SCALE 0.025
|
||||
#define LETTER_WIDTH 3
|
||||
#define SPACE_WIDTH 1
|
||||
|
||||
typedef struct {
|
||||
unsigned line_count;
|
||||
unsigned line_lens[MAX_LINES];
|
||||
vec2_t lines[MAX_LINES][MAX_VERTS];
|
||||
} glyph_t;
|
||||
|
||||
static const mat3_t text_transform = {
|
||||
{ TEXT_SCALE, 0, 0 },
|
||||
{ 0, TEXT_SCALE, 0 },
|
||||
{ 0, 0, 1 },
|
||||
};
|
||||
|
||||
static const glyph_t font[] = {
|
||||
['A'] = {
|
||||
.line_count = 2,
|
||||
.line_lens = { 3, 2 },
|
||||
.lines = {
|
||||
{ { -1, -4 }, { 0, 4 }, { 1, -4 } },
|
||||
{ { -0.75, -2 }, { 0.75, -2 } },
|
||||
},
|
||||
},
|
||||
['E'] = {
|
||||
.line_count = 2,
|
||||
.line_lens = { 4, 2 },
|
||||
.lines = {
|
||||
{ { 1, 4 }, { -1, 4 }, { -1, -4 }, { 1, -4 } },
|
||||
{ { -1, -2 }, { 0, -2 } },
|
||||
},
|
||||
},
|
||||
['G'] = {
|
||||
.line_count = 1,
|
||||
.line_lens = { 5 },
|
||||
.lines = {
|
||||
{ { 1, 4 }, { -1, 4 }, { -1, -4 }, { 1, -4 }, { 1, -2 } },
|
||||
},
|
||||
},
|
||||
['M'] = {
|
||||
.line_count = 1,
|
||||
.line_lens = { 5 },
|
||||
.lines = {
|
||||
{ { -1, -4 }, { -1, 4 }, { 0, -4 }, { 1, 4 }, { 1, -4 } },
|
||||
},
|
||||
},
|
||||
['O'] = {
|
||||
.line_count = 1,
|
||||
.line_lens = { 5 },
|
||||
.lines = {
|
||||
{ { -1, 4 }, { -1, -4 }, { 1, -4 }, { 1, 4 }, { -1, 4 } },
|
||||
},
|
||||
},
|
||||
['R'] = {
|
||||
.line_count = 1,
|
||||
.line_lens = { 6 },
|
||||
.lines = {
|
||||
{
|
||||
{ -1, -4 }, { -1, 4 }, { 1, 4 },
|
||||
{ 1, -2 }, { -1, -2 }, { 1, -4 },
|
||||
},
|
||||
},
|
||||
},
|
||||
['V'] = {
|
||||
.line_count = 1,
|
||||
.line_lens = { 3 },
|
||||
.lines = {
|
||||
{ { -1, 4 }, { 0, -4 }, { 1, 4 } },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
void text_draw(const char *s)
|
||||
{
|
||||
int width = 0;
|
||||
for (const char *p = s; *p != '\0'; ++p)
|
||||
width += *p == ' ' ? SPACE_WIDTH : LETTER_WIDTH;
|
||||
--width;
|
||||
|
||||
const vec2_t bg_size = {
|
||||
.x = TEXT_SCALE * (width + 2),
|
||||
.y = TEXT_SCALE * (TEXT_HEIGHT + 2),
|
||||
};
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user