]> git.lizzy.rs Git - nothing.git/blob - src/game/level/level_editor/player_layer.c
0bec114a97aa92a8ba40629cc1396719e47ff922
[nothing.git] / src / game / level / level_editor / player_layer.c
1 #include <stdio.h>
2
3 #include <SDL.h>
4
5 #include "game/camera.h"
6 #include "system/stacktrace.h"
7 #include "player_layer.h"
8 #include "system/nth_alloc.h"
9 #include "system/log.h"
10 #include "undo_history.h"
11
12 PlayerLayer create_player_layer(Vec position, Color color)
13 {
14     return (PlayerLayer) {
15         .position = position,
16         .color_picker = create_color_picker_from_rgba(color),
17         .prev_color = color
18     };
19 }
20
21 PlayerLayer create_player_layer_from_line_stream(LineStream *line_stream)
22 {
23     trace_assert(line_stream);
24
25     const char *line = line_stream_next(line_stream);
26     trace_assert(line);
27
28     char colorstr[7] = "000000";
29     Point position = vec(0.0f, 0.0f);
30
31     const int bound =
32         sscanf(line, "%f%f%6s", &position.x, &position.y, colorstr);
33
34 #define BOUND_EXPECTED 3
35     if (bound != BOUND_EXPECTED) {
36         log_fail("Could not read Player Layer properly. Parsed tokens: %d. Expected: %d\n",
37                  bound, BOUND_EXPECTED);
38     }
39 #undef BOUND_EXPECTED
40
41     return create_player_layer(position, hexstr(colorstr));
42 }
43
44 LayerPtr player_layer_as_layer(PlayerLayer *player_layer)
45 {
46     LayerPtr layer = {
47         .type = LAYER_PLAYER,
48         .ptr = player_layer
49     };
50     return layer;
51 }
52
53 int player_layer_render(const PlayerLayer *player_layer,
54                         Camera *camera,
55                         int active)
56 {
57     trace_assert(player_layer);
58     trace_assert(camera);
59
60     if (camera_fill_rect(
61             camera,
62             rect_from_vecs(
63                 player_layer->position,
64                 vec(25.0f, 25.0f)),
65             color_scale(
66                 color_picker_rgba(&player_layer->color_picker),
67                 rgba(1.0f, 1.0f, 1.0f, active ? 1.0f : 0.5f))) < 0) {
68         return -1;
69     }
70
71     if (active && color_picker_render(
72             &player_layer->color_picker,
73             camera)) {
74         return -1;
75     }
76
77     return 0;
78 }
79
80 static void player_layer_revert_position(void *layer, Context context)
81 {
82     trace_assert(layer);
83
84     PlayerLayer *player_layer = layer;
85     player_layer->position = *((Point*)context.data);
86 }
87
88 static
89 void player_layer_revert_color(void *layer, Context context)
90 {
91     trace_assert(layer);
92     PlayerLayer *player_layer = layer;
93
94     trace_assert(sizeof(Color) <= CONTEXT_SIZE);
95     Color *color = (Color *)context.data;
96
97     player_layer->color_picker = create_color_picker_from_rgba(*color);
98     player_layer->prev_color = *color;
99 }
100
101 int player_layer_event(PlayerLayer *player_layer,
102                        const SDL_Event *event,
103                        const Camera *camera,
104                        UndoHistory *undo_history)
105 {
106     trace_assert(player_layer);
107     trace_assert(event);
108     trace_assert(camera);
109     trace_assert(undo_history);
110
111     int selected = 0;
112     if (color_picker_event(
113             &player_layer->color_picker,
114             event,
115             camera,
116             &selected) < 0) {
117         return -1;
118     }
119
120     if (selected && !color_picker_drag(&player_layer->color_picker)) {
121         undo_history_push(
122             undo_history,
123             create_action(
124                 player_layer,
125                 player_layer_revert_color,
126                 &player_layer->prev_color,
127                 sizeof(player_layer->prev_color)));
128         player_layer->prev_color = color_picker_rgba(&player_layer->color_picker);
129     }
130
131     if (!selected &&
132         event->type == SDL_MOUSEBUTTONDOWN &&
133         event->button.button == SDL_BUTTON_LEFT) {
134         Action action = {
135             .layer = player_layer,
136             .revert = player_layer_revert_position
137         };
138         trace_assert(sizeof(player_layer->position) <= CONTEXT_SIZE);
139         memcpy(action.context.data, &player_layer->position, sizeof(player_layer->position));
140         undo_history_push(undo_history, action);
141
142         player_layer->position =
143             camera_map_screen(camera,
144                               event->button.x,
145                               event->button.y);
146     }
147
148     return 0;
149 }
150
151 int player_layer_dump_stream(const PlayerLayer *player_layer,
152                              FILE *filedump)
153 {
154     trace_assert(player_layer);
155     trace_assert(filedump);
156
157     fprintf(filedump, "%f %f ", player_layer->position.x, player_layer->position.y);
158     color_hex_to_stream(color_picker_rgba(&player_layer->color_picker), filedump);
159     fprintf(filedump, "\n");
160
161     return 0;
162 }