3 #include "game/camera.h"
4 #include "game/level/boxes.h"
5 #include "game/level/level_editor/proto_rect.h"
6 #include "game/level/level_editor/color_picker.h"
7 #include "game/level/level_editor/rect_layer.h"
8 #include "game/level/level_editor/point_layer.h"
9 #include "game/level/level_editor/player_layer.h"
10 #include "game/level/level_editor/layer_picker.h"
11 #include "system/stacktrace.h"
12 #include "system/nth_alloc.h"
13 #include "system/lt.h"
14 #include "system/log.h"
16 #include "level_editor.h"
23 LayerPicker layer_picker;
25 RectLayer *boxes_layer;
26 RectLayer *platforms_layer;
27 RectLayer *back_platforms_layer;
28 PointLayer *goals_layer;
29 PlayerLayer *player_layer;
30 RectLayer *lava_layer;
31 RectLayer *regions_layer;
32 LayerPtr layers[LAYER_PICKER_N];
37 LevelEditor *create_level_editor(RectLayer *boxes_layer,
38 RectLayer *platforms_layer,
39 RectLayer *back_platforms_layer,
40 PointLayer *goals_layer,
41 PlayerLayer *player_layer,
42 RectLayer *lava_layer,
43 RectLayer *regions_layer)
45 trace_assert(boxes_layer);
46 trace_assert(platforms_layer);
47 trace_assert(back_platforms_layer);
48 trace_assert(goals_layer);
49 trace_assert(player_layer);
50 trace_assert(lava_layer);
51 trace_assert(regions_layer);
55 LevelEditor *level_editor = PUSH_LT(lt, nth_calloc(1, sizeof(LevelEditor)), free);
56 if (level_editor == NULL) {
59 level_editor->lt = lt;
61 level_editor->camera_position = vec(0.0f, 0.0f);
62 level_editor->camera_scale = 1.0f;
64 level_editor->boxes_layer = PUSH_LT(lt, boxes_layer, destroy_rect_layer);
65 level_editor->platforms_layer = PUSH_LT(lt, platforms_layer, destroy_rect_layer);
66 level_editor->back_platforms_layer = PUSH_LT(lt, back_platforms_layer, destroy_rect_layer);
67 level_editor->goals_layer = PUSH_LT(lt, goals_layer, destroy_point_layer);
68 level_editor->player_layer = PUSH_LT(lt, player_layer, destroy_player_layer);
69 level_editor->lava_layer = PUSH_LT(lt, lava_layer, destroy_rect_layer);
70 level_editor->regions_layer = PUSH_LT(lt, regions_layer, destroy_rect_layer);
72 level_editor->layers[LAYER_PICKER_BOXES] = rect_layer_as_layer(level_editor->boxes_layer);
73 level_editor->layers[LAYER_PICKER_PLATFORMS] = rect_layer_as_layer(level_editor->platforms_layer);
74 level_editor->layers[LAYER_PICKER_BACK_PLATFORMS] = rect_layer_as_layer(level_editor->back_platforms_layer);
75 level_editor->layers[LAYER_PICKER_GOALS] = point_layer_as_layer(level_editor->goals_layer);
76 level_editor->layers[LAYER_PICKER_PLAYER] = player_layer_as_layer(level_editor->player_layer);
77 level_editor->layers[LAYER_PICKER_LAVA] = rect_layer_as_layer(level_editor->lava_layer);
78 level_editor->layers[LAYER_PICKER_REGIONS] = rect_layer_as_layer(level_editor->regions_layer);
80 size_t n = rect_layer_count(level_editor->regions_layer);
81 const char *ids = rect_layer_ids(level_editor->regions_layer);
82 log_info("Regions:\n");
83 for (size_t i = 0; i < n; ++i) {
84 log_info("%s\n", ids + i * 36);
87 level_editor->layer_picker = LAYER_PICKER_BOXES;
89 level_editor->drag = false;
94 void destroy_level_editor(LevelEditor *level_editor)
96 trace_assert(level_editor);
97 RETURN_LT0(level_editor->lt);
100 int level_editor_render(const LevelEditor *level_editor,
103 trace_assert(level_editor);
104 trace_assert(camera);
106 for (size_t i = 0; i < LAYER_PICKER_N; ++i) {
108 level_editor->layers[i],
110 i == level_editor->layer_picker ? 1.0f : 0.5f) < 0) {
115 if (layer_picker_render(&level_editor->layer_picker, camera) < 0) {
122 int level_editor_event(LevelEditor *level_editor,
123 const SDL_Event *event,
124 const Camera *camera)
126 trace_assert(level_editor);
128 trace_assert(camera);
130 switch (event->type) {
131 case SDL_MOUSEWHEEL: {
132 // TODO(#679): zooming in edit mode is not smooth enough
133 if (event->wheel.y > 0) {
134 level_editor->camera_scale += 0.1f;
135 } else if (event->wheel.y < 0) {
136 level_editor->camera_scale = fmaxf(0.1f, level_editor->camera_scale - 0.1f);
140 case SDL_MOUSEBUTTONUP:
141 case SDL_MOUSEBUTTONDOWN: {
142 if (event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_MIDDLE) {
143 level_editor->drag = true;
146 if (event->type == SDL_MOUSEBUTTONUP && event->button.button == SDL_BUTTON_MIDDLE) {
147 level_editor->drag = false;
151 case SDL_MOUSEMOTION: {
152 if (level_editor->drag) {
153 const Vec next_position = camera_map_screen(camera, event->motion.x, event->motion.y);
154 const Vec prev_position = camera_map_screen(
156 event->motion.x + event->motion.xrel,
157 event->motion.y + event->motion.yrel);
159 vec_add(&level_editor->camera_position,
160 vec_sub(next_position, prev_position));
166 bool selected = false;
167 if (layer_picker_event(
168 &level_editor->layer_picker,
177 level_editor->layers[level_editor->layer_picker],
187 int level_editor_focus_camera(LevelEditor *level_editor,
190 camera_center_at(camera, level_editor->camera_position);
191 camera_scale(camera, level_editor->camera_scale);
195 const RectLayer *level_editor_boxes(const LevelEditor *level_editor)
197 return level_editor->boxes_layer;
200 const RectLayer *level_editor_platforms(const LevelEditor *level_editor)
202 return level_editor->platforms_layer;
205 const RectLayer *level_editor_back_platforms(const LevelEditor *level_editor)
207 return level_editor->back_platforms_layer;
210 const PointLayer *level_editor_goals_layer(const LevelEditor *level_editor)
212 return level_editor->goals_layer;
215 const PlayerLayer *level_editor_player_layer(const LevelEditor *level_editor)
217 return level_editor->player_layer;
220 const RectLayer *level_editor_lava_layer(const LevelEditor *level_editor)
222 return level_editor->lava_layer;
225 const RectLayer *level_editor_regions_layer(const LevelEditor *level_editor)
227 return level_editor->regions_layer;