]> git.lizzy.rs Git - nothing.git/blob - src/game/level/labels.c
TODO(#256)
[nothing.git] / src / game / level / labels.c
1 #include <assert.h>
2
3 #include "game/camera.h"
4 #include "game/level/labels.h"
5 #include "system/error.h"
6 #include "system/lt.h"
7
8 #define LABEL_TEXT_MAX_LENGTH 64
9
10 struct labels_t
11 {
12     lt_t *lt;
13     size_t count;
14     vec_t *positions;
15     color_t *colors;
16     char **texts;
17 };
18
19 static char *trim_endline(char *s)
20 {
21     const size_t n = strlen(s);
22
23     if (n == 0) {
24         return s;
25     }
26
27     if (s[n - 1] == '\n') {
28         s[n - 1] = '\0';
29     }
30
31     return s;
32 }
33
34 /* TODO(#256): labels don't play appear animation when they get into the camera view */
35
36 labels_t *create_labels_from_stream(FILE *stream)
37 {
38     assert(stream);
39
40     lt_t *const lt = create_lt();
41     if (lt == NULL) {
42         return NULL;
43     }
44
45     labels_t * const labels = PUSH_LT(lt, malloc(sizeof(labels_t)), free);
46     if (labels == NULL) {
47         throw_error(ERROR_TYPE_LIBC);
48         RETURN_LT(lt, NULL);
49     }
50     labels->lt = lt;
51
52     if (fscanf(stream, "%lu", &labels->count) == EOF) {
53         throw_error(ERROR_TYPE_LIBC);
54         RETURN_LT(lt, NULL);
55     }
56
57     labels->positions = PUSH_LT(lt, malloc(sizeof(vec_t) * labels->count), free);
58     if (labels->positions == NULL) {
59         throw_error(ERROR_TYPE_LIBC);
60         RETURN_LT(lt, NULL);
61     }
62
63     labels->colors = PUSH_LT(lt, malloc(sizeof(color_t) * labels->count), free);
64     if (labels->colors == NULL) {
65         throw_error(ERROR_TYPE_LIBC);
66         RETURN_LT(lt, NULL);
67     }
68
69     labels->texts = PUSH_LT(lt, malloc(sizeof(char*) * labels->count), free);
70     if (labels->texts == NULL) {
71         throw_error(ERROR_TYPE_LIBC);
72         RETURN_LT(lt, NULL);
73     }
74
75     for (size_t i = 0; i < labels->count; ++i) {
76         labels->texts[i] = PUSH_LT(lt, malloc(sizeof(char) * (LABEL_TEXT_MAX_LENGTH + 1)), free);
77         if (labels->texts[i] == NULL) {
78             throw_error(ERROR_TYPE_LIBC);
79             RETURN_LT(lt, NULL);
80         }
81     }
82
83     char color[7];
84     for (size_t i = 0; i < labels->count; ++i) {
85         if (fscanf(stream, "%f%f%6s\n",
86                    &labels->positions[i].x,
87                    &labels->positions[i].y,
88                    color) == EOF) {
89             throw_error(ERROR_TYPE_LIBC);
90             RETURN_LT(lt, NULL);
91         }
92
93         labels->colors[i] = color_from_hexstr(color);
94
95         if (fgets(labels->texts[i], LABEL_TEXT_MAX_LENGTH, stream) == NULL) {
96             throw_error(ERROR_TYPE_LIBC);
97             RETURN_LT(lt, NULL);
98         }
99
100         trim_endline(labels->texts[i]);
101     }
102
103     return labels;
104 }
105
106 void destroy_labels(labels_t *label)
107 {
108     assert(label);
109     RETURN_LT0(label->lt);
110 }
111
112 int labels_render(const labels_t *label,
113                  camera_t *camera)
114 {
115     assert(label);
116     assert(camera);
117
118     for (size_t i = 0; i < label->count; ++i) {
119         if (camera_render_text(camera,
120                                label->texts[i],
121                                vec(2.0f, 2.0f),
122                                label->colors[i],
123                                label->positions[i]) < 0) {
124             return -1;
125         }
126     }
127
128     return 0;
129 }
130
131 void labels_update(labels_t *label,
132                   float delta_time)
133 {
134     assert(label);
135     (void) delta_time;
136 }