diff options
| -rw-r--r-- | dc/dc.c | 85 | ||||
| -rw-r--r-- | teensy/teensy.h | 16 | ||||
| -rw-r--r-- | teensy/teensy_renderer.c | 54 |
3 files changed, 147 insertions, 8 deletions
@@ -13,6 +13,7 @@ #define TILE_SIZE 16 struct ty_image img; +struct ty_font font; void tick(void) { @@ -59,10 +60,57 @@ void tick(void) ty_color(0xFF, 0xF0, 0x80) ); - ty_draw_end(); + ty_draw_text(&font, ty_vec2i(5, SCREEN_HEIGHT - 5 - 8), "hello, world!"); double frame_time = ty_get_time() - start; - ty_log_debug("%g ms, %g FPS", frame_time * 1000, 1.0 / frame_time); + + char ms_fmt[] = "%.2g ms"; + int ms_width = ty_font_width(&font, ms_fmt, frame_time * 1000); + + ty_draw_rect( + (struct ty_recti){ + 5, 5, + ms_width, 8, + }, + TY_COLOR_BLACK + ); + ty_draw_text_fmt( + &font, + ty_vec2i(5, 5), + ms_fmt, + frame_time * 1000 + ); + + char fps_fmt[] = "%4d fps"; + int fps_width = ty_font_width(&font, fps_fmt, (int)(1.0 / frame_time)); + + ty_draw_rect( + (struct ty_recti){ + 5, 5 + 8, + fps_width, 8, + }, + TY_COLOR_BLACK + ); + ty_draw_text_fmt( + &font, + ty_vec2i(5, 5 + 8), + fps_fmt, + (int)(1.0 / frame_time) + ); + + ty_draw_end(); +} + +struct ty_image load_qoi_image(const char *path) +{ + qoi_desc desc; + void *data = qoi_read(path, &desc, 3); + if (!data) + ty_log_fatal(TY_ERR_IO, "failed to read image"); + struct ty_image img = ty_create_image(desc.width, desc.height, data); + free(data); + + return img; } int main(void) @@ -75,21 +123,42 @@ int main(void) }; ty_init(hints); - qoi_desc desc; - void *data = qoi_read("test_img.qoi", &desc, 3); - if (!data) - ty_log_fatal(TY_ERR_IO, "failed to read image"); - img = ty_create_image(desc.width, desc.height, data); - free(data); + img = load_qoi_image("test_img.qoi"); + + char font_chars[] = + "abcdefghijklmnopqrstuvwxyz0123456789" + "!\"'#$%&()*+,-./@[]\\^_`{}|~:;<>=? " + ; + struct ty_image font_img = load_qoi_image("font.qoi"); + + int glyph_height = 8; + + for (int i = 0; font_chars[i] != '\0'; i++) { + struct ty_image glyph = ty_create_image( + font_img.width, + glyph_height, + font_img.data + font_img.width * glyph_height * i + ); + + + ty_font_add_glyph( + &font, + *(uint8_t*)&font_chars[i], + glyph + ); + } while (ty_is_game_running()) { int ticks = ty_tick(); for (int i = 0; i < ticks; i++) tick(); + + ty_free_temp_allocs(); // ty_sleep(1000 / hints.ticrate); } ty_free_image(img); + ty_free_image(font_img); ty_deinit(); return 0; diff --git a/teensy/teensy.h b/teensy/teensy.h index 1f082f9..0b7829c 100644 --- a/teensy/teensy.h +++ b/teensy/teensy.h @@ -1,6 +1,8 @@ #ifndef TEENSY_H_ #define TEENSY_H_ +#include <limits.h> + #include "teensy_common.h" #include "teensy_context.h" #include "teensy_list.h" @@ -68,6 +70,10 @@ struct ty_image { int height; }; +struct ty_font { + struct ty_image glyphs[CHAR_MAX]; +}; + struct ty_renderer { struct ty_image screen; }; @@ -92,6 +98,9 @@ void ty_img_set_pixel( struct ty_color color ); +void ty_font_add_glyph(struct ty_font *font, uint8_t c, struct ty_image img); +int ty_font_width(struct ty_font *font, const char *fmt, ...); + void ty_draw_clear(struct ty_color col); void ty_draw_image(struct ty_image img, struct ty_vec2i pos); void ty_draw_image_ex( @@ -105,6 +114,13 @@ void ty_draw_line( struct ty_vec2i end, struct ty_color color ); +void ty_draw_text(struct ty_font *font, struct ty_vec2i pos, const char *text); +void ty_draw_text_fmt( + struct ty_font *font, + struct ty_vec2i pos, + const char *fmt, + ... +); void ty_draw_end(void); void ty_sleep(uint64_t ms); diff --git a/teensy/teensy_renderer.c b/teensy/teensy_renderer.c index b29e485..b51d2a9 100644 --- a/teensy/teensy_renderer.c +++ b/teensy/teensy_renderer.c @@ -3,6 +3,7 @@ #include <stdio.h> #include <string.h> #include <math.h> +#include <stdarg.h> #include "teensy_context.h" #include "teensy_list.h" @@ -91,6 +92,31 @@ void ty_img_set_pixel( img.data[pos.y * img.width + pos.x] = color; } +// This function technically is not needed, but I may want unicode support in +// the future, when an abstraction like this is needed. +void ty_font_add_glyph(struct ty_font *font, uint8_t c, struct ty_image img) +{ + font->glyphs[c] = img; +} + +int ty_font_width(struct ty_font *font, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + int len = vsnprintf(NULL, 0, fmt, args); + char *text = ty_talloc(sizeof(char) * (len + 1)); + va_end(args); + + va_start(args, fmt); + vsnprintf(text, len + 1, fmt, args); + va_end(args); + + int width = 0; + for (uint8_t *c = (uint8_t*)text; *c != '\0'; c++) + width += font->glyphs[*c].width; + return width; +} + void ty_draw_clear(struct ty_color col) { assert(is_renderer_init()); @@ -211,6 +237,34 @@ void ty_draw_line( } } +void ty_draw_text(struct ty_font *font, struct ty_vec2i pos, const char *text) +{ + for (const uint8_t *c = (const uint8_t*)text; *c != '\0'; c++) { + struct ty_image glyph = font->glyphs[*c]; + ty_draw_image(glyph, pos); + pos.x += glyph.width; + } +} + +void ty_draw_text_fmt( + struct ty_font *font, + struct ty_vec2i pos, + const char *fmt, + ... +) { + va_list args; + va_start(args, fmt); + int len = vsnprintf(NULL, 0, fmt, args); + char *text = ty_talloc(sizeof(char) * (len + 1)); + va_end(args); + + va_start(args, fmt); + vsnprintf(text, len + 1, fmt, args); + va_end(args); + + ty_draw_text(font, pos, text); +} + void ty_draw_end(void) { assert(is_renderer_init()); |
