5 #include "game/camera.h"
6 #include "game/level/labels.h"
7 #include "game/level/level_editor/label_layer.h"
8 #include "system/line_stream.h"
9 #include "system/log.h"
10 #include "system/lt.h"
11 #include "system/nth_alloc.h"
12 #include "system/stacktrace.h"
13 #include "system/str.h"
17 LABEL_STATE_VIRGIN = 0,
34 enum LabelState *states;
37 Labels *create_labels_from_label_layer(const LabelLayer *label_layer)
39 trace_assert(label_layer);
43 Labels *labels = PUSH_LT(lt, nth_calloc(1, sizeof(Labels)), free);
49 labels->count = label_layer_count(label_layer);
51 labels->ids = PUSH_LT(lt, nth_calloc(labels->count, sizeof(char) * ENTITY_MAX_ID_SIZE), free);
52 if (labels->ids == NULL) {
56 label_layer_ids(label_layer),
57 labels->count * sizeof(char) * ENTITY_MAX_ID_SIZE);
59 labels->positions = PUSH_LT(lt, nth_calloc(1, sizeof(Vec2f) * labels->count), free);
60 if (labels->positions == NULL) {
63 memcpy(labels->positions,
64 label_layer_positions(label_layer),
65 labels->count * sizeof(Vec2f));
67 labels->colors = PUSH_LT(lt, nth_calloc(1, sizeof(Color) * labels->count), free);
68 if (labels->colors == NULL) {
71 memcpy(labels->colors,
72 label_layer_colors(label_layer),
73 labels->count * sizeof(Color));
75 labels->texts = PUSH_LT(lt, nth_calloc(1, sizeof(char*) * labels->count), free);
76 if (labels->texts == NULL) {
80 char *texts = labels_layer_texts(label_layer);
81 for (size_t i = 0; i < labels->count; ++i) {
82 labels->texts[i] = PUSH_LT(
84 string_duplicate(texts + i * LABEL_LAYER_TEXT_MAX_SIZE, NULL),
88 labels->alphas = PUSH_LT(lt, nth_calloc(1, sizeof(float) * labels->count), free);
89 if (labels->alphas == NULL) {
93 labels->delta_alphas = PUSH_LT(lt, nth_calloc(1, sizeof(float) * labels->count), free);
94 if (labels->delta_alphas == NULL) {
98 labels->states = PUSH_LT(lt, nth_calloc(1, sizeof(enum LabelState) * labels->count), free);
99 if (labels->states == NULL) {
106 void destroy_labels(Labels *label)
109 RETURN_LT0(label->lt);
112 int labels_render(const Labels *label,
113 const Camera *camera)
116 trace_assert(camera);
118 for (size_t i = 0; i < label->count; ++i) {
120 const float state = label->alphas[i] * (2 - label->alphas[i]);
122 if (camera_render_text(camera,
125 rgba(label->colors[i].r,
129 vec_sum(label->positions[i],
130 vec(0.0f, -8.0f * state))) < 0) {
138 void labels_update(Labels *label,
144 for (size_t i = 0; i < label->count; ++i) {
145 label->alphas[i] = label->alphas[i] + label->delta_alphas[i] * delta_time;
147 if (label->alphas[i] < 0.0f) {
148 label->alphas[i] = 0.0f;
149 label->delta_alphas[i] = 0.0f;
152 if (label->alphas[i] > 1.0f) {
153 label->alphas[i] = 1.0f;
154 label->delta_alphas[i] = 0.0f;
159 void labels_enter_camera_event(Labels *labels,
160 const Camera *camera)
162 trace_assert(labels);
163 trace_assert(camera);
165 for (size_t i = 0; i < labels->count; ++i) {
166 const int became_visible = camera_is_text_visible(
169 labels->positions[i],
172 if (labels->states[i] == LABEL_STATE_VIRGIN && became_visible) {
173 labels->states[i] = LABEL_STATE_APPEARED;
174 labels->alphas[i] = 0.0f;
175 labels->delta_alphas[i] = 1.0f;
180 void labels_hide(Labels *labels, char id[ENTITY_MAX_ID_SIZE])
182 trace_assert(labels);
185 for (size_t i = 0; i < labels->count; ++i) {
186 if (strncmp(id, labels->ids + i * ENTITY_MAX_ID_SIZE, ENTITY_MAX_ID_SIZE) == 0) {
187 if (labels->states[i] != LABEL_STATE_HIDDEN) {
188 labels->states[i] = LABEL_STATE_HIDDEN;
189 labels->alphas[i] = 1.0f;
190 labels->delta_alphas[i] = -3.0f;