5 #include "ebisp/interpreter.h"
6 #include "game/camera.h"
7 #include "game/level/labels.h"
8 #include "game/level/level_editor/label_layer.h"
9 #include "system/line_stream.h"
10 #include "system/log.h"
11 #include "system/lt.h"
12 #include "system/nth_alloc.h"
13 #include "system/stacktrace.h"
14 #include "system/str.h"
16 #define LABEL_MAX_ID_SIZE 36
20 LABEL_STATE_VIRGIN = 0,
37 enum LabelState *states;
40 Labels *create_labels_from_line_stream(LineStream *line_stream)
42 trace_assert(line_stream);
46 Labels * const labels = PUSH_LT(lt, nth_calloc(1, sizeof(Labels)), free);
53 line_stream_next(line_stream),
55 &labels->count) == EOF) {
56 log_fail("Could not read amount of labels\n");
60 labels->ids = PUSH_LT(lt, nth_calloc(labels->count, sizeof(char) * LABEL_MAX_ID_SIZE), free);
61 if (labels->ids == NULL) {
65 labels->positions = PUSH_LT(lt, nth_calloc(1, sizeof(Vec2f) * labels->count), free);
66 if (labels->positions == NULL) {
70 labels->colors = PUSH_LT(lt, nth_calloc(1, sizeof(Color) * labels->count), free);
71 if (labels->colors == NULL) {
75 labels->texts = PUSH_LT(lt, nth_calloc(1, sizeof(char*) * labels->count), free);
76 if (labels->texts == NULL) {
80 labels->alphas = PUSH_LT(lt, nth_calloc(1, sizeof(float) * labels->count), free);
81 if (labels->alphas == NULL) {
85 labels->delta_alphas = PUSH_LT(lt, nth_calloc(1, sizeof(float) * labels->count), free);
86 if (labels->delta_alphas == NULL) {
90 labels->states = PUSH_LT(lt, nth_calloc(1, sizeof(enum LabelState) * labels->count), free);
91 if (labels->states == NULL) {
96 for (size_t i = 0; i < labels->count; ++i) {
98 line_stream_next(line_stream),
99 "%" STRINGIFY(LABEL_MAX_ID_SIZE) "s%f%f%6s\n",
100 labels->ids + i * LABEL_MAX_ID_SIZE,
101 &labels->positions[i].x,
102 &labels->positions[i].y,
104 log_fail("Could not read position and color of %dth label\n", i);
108 labels->colors[i] = hexstr(color);
110 const char *label_text = line_stream_next(line_stream);
111 if (label_text == NULL) {
112 log_fail("Could not read text of %dth label\n", i);
116 labels->texts[i] = PUSH_LT(
118 string_duplicate(label_text, NULL),
120 if (labels->texts[i] == NULL) {
124 trim_endline(labels->texts[i]);
130 Labels *create_labels_from_label_layer(const LabelLayer *label_layer)
132 trace_assert(label_layer);
134 Lt *lt = create_lt();
136 Labels *labels = PUSH_LT(lt, nth_calloc(1, sizeof(Labels)), free);
137 if (labels == NULL) {
142 labels->count = label_layer_count(label_layer);
144 labels->ids = PUSH_LT(lt, nth_calloc(labels->count, sizeof(char) * LABEL_MAX_ID_SIZE), free);
145 if (labels->ids == NULL) {
149 label_layer_ids(label_layer),
150 labels->count * sizeof(char) * LABEL_MAX_ID_SIZE);
152 labels->positions = PUSH_LT(lt, nth_calloc(1, sizeof(Vec2f) * labels->count), free);
153 if (labels->positions == NULL) {
156 memcpy(labels->positions,
157 label_layer_positions(label_layer),
158 labels->count * sizeof(Vec2f));
160 labels->colors = PUSH_LT(lt, nth_calloc(1, sizeof(Color) * labels->count), free);
161 if (labels->colors == NULL) {
164 memcpy(labels->colors,
165 label_layer_colors(label_layer),
166 labels->count * sizeof(Color));
168 labels->texts = PUSH_LT(lt, nth_calloc(1, sizeof(char*) * labels->count), free);
169 if (labels->texts == NULL) {
173 char *texts = labels_layer_texts(label_layer);
174 for (size_t i = 0; i < labels->count; ++i) {
175 labels->texts[i] = PUSH_LT(
177 string_duplicate(texts + i * LABEL_LAYER_TEXT_MAX_SIZE, NULL),
181 labels->alphas = PUSH_LT(lt, nth_calloc(1, sizeof(float) * labels->count), free);
182 if (labels->alphas == NULL) {
186 labels->delta_alphas = PUSH_LT(lt, nth_calloc(1, sizeof(float) * labels->count), free);
187 if (labels->delta_alphas == NULL) {
191 labels->states = PUSH_LT(lt, nth_calloc(1, sizeof(enum LabelState) * labels->count), free);
192 if (labels->states == NULL) {
199 void destroy_labels(Labels *label)
202 RETURN_LT0(label->lt);
205 int labels_render(const Labels *label,
206 const Camera *camera)
209 trace_assert(camera);
211 for (size_t i = 0; i < label->count; ++i) {
213 const float state = label->alphas[i] * (2 - label->alphas[i]);
215 if (camera_render_text(camera,
218 rgba(label->colors[i].r,
222 vec_sum(label->positions[i],
223 vec(0.0f, -8.0f * state))) < 0) {
231 void labels_update(Labels *label,
237 for (size_t i = 0; i < label->count; ++i) {
238 label->alphas[i] = label->alphas[i] + label->delta_alphas[i] * delta_time;
240 if (label->alphas[i] < 0.0f) {
241 label->alphas[i] = 0.0f;
242 label->delta_alphas[i] = 0.0f;
245 if (label->alphas[i] > 1.0f) {
246 label->alphas[i] = 1.0f;
247 label->delta_alphas[i] = 0.0f;
252 void labels_enter_camera_event(Labels *labels,
253 const Camera *camera)
255 trace_assert(labels);
256 trace_assert(camera);
258 for (size_t i = 0; i < labels->count; ++i) {
259 const int became_visible = camera_is_text_visible(
262 labels->positions[i],
265 if (labels->states[i] == LABEL_STATE_VIRGIN && became_visible) {
266 labels->states[i] = LABEL_STATE_APPEARED;
267 labels->alphas[i] = 0.0f;
268 labels->delta_alphas[i] = 1.0f;
273 static struct EvalResult
274 labels_action(Labels *labels,
280 trace_assert(labels);
284 const char *target = NULL;
285 struct Expr rest = void_expr();
286 struct EvalResult res = match_list(gc, "q*", path, &target, &rest);
291 if (strcmp(target, "hide") == 0) {
292 if (labels->states[index] != LABEL_STATE_HIDDEN) {
293 labels->states[index] = LABEL_STATE_HIDDEN;
294 labels->alphas[index] = 1.0f;
295 labels->delta_alphas[index] = -3.0f;
297 return eval_success(NIL(gc));
300 return unknown_target(gc, labels->ids + index * LABEL_MAX_ID_SIZE, target);
304 labels_send(Labels *labels, Gc *gc, struct Scope *scope, struct Expr path)
306 trace_assert(labels);
310 const char *target = NULL;
311 struct Expr rest = void_expr();
312 struct EvalResult res = match_list(gc, "s*", path, &target, &rest);
317 for (size_t i = 0; i < labels->count; ++i) {
318 if (strcmp(target, labels->ids + i * LABEL_MAX_ID_SIZE) == 0) {
319 return labels_action(labels, i, gc, scope, rest);
323 return unknown_target(gc, "label", target);