5 #include "game/camera.h"
6 #include "game/level/labels.h"
7 #include "game/level/level_editor/label_layer.h"
8 #include "system/log.h"
10 #include "system/nth_alloc.h"
11 #include "system/stacktrace.h"
12 #include "system/str.h"
16 LABEL_STATE_VIRGIN = 0,
33 enum LabelState *states;
36 Labels *create_labels_from_label_layer(const LabelLayer *label_layer)
38 trace_assert(label_layer);
42 Labels *labels = PUSH_LT(lt, nth_calloc(1, sizeof(Labels)), free);
48 labels->count = label_layer_count(label_layer);
50 labels->ids = PUSH_LT(lt, nth_calloc(labels->count, sizeof(char) * ENTITY_MAX_ID_SIZE), free);
51 if (labels->ids == NULL) {
55 label_layer_ids(label_layer),
56 labels->count * sizeof(char) * ENTITY_MAX_ID_SIZE);
58 labels->positions = PUSH_LT(lt, nth_calloc(1, sizeof(Vec2f) * labels->count), free);
59 if (labels->positions == NULL) {
62 memcpy(labels->positions,
63 label_layer_positions(label_layer),
64 labels->count * sizeof(Vec2f));
66 labels->colors = PUSH_LT(lt, nth_calloc(1, sizeof(Color) * labels->count), free);
67 if (labels->colors == NULL) {
70 memcpy(labels->colors,
71 label_layer_colors(label_layer),
72 labels->count * sizeof(Color));
74 labels->texts = PUSH_LT(lt, nth_calloc(1, sizeof(char*) * labels->count), free);
75 if (labels->texts == NULL) {
79 char *texts = labels_layer_texts(label_layer);
80 for (size_t i = 0; i < labels->count; ++i) {
81 labels->texts[i] = PUSH_LT(
83 string_duplicate(texts + i * LABEL_LAYER_TEXT_MAX_SIZE, NULL),
87 labels->alphas = PUSH_LT(lt, nth_calloc(1, sizeof(float) * labels->count), free);
88 if (labels->alphas == NULL) {
92 labels->delta_alphas = PUSH_LT(lt, nth_calloc(1, sizeof(float) * labels->count), free);
93 if (labels->delta_alphas == NULL) {
97 labels->states = PUSH_LT(lt, nth_calloc(1, sizeof(enum LabelState) * labels->count), free);
98 if (labels->states == NULL) {
105 void destroy_labels(Labels *label)
108 RETURN_LT0(label->lt);
111 int labels_render(const Labels *label,
112 const Camera *camera)
115 trace_assert(camera);
117 for (size_t i = 0; i < label->count; ++i) {
119 const float state = label->alphas[i] * (2 - label->alphas[i]);
121 if (camera_render_text(camera,
124 rgba(label->colors[i].r,
128 vec_sum(label->positions[i],
129 vec(0.0f, -8.0f * state))) < 0) {
137 void labels_update(Labels *label,
143 for (size_t i = 0; i < label->count; ++i) {
144 label->alphas[i] = label->alphas[i] + label->delta_alphas[i] * delta_time;
146 if (label->alphas[i] < 0.0f) {
147 label->alphas[i] = 0.0f;
148 label->delta_alphas[i] = 0.0f;
151 if (label->alphas[i] > 1.0f) {
152 label->alphas[i] = 1.0f;
153 label->delta_alphas[i] = 0.0f;
158 void labels_enter_camera_event(Labels *labels,
159 const Camera *camera)
161 trace_assert(labels);
162 trace_assert(camera);
164 for (size_t i = 0; i < labels->count; ++i) {
165 const int became_visible = camera_is_text_visible(
168 labels->positions[i],
171 if (labels->states[i] == LABEL_STATE_VIRGIN && became_visible) {
172 labels->states[i] = LABEL_STATE_APPEARED;
173 labels->alphas[i] = 0.0f;
174 labels->delta_alphas[i] = 1.0f;
179 void labels_hide(Labels *labels, char id[ENTITY_MAX_ID_SIZE])
181 trace_assert(labels);
184 for (size_t i = 0; i < labels->count; ++i) {
185 if (strncmp(id, labels->ids + i * ENTITY_MAX_ID_SIZE, ENTITY_MAX_ID_SIZE) == 0) {
186 if (labels->states[i] != LABEL_STATE_HIDDEN) {
187 labels->states[i] = LABEL_STATE_HIDDEN;
188 labels->alphas[i] = 1.0f;
189 labels->delta_alphas[i] = -3.0f;