]> git.lizzy.rs Git - nothing.git/blob - src/ui/menu_title.c
(#719) Animate the MenuTitle
[nothing.git] / src / ui / menu_title.c
1 #include <SDL2/SDL.h>
2
3 #include "math/point.h"
4
5 #include "./menu_title.h"
6 #include "system/lt.h"
7 #include "system/stacktrace.h"
8 #include "system/nth_alloc.h"
9 #include "system/str.h"
10 #include "game/sprite_font.h"
11
12 struct MenuTitle
13 {
14     Lt *lt;
15     const char *text;
16     Vec font_scale;
17     const Sprite_font *sprite_font;
18     float angle;
19 };
20
21 MenuTitle *create_menu_title(const char *text,
22                              Vec font_scale,
23                              const Sprite_font *sprite_font)
24 {
25     trace_assert(text);
26
27     Lt *lt = create_lt();
28     if (lt == NULL) {
29         return NULL;
30     }
31
32     MenuTitle *menu_title = PUSH_LT(
33         lt,
34         nth_alloc(sizeof(MenuTitle)),
35         free);
36     if (menu_title == NULL) {
37         RETURN_LT(lt, NULL);
38     }
39     menu_title->lt = lt;
40
41     menu_title->text = PUSH_LT(
42         lt,
43         string_duplicate(text, NULL),
44         free);
45     if (menu_title->text == NULL) {
46         RETURN_LT(lt, NULL);
47     }
48
49     menu_title->font_scale = font_scale;
50     menu_title->sprite_font = sprite_font;
51     menu_title->angle = 0.0f;
52
53     return menu_title;
54 }
55
56 void destroy_menu_title(MenuTitle *menu_title)
57 {
58     trace_assert(menu_title);
59     RETURN_LT0(menu_title->lt);
60 }
61
62 int menu_title_render(const MenuTitle *menu_title,
63                       SDL_Renderer *renderer,
64                       Vec position)
65 {
66     trace_assert(menu_title);
67     trace_assert(renderer);
68
69
70     const size_t n = strlen(menu_title->text);
71     char buf[2] = {0, 0};
72
73     for (size_t i = 0; i < n; ++i) {
74         buf[0] = menu_title->text[i];
75
76         if (sprite_font_render_text(
77                 menu_title->sprite_font,
78                 renderer,
79                 vec_sum(
80                     position,
81                     vec(
82                         (float) (i * FONT_CHAR_WIDTH) * menu_title->font_scale.x,
83                         sinf(menu_title->angle + (float) i / (float) n * 10.0f) * 20.0f)),
84                 menu_title->font_scale,
85                 rgba(1.0f, 1.0f, 1.0f, 1.0f),
86                 buf) < 0) {
87             return -1;
88         }
89     }
90
91     return 0;
92 }
93
94 int menu_title_update(MenuTitle *menu_title, float delta_time)
95 {
96     trace_assert(menu_title);
97     menu_title->angle = fmodf(menu_title->angle + 10.0f * delta_time, 2 * PI);
98     return 0;
99 }
100
101 Vec menu_title_size(const MenuTitle *menu_title)
102 {
103     trace_assert(menu_title);
104
105     Rect boundary = sprite_font_boundary_box(
106         menu_title->sprite_font,
107         vec(0.0f, 0.0f),
108         menu_title->font_scale,
109         menu_title->text);
110
111     return vec(boundary.w, boundary.h);
112 }