]> git.lizzy.rs Git - nothing.git/blob - src/game/level/level_editor/label_layer.c
Add TODO(#892)
[nothing.git] / src / game / level / level_editor / label_layer.c
1 #include <SDL.h>
2
3 #include "system/line_stream.h"
4 #include "system/stacktrace.h"
5 #include "system/nth_alloc.h"
6 #include "system/lt.h"
7 #include "system/str.h"
8 #include "system/log.h"
9 #include "math/point.h"
10 #include "label_layer.h"
11 #include "dynarray.h"
12 #include "color.h"
13 #include "game/camera.h"
14
15 #define LABEL_LAYER_ID_MAX_SIZE 36
16
17 struct LabelLayer {
18     Lt *lt;
19     Dynarray *ids;
20     Dynarray *positions;
21     Dynarray *colors;
22     Dynarray *texts;
23 };
24
25 LayerPtr label_layer_as_layer(LabelLayer *label_layer)
26 {
27     LayerPtr layer = {
28         .ptr = label_layer,
29         .type = LAYER_LABEL
30     };
31     return layer;
32 }
33
34 LabelLayer *create_label_layer(void)
35 {
36     Lt *lt = create_lt();
37
38     LabelLayer *label_layer = PUSH_LT(
39         lt, nth_calloc(1, sizeof(LabelLayer)), free);
40     if (label_layer == NULL) {
41         RETURN_LT(lt, NULL);
42     }
43     label_layer->lt = lt;
44
45     label_layer->ids = PUSH_LT(
46         lt,
47         create_dynarray(sizeof(char) * LABEL_LAYER_ID_MAX_SIZE),
48         destroy_dynarray);
49     if (label_layer->ids == NULL) {
50         RETURN_LT(lt, NULL);
51     }
52
53     label_layer->positions = PUSH_LT(lt, create_dynarray(sizeof(Point)), destroy_dynarray);
54     if (label_layer->positions == NULL) {
55         RETURN_LT(lt, NULL);
56     }
57
58     label_layer->colors = PUSH_LT(lt, create_dynarray(sizeof(Color)), destroy_dynarray);
59     if (label_layer->colors == NULL) {
60         RETURN_LT(lt, NULL);
61     }
62
63     label_layer->texts = PUSH_LT(lt, create_dynarray(sizeof(char*)), destroy_dynarray);
64     if (label_layer->texts == NULL) {
65         RETURN_LT(lt, NULL);
66     }
67
68     return label_layer;
69 }
70
71 LabelLayer *create_label_layer_from_line_stream(LineStream *line_stream)
72 {
73     trace_assert(line_stream);
74     LabelLayer *label_layer = create_label_layer();
75
76     if (label_layer == NULL) {
77         RETURN_LT(label_layer->lt, NULL);
78     }
79
80     const char *line = line_stream_next(line_stream);
81     if (line == NULL) {
82         log_fail("Could not read amount of labels\n");
83         RETURN_LT(label_layer->lt, NULL);
84     }
85
86     size_t n = 0;
87     if (sscanf(line, "%lu", &n) == EOF) {
88         log_fail("Could not parse amount of labels\n");
89         RETURN_LT(label_layer->lt, NULL);
90     }
91
92     for (size_t i = 0; i < n; ++i) {
93         char hex[7];
94         char id[LABEL_LAYER_ID_MAX_SIZE];
95         Point position;
96
97         line = line_stream_next(line_stream);
98         if (line == NULL) {
99             log_fail("Could not read label meta info\n");
100             RETURN_LT(label_layer->lt, NULL);
101         }
102
103         if (sscanf(
104                 line,
105                 "%"STRINGIFY(LABEL_LAYER_ID_MAX_SIZE)"s%f%f%6s\n",
106                 id, &position.x, &position.y, hex) == EOF) {
107             log_fail("Could not parse label meta info\n");
108             RETURN_LT(label_layer->lt, NULL);
109         }
110
111         Color color = hexstr(hex);
112
113         dynarray_push(label_layer->ids, id);
114         dynarray_push(label_layer->positions, &position);
115         dynarray_push(label_layer->colors, &color);
116
117         line = line_stream_next(line_stream);
118         if (line == NULL) {
119             log_fail("Could not read label text\n");
120         }
121
122         char *label_text = PUSH_LT(label_layer->lt, string_duplicate(line, NULL), free);
123         trim_endline(label_text);
124         dynarray_push(label_layer->texts, &label_text);
125     }
126
127     return label_layer;
128 }
129
130 void destroy_label_layer(LabelLayer *label_layer)
131 {
132     trace_assert(label_layer);
133     destroy_lt(label_layer->lt);
134 }
135
136 int label_layer_render(const LabelLayer *label_layer,
137                        Camera *camera,
138                        float fa)
139 {
140     trace_assert(label_layer);
141     trace_assert(camera);
142
143     size_t n = dynarray_count(label_layer->ids);
144     Point *positions = dynarray_data(label_layer->positions);
145     Color *colors = dynarray_data(label_layer->colors);
146     char **texts = dynarray_data(label_layer->texts);
147
148     /* TODO(#891): LabelLayer doesn't show the final position of Label after the animation */
149     for (size_t i = 0; i < n; ++i) {
150         if (camera_render_text(
151                 camera,
152                 texts[i],
153                 vec(2.0f, 2.0f),
154                 color_scale(
155                     colors[i],
156                     rgba(1.0f, 1.0f, 1.0f, fa)),
157                 positions[i]) < 0) {
158             return -1;
159         }
160     }
161
162     return 0;
163 }
164
165 int label_layer_event(LabelLayer *label_layer,
166                       const SDL_Event *event,
167                       const Camera *camera)
168 {
169     trace_assert(label_layer);
170     trace_assert(event);
171     trace_assert(camera);
172     /* TODO(#892): LabelLayer doesn't allow to modify and add labels */
173     return 0;
174 }
175
176 size_t label_layer_count(const LabelLayer *label_layer)
177 {
178     return dynarray_count(label_layer->ids);
179 }
180
181 char *label_layer_ids(const LabelLayer *label_layer)
182 {
183     return dynarray_data(label_layer->ids);
184 }
185
186 Point *label_layer_positions(const LabelLayer *label_layer)
187 {
188     return dynarray_data(label_layer->positions);
189 }
190
191 Color *label_layer_colors(const LabelLayer *label_layer)
192 {
193     return dynarray_data(label_layer->colors);
194 }
195
196 char **labels_layer_texts(const LabelLayer *label_layer)
197 {
198     return dynarray_data(label_layer->texts);
199 }