diff --git a/libc3/window/sdl2/demo/matrix.c b/libc3/window/sdl2/demo/matrix.c
index 827b089..b91e7a4 100644
--- a/libc3/window/sdl2/demo/matrix.c
+++ b/libc3/window/sdl2/demo/matrix.c
@@ -28,8 +28,11 @@ static s_gl_sprite g_matrix_shade = {0};
static f64 g_matrix_time;
void matrix_column_clean (s_tag *tag);
-bool matrix_column_init (s_sequence *seq, s_tag *tag, f32 x);
+bool matrix_column_init (s_sequence *seq, s_tag *tag);
bool matrix_column_render (s_sequence *seq, s_tag *tag);
+void matrix_screen_clean (s_tag *tag);
+bool matrix_screen_init (s_tag *tag);
+bool matrix_screen_render (s_sequence *seq, s_tag *tag);
void matrix_text_clean (s_tag *tag);
bool matrix_text_init (s_tag *tag, f32 y);
bool matrix_text_render (s_sequence *seq, const s_tag *tag, f32 **py);
@@ -50,11 +53,10 @@ void matrix_column_clean (s_tag *tag)
}
}
-bool matrix_column_init (s_sequence *seq, s_tag *tag, f32 x)
+bool matrix_column_init (s_sequence *seq, s_tag *tag)
{
s_list *list;
s_window_sdl2 *window;
- (void) x;
assert(seq);
window = seq->window;
assert(window);
@@ -78,7 +80,8 @@ bool matrix_column_render (s_sequence *seq, s_tag *tag)
assert(glGetError() == GL_NO_ERROR);
window = seq->window;
assert(window);
- if (tag->type != TAG_LIST) {
+ if (!tag ||
+ tag->type != TAG_LIST) {
err_puts("matrix_column_render: invalid tag");
assert(! "matrix_column_render: invalid tag");
return false;
@@ -117,7 +120,7 @@ bool matrix_load (s_sequence *seq)
point_per_pixel))
return false;
gl_font_set_size(&g_matrix_font, MATRIX_FONT_SIZE);
- if (! matrix_column_init(seq, &seq->tag, 0))
+ if (! matrix_screen_init(&seq->tag))
return false;
if (! gl_sprite_init(&g_matrix_shade,
"img/matrix_shade.png",
@@ -133,13 +136,82 @@ bool matrix_render (s_sequence *seq)
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
assert(glGetError() == GL_NO_ERROR);
- matrix_column_render(seq, &seq->tag);
+ matrix_screen_render(seq, &seq->tag);
assert(glGetError() == GL_NO_ERROR);
if (seq->t - g_matrix_time > MATRIX_TIME)
g_matrix_time = seq->t;
return true;
}
+void matrix_screen_clean (s_tag *tag)
+{
+ s_list *list;
+ if (! tag ||
+ tag->type != TAG_LIST) {
+ err_puts("matrix_screen_clean: invalid tag");
+ assert(! "matrix_screen_clean: invalid tag");
+ return;
+ }
+ list = tag->data.list;
+ while (list) {
+ matrix_column_clean(&list->tag);
+ list = list_delete(list);
+ }
+}
+
+bool matrix_screen_init (s_tag *tag)
+{
+ tag_init_list(tag, NULL);
+ return true;
+}
+
+bool matrix_screen_render (s_sequence *seq, s_tag *tag)
+{
+ s_list **l;
+ s_list *list;
+ s_mat4 matrix;
+ s_window_sdl2 *window;
+ f32 x;
+ assert(seq);
+ window = seq->window;
+ assert(window);
+ if (! tag ||
+ tag->type != TAG_LIST) {
+ err_puts("matrix_screen_render: invalid tag");
+ assert(! "matrix_screen_render: invalid tag");
+ return false;
+ }
+ x = 0;
+ l = &tag->data.list;
+ while (*l) {
+ if (x > window->w) {
+ matrix_column_clean(&(*l)->tag);
+ *l = list_delete(*l);
+ }
+ else {
+ x += MATRIX_FONT_SIZE;
+ l = &(*l)->next.data.list;
+ }
+ }
+ while (x < window->w) {
+ *l = list_new(NULL);
+ if (! matrix_column_init(seq, &(*l)->tag))
+ return false;
+ x += MATRIX_FONT_SIZE;
+ l = &(*l)->next.data.list;
+ }
+ matrix = g_ortho.model_matrix; {
+ list = tag->data.list;
+ while (list) {
+ if (! matrix_column_render(seq, &list->tag))
+ return false;
+ mat4_translate(&g_ortho.model_matrix, MATRIX_FONT_SIZE, 0, 0);
+ list = list_next(list);
+ }
+ } g_ortho.model_matrix = matrix;
+ return true;
+}
+
bool matrix_text_init (s_tag *tag, f32 y)
{
char a[1024];
@@ -230,21 +302,24 @@ void matrix_text_clean (s_tag *tag)
{
s_map *map;
s_gl_text *text;
- if (tag->type == TAG_MAP &&
- (map = &tag->data.map) &&
- map->count == 3 &&
- map->key[1].type == TAG_SYM &&
- map->key[1].data.sym == sym_1("text") &&
- map->value[1].type == TAG_PTR &&
- (text = map->value[1].data.ptr.p)) {
- gl_vtext_clean(text);
+ if (! (tag->type == TAG_MAP &&
+ (map = &tag->data.map) &&
+ map->count == 3 &&
+ map->key[1].type == TAG_SYM &&
+ map->key[1].data.sym == sym_1("text") &&
+ map->value[1].type == TAG_PTR &&
+ (text = map->value[1].data.ptr.p))) {
+ err_puts("matrix_text_clean: invalid tag");
+ assert(! "matrix_text_clean: invalid tag");
+ return;
}
+ gl_vtext_clean(text);
}
bool matrix_unload (s_sequence *seq)
{
assert(seq);
- matrix_text_clean(&seq->tag);
+ matrix_screen_clean(&seq->tag);
tag_void(&seq->tag);
gl_font_clean(&g_matrix_font);
return true;
diff --git a/libc3/window/sdl2/gl_vtext.c b/libc3/window/sdl2/gl_vtext.c
index 2603ab2..b12ec93 100644
--- a/libc3/window/sdl2/gl_vtext.c
+++ b/libc3/window/sdl2/gl_vtext.c
@@ -173,7 +173,7 @@ bool gl_vtext_render_to_texture (s_gl_text *text)
x = (data_w - (glyph->metrics.width >> 6)) / 2;
i = 0;
while (i < glyph->bitmap.rows) {
- data_y = data_h - 1 - (y + i + max_ascent - glyph->bitmap_top);
+ data_y = data_h - line_height - 1 - (y + i + max_ascent - glyph->bitmap_top);
//printf("\n");
j = 0;
while (j < glyph->bitmap.width) {
@@ -210,25 +210,25 @@ bool gl_vtext_render_to_texture_random (s_gl_text *text, uw len)
{
FT_UInt *glyphs;
u8 *data;
- uw data_w;
- uw data_h;
+ sw data_w;
+ sw data_h;
u8 *data_pixel;
- uw data_size;
- uw data_x;
- uw data_y;
+ sw data_size;
+ sw data_x;
+ sw data_y;
FT_Face face;
const s_gl_font *font;
FT_GlyphSlot glyph;
FT_UInt glyph_index;
- uw i;
- uw j;
- uw k;
- uw line_height;
- uw max_ascent;
- uw max_descent;
+ sw i;
+ sw j;
+ sw k;
+ sw line_height;
+ sw max_ascent;
+ sw max_descent;
f32 scale_y;
- uw x;
- uw y;
+ sw x;
+ sw y;
assert(text);
assert(text->font);
assert(text->texture);
@@ -245,7 +245,7 @@ bool gl_vtext_render_to_texture_random (s_gl_text *text, uw len)
" failed to allocate memory");
return false;
}
- for (i = 0; i < len; i++) {
+ for (i = 0; i < (sw) len; i++) {
do {
u32_random_uniform(glyphs + i, face->num_glyphs - 2);
glyphs[i]++;
@@ -262,7 +262,7 @@ bool gl_vtext_render_to_texture_random (s_gl_text *text, uw len)
data_w = 0;
data_h = 0;
x = 0;
- for (i = 0; i < len; i++) {
+ for (i = 0; i < (sw) len; i++) {
glyph_index = glyphs[i];
if (FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER)) {
err_write_1("gl_vtext_render_to_texture_random: failed to load glyph: ");
@@ -276,11 +276,13 @@ bool gl_vtext_render_to_texture_random (s_gl_text *text, uw len)
data_w = x;
data_h += line_height;
}
+ data_w++;
+ data_h += line_height * 2;
data_size = data_w * data_h * 4;
data = calloc(1, data_size);
x = 0;
y = 0;
- for (i = 0; i < len; i++) {
+ for (i = 0; i < (sw) len; i++) {
glyph_index = glyphs[i];
if (FT_Load_Glyph(face, glyph_index, FT_LOAD_RENDER))
continue;
@@ -288,7 +290,8 @@ bool gl_vtext_render_to_texture_random (s_gl_text *text, uw len)
x = (data_w - (glyph->metrics.width >> 6)) / 2;
j = 0;
while (j < glyph->bitmap.rows) {
- data_y = data_h - 1 - (y + j + max_ascent - glyph->bitmap_top);
+ data_y = data_h - line_height - 1 -
+ ((sw) y + j + max_ascent - glyph->bitmap_top);
//printf("\n");
k = 0;
while (k < glyph->bitmap.width) {