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