4 #include "game/camera.h"
5 #include "game/level/labels.h"
7 #include "system/line_stream.h"
9 #include "system/nth_alloc.h"
10 #include "system/log.h"
12 #define LABEL_MAX_ID_SIZE 36
16 LABEL_STATE_VIRGIN = 0,
31 enum LabelState *states;
35 Labels *create_labels_from_line_stream(LineStream *line_stream)
39 Lt *const lt = create_lt();
44 Labels * const labels = PUSH_LT(lt, nth_alloc(sizeof(Labels)), free);
51 line_stream_next(line_stream),
53 &labels->count) == EOF) {
54 log_fail("Could not read amount of labels\n");
58 labels->ids = PUSH_LT(lt, nth_alloc(sizeof(char*) * labels->count), free);
59 if (labels->ids == NULL) {
63 labels->positions = PUSH_LT(lt, nth_alloc(sizeof(Vec) * labels->count), free);
64 if (labels->positions == NULL) {
68 labels->colors = PUSH_LT(lt, nth_alloc(sizeof(Color) * labels->count), free);
69 if (labels->colors == NULL) {
73 labels->texts = PUSH_LT(lt, nth_alloc(sizeof(char*) * labels->count), free);
74 if (labels->texts == NULL) {
78 labels->alphas = PUSH_LT(lt, nth_alloc(sizeof(float) * labels->count), free);
79 if (labels->alphas == NULL) {
83 labels->delta_alphas = PUSH_LT(lt, nth_alloc(sizeof(float) * labels->count), free);
84 if (labels->delta_alphas == NULL) {
88 labels->states = PUSH_LT(lt, nth_alloc(sizeof(enum LabelState) * labels->count), free);
89 if (labels->states == NULL) {
93 labels->visible = PUSH_LT(lt, nth_alloc(sizeof(int) * labels->count), free);
94 if (labels->visible == NULL) {
99 for (size_t i = 0; i < labels->count; ++i) {
100 labels->alphas[i] = 0.0f;
101 labels->delta_alphas[i] = 0.0f;
102 labels->states[i] = LABEL_STATE_VIRGIN;
103 labels->visible[i] = 0;
104 labels->texts[i] = NULL;
106 labels->ids[i] = PUSH_LT(lt, nth_alloc(sizeof(char) * LABEL_MAX_ID_SIZE), free);
107 if (labels->ids[i] == NULL) {
112 line_stream_next(line_stream),
113 "%" STRINGIFY(LABEL_MAX_ID_SIZE) "s%f%f%6s\n",
115 &labels->positions[i].x,
116 &labels->positions[i].y,
118 log_fail("Could not read position and color of %dth label\n", i);
122 labels->colors[i] = hexstr(color);
124 const char *label_text = line_stream_next(line_stream);
125 if (label_text == NULL) {
126 log_fail("Could not read text of %dth label\n", i);
130 labels->texts[i] = PUSH_LT(
132 string_duplicate(label_text, NULL),
134 if (labels->texts[i] == NULL) {
138 trim_endline(labels->texts[i]);
144 void destroy_labels(Labels *label)
147 RETURN_LT0(label->lt);
150 int labels_render(const Labels *label,
156 for (size_t i = 0; i < label->count; ++i) {
157 if (label->visible[i]) {
159 const float state = label->alphas[i] * (2 - label->alphas[i]);
161 if (camera_render_text(camera,
164 rgba(label->colors[i].r,
168 vec_sum(label->positions[i],
169 vec(0.0f, -8.0f * state))) < 0) {
178 void labels_update(Labels *label,
184 for (size_t i = 0; i < label->count; ++i) {
185 label->alphas[i] = label->alphas[i] + label->delta_alphas[i] * delta_time;
187 if (label->alphas[i] < 0.0f) {
188 label->alphas[i] = 0.0f;
189 label->delta_alphas[i] = 0.0f;
192 if (label->alphas[i] > 1.0f) {
193 label->alphas[i] = 1.0f;
194 label->delta_alphas[i] = 0.0f;
199 void labels_enter_camera_event(Labels *labels,
200 const Camera *camera)
205 for (size_t i = 0; i < labels->count; ++i) {
206 const int became_visible = camera_is_text_visible(
209 labels->positions[i],
212 if (labels->states[i] == LABEL_STATE_VIRGIN && !labels->visible[i] && became_visible) {
213 labels->states[i] = LABEL_STATE_APPEARED;
214 labels->alphas[i] = 0.0f;
215 labels->delta_alphas[i] = 1.0f;
218 /* TODO: can we replace labels->visible with labels->states? */
219 labels->visible[i] = became_visible;
223 void labels_hide(Labels *labels,
224 const char *label_id)
229 for (size_t i = 0; i < labels->count; ++i) {
230 if (strcmp(labels->ids[i], label_id) == 0 && labels->states[i] != LABEL_STATE_HIDDEN) {
231 labels->states[i] = LABEL_STATE_HIDDEN;
232 labels->alphas[i] = 1.0f;
233 labels->delta_alphas[i] = -1.0f;