level->platforms = PUSH_LT(
lt,
- create_platforms_from_rect_layer(level_editor->platforms_layer),
+ create_platforms_from_rect_layer(&level_editor->platforms_layer),
destroy_platforms);
if (level->platforms == NULL) {
RETURN_LT(lt, NULL);
level->lava = PUSH_LT(
lt,
- create_lava_from_rect_layer(level_editor->lava_layer),
+ create_lava_from_rect_layer(&level_editor->lava_layer),
destroy_lava);
if (level->lava == NULL) {
RETURN_LT(lt, NULL);
level->back_platforms = PUSH_LT(
lt,
- create_platforms_from_rect_layer(level_editor->back_platforms_layer),
+ create_platforms_from_rect_layer(&level_editor->back_platforms_layer),
destroy_platforms);
if (level->back_platforms == NULL) {
RETURN_LT(lt, NULL);
level->boxes = PUSH_LT(
lt,
- create_boxes_from_rect_layer(level_editor->boxes_layer, level->rigid_bodies),
+ create_boxes_from_rect_layer(&level_editor->boxes_layer, level->rigid_bodies),
destroy_boxes);
if (level->boxes == NULL) {
RETURN_LT(lt, NULL);
level->regions = PUSH_LT(
lt,
create_regions_from_rect_layer(
- level_editor->regions_layer,
+ &level_editor->regions_layer,
level->labels,
level->goals),
destroy_regions);
level_editor->player_layer =
create_player_layer(vec(0.0f, 0.0f), hexstr("ff8080"));
- level_editor->platforms_layer = PUSH_LT(
- lt,
- create_rect_layer("platform", cursor),
- destroy_rect_layer);
- if (level_editor->platforms_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
+ level_editor->platforms_layer = create_rect_layer("platform", cursor);
level_editor->goals_layer = PUSH_LT(
lt,
RETURN_LT(lt, NULL);
}
- level_editor->lava_layer = PUSH_LT(
- lt,
- create_rect_layer("lava", cursor),
- destroy_rect_layer);
- if (level_editor->lava_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
-
- level_editor->back_platforms_layer = PUSH_LT(
- lt,
- create_rect_layer("back_platform", cursor),
- destroy_rect_layer);
- if (level_editor->back_platforms_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
-
- level_editor->boxes_layer = PUSH_LT(
- lt,
- create_rect_layer("box", cursor),
- destroy_rect_layer);
- if (level_editor->boxes_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
+ level_editor->lava_layer = create_rect_layer("lava", cursor);
+ level_editor->back_platforms_layer = create_rect_layer("back_platform", cursor);
+ level_editor->boxes_layer = create_rect_layer("box", cursor);
level_editor->label_layer = PUSH_LT(
lt,
RETURN_LT(lt, NULL);
}
- level_editor->regions_layer = PUSH_LT(
- lt,
- create_rect_layer("region", cursor),
- destroy_rect_layer);
- if (level_editor->regions_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
+ level_editor->regions_layer = create_rect_layer("region", cursor),
- level_editor->layers[LAYER_PICKER_BOXES] = rect_layer_as_layer(level_editor->boxes_layer);
- level_editor->layers[LAYER_PICKER_PLATFORMS] = rect_layer_as_layer(level_editor->platforms_layer);
- level_editor->layers[LAYER_PICKER_BACK_PLATFORMS] = rect_layer_as_layer(level_editor->back_platforms_layer);
+ level_editor->layers[LAYER_PICKER_BOXES] = rect_layer_as_layer(&level_editor->boxes_layer);
+ level_editor->layers[LAYER_PICKER_PLATFORMS] = rect_layer_as_layer(&level_editor->platforms_layer);
+ level_editor->layers[LAYER_PICKER_BACK_PLATFORMS] = rect_layer_as_layer(&level_editor->back_platforms_layer);
level_editor->layers[LAYER_PICKER_GOALS] = point_layer_as_layer(level_editor->goals_layer);
level_editor->layers[LAYER_PICKER_PLAYER] = player_layer_as_layer(&level_editor->player_layer);
- level_editor->layers[LAYER_PICKER_LAVA] = rect_layer_as_layer(level_editor->lava_layer);
- level_editor->layers[LAYER_PICKER_REGIONS] = rect_layer_as_layer(level_editor->regions_layer);
+ level_editor->layers[LAYER_PICKER_LAVA] = rect_layer_as_layer(&level_editor->lava_layer);
+ level_editor->layers[LAYER_PICKER_REGIONS] = rect_layer_as_layer(&level_editor->regions_layer);
level_editor->layers[LAYER_PICKER_BACKGROUND] = background_layer_as_layer(&level_editor->background_layer);
level_editor->layers[LAYER_PICKER_LABELS] = label_layer_as_layer(level_editor->label_layer);
level_editor->label_layer = chop_label_layer(&tmpmem, &input, "label");
level_editor->regions_layer = chop_rect_layer(&tmpmem, &input, "region", cursor),
- level_editor->layers[LAYER_PICKER_BOXES] = rect_layer_as_layer(level_editor->boxes_layer);
- level_editor->layers[LAYER_PICKER_PLATFORMS] = rect_layer_as_layer(level_editor->platforms_layer);
- level_editor->layers[LAYER_PICKER_BACK_PLATFORMS] = rect_layer_as_layer(level_editor->back_platforms_layer);
+ level_editor->layers[LAYER_PICKER_BOXES] = rect_layer_as_layer(&level_editor->boxes_layer);
+ level_editor->layers[LAYER_PICKER_PLATFORMS] = rect_layer_as_layer(&level_editor->platforms_layer);
+ level_editor->layers[LAYER_PICKER_BACK_PLATFORMS] = rect_layer_as_layer(&level_editor->back_platforms_layer);
level_editor->layers[LAYER_PICKER_GOALS] = point_layer_as_layer(level_editor->goals_layer);
level_editor->layers[LAYER_PICKER_PLAYER] = player_layer_as_layer(&level_editor->player_layer);
- level_editor->layers[LAYER_PICKER_LAVA] = rect_layer_as_layer(level_editor->lava_layer);
- level_editor->layers[LAYER_PICKER_REGIONS] = rect_layer_as_layer(level_editor->regions_layer);
+ level_editor->layers[LAYER_PICKER_LAVA] = rect_layer_as_layer(&level_editor->lava_layer);
+ level_editor->layers[LAYER_PICKER_REGIONS] = rect_layer_as_layer(&level_editor->regions_layer);
level_editor->layers[LAYER_PICKER_BACKGROUND] = background_layer_as_layer(&level_editor->background_layer);
level_editor->layers[LAYER_PICKER_LABELS] = label_layer_as_layer(level_editor->label_layer);
#include "game/level/level_editor/layer.h"
#include "game/level/level_editor/layer_picker.h"
#include "game/level/level_editor/undo_history.h"
+#include "game/level/level_editor/rect_layer.h"
#include "ui/wiggly_text.h"
#include "ui/cursor.h"
typedef struct LevelEditor LevelEditor;
-typedef struct RectLayer RectLayer;
typedef struct PointLayer PointLayer;
typedef struct LabelLayer LabelLayer;
typedef struct Sound_samples Sound_samples;
LayerPicker layer_picker;
FadingWigglyText notice;
- RectLayer *boxes_layer;
- RectLayer *platforms_layer;
- RectLayer *back_platforms_layer;
+ RectLayer boxes_layer;
+ RectLayer platforms_layer;
+ RectLayer back_platforms_layer;
PointLayer *goals_layer;
PlayerLayer player_layer;
- RectLayer *lava_layer;
- RectLayer *regions_layer;
+ RectLayer lava_layer;
+ RectLayer regions_layer;
BackgroundLayer background_layer;
LabelLayer *label_layer;
CURSOR_STYLE_RESIZE_DIAG1 // [12]
};
-typedef enum {
- RECT_LAYER_IDLE = 0,
- RECT_LAYER_CREATE,
- RECT_LAYER_RESIZE,
- RECT_LAYER_MOVE,
- RECT_LAYER_ID_RENAME,
- RECT_LAYER_RECOLOR
-} RectLayerState;
-
-struct RectLayer {
- Lt *lt;
- RectLayerState state;
- int resize_mask;
- Dynarray ids;
- Dynarray rects;
- Dynarray colors;
- Dynarray actions;
- ColorPicker color_picker;
- Vec2f create_begin;
- Vec2f create_end;
- int selection;
- Vec2f move_anchor; // The mouse offset from the left-top
- // corner of the rect during moving it
- Edit_field id_edit_field;
- Color inter_color;
- Rect inter_rect;
- int id_name_counter;
- const char *id_name_prefix;
- Cursor *cursor;
-
- int snapping_enabled;
-};
-
typedef enum {
RECT_UNDO_ADD,
RECT_UNDO_DELETE,
return layer;
}
-RectLayer *create_rect_layer(const char *id_name_prefix, Cursor *cursor)
+RectLayer create_rect_layer(const char *id_name_prefix, Cursor *cursor)
{
trace_assert(cursor);
- Lt *lt = create_lt();
-
- RectLayer *layer = PUSH_LT(lt, nth_calloc(1, sizeof(RectLayer)), free);
- if (layer == NULL) {
- RETURN_LT(lt, NULL);
- }
- layer->lt = lt;
-
- layer->ids = create_dynarray(sizeof(char) * ENTITY_MAX_ID_SIZE);
- layer->rects = create_dynarray(sizeof(Rect));
- layer->colors = create_dynarray(sizeof(Color));
- layer->actions = create_dynarray(sizeof(Action));
+ RectLayer result = {0};
- layer->id_edit_field.font_size = RECT_LAYER_ID_LABEL_SIZE;
- layer->id_edit_field.font_color = COLOR_BLACK;
+ result.ids = create_dynarray(sizeof(char) * ENTITY_MAX_ID_SIZE);
+ result.rects = create_dynarray(sizeof(Rect));
+ result.colors = create_dynarray(sizeof(Color));
+ result.actions = create_dynarray(sizeof(Action));
+ result.id_edit_field.font_size = RECT_LAYER_ID_LABEL_SIZE;
+ result.id_edit_field.font_color = COLOR_BLACK;
+ result.color_picker = create_color_picker_from_rgba(rgba(1.0f, 0.0f, 0.0f, 1.0f));
+ result.selection = -1;
+ result.id_name_prefix = id_name_prefix;
+ result.cursor = cursor;
- layer->color_picker = create_color_picker_from_rgba(rgba(1.0f, 0.0f, 0.0f, 1.0f));
- layer->selection = -1;
- layer->id_name_prefix = id_name_prefix;
- layer->cursor = cursor;
-
- return layer;
+ return result;
}
-RectLayer *chop_rect_layer(Memory *memory,
- String *input,
- const char *id_name_prefix,
- Cursor *cursor)
+RectLayer chop_rect_layer(Memory *memory,
+ String *input,
+ const char *id_name_prefix,
+ Cursor *cursor)
{
trace_assert(memory);
trace_assert(input);
- RectLayer *layer = create_rect_layer(id_name_prefix, cursor);
- trace_assert(layer);
+ RectLayer layer = create_rect_layer(id_name_prefix, cursor);
int n = atoi(string_to_cstr(memory, trim(chop_by_delim(input, '\n'))));
char id[ENTITY_MAX_ID_SIZE];
string_id.data,
min_size_t(ENTITY_MAX_ID_SIZE - 1, string_id.count));
- dynarray_push(&layer->rects, &rect);
- dynarray_push(&layer->colors, &color);
- dynarray_push(&layer->ids, id);
+ dynarray_push(&layer.rects, &rect);
+ dynarray_push(&layer.colors, &color);
+ dynarray_push(&layer.ids, id);
Action action = {
.type = ACTION_NONE,
}
}
- dynarray_push(&layer->actions, &action);
+ dynarray_push(&layer.actions, &action);
}
return layer;
}
-void destroy_rect_layer(RectLayer *layer)
-{
- trace_assert(layer);
-
- free(layer->ids.data);
- free(layer->rects.data);
- free(layer->colors.data);
- free(layer->actions.data);
-
- RETURN_LT0(layer->lt);
-}
-
int rect_layer_render(const RectLayer *layer, const Camera *camera, int active)
{
trace_assert(layer);
typedef struct RectLayer RectLayer;
+typedef enum {
+ RECT_LAYER_IDLE = 0,
+ RECT_LAYER_CREATE,
+ RECT_LAYER_RESIZE,
+ RECT_LAYER_MOVE,
+ RECT_LAYER_ID_RENAME,
+ RECT_LAYER_RECOLOR
+} RectLayerState;
+
+struct RectLayer {
+ RectLayerState state;
+ int resize_mask;
+ Dynarray ids;
+ Dynarray rects;
+ Dynarray colors;
+ Dynarray actions;
+ ColorPicker color_picker;
+ Vec2f create_begin;
+ Vec2f create_end;
+ int selection;
+ Vec2f move_anchor; // The mouse offset from the left-top
+ // corner of the rect during moving it
+ Edit_field id_edit_field;
+ Color inter_color;
+ Rect inter_rect;
+ int id_name_counter;
+ const char *id_name_prefix;
+ Cursor *cursor;
+
+ int snapping_enabled;
+};
+
LayerPtr rect_layer_as_layer(RectLayer *layer);
// NOTE: create_rect_layer and create_rect_layer_from_line_stream does
// not own id_name_prefix
-RectLayer *create_rect_layer(const char *id_name_prefix,
- Cursor *cursor);
-RectLayer *chop_rect_layer(Memory *memory,
- String *input,
- const char *id_name_prefix,
- Cursor *cursor);
-void destroy_rect_layer(RectLayer *layer);
+RectLayer create_rect_layer(const char *id_name_prefix,
+ Cursor *cursor);
+RectLayer chop_rect_layer(Memory *memory,
+ String *input,
+ const char *id_name_prefix,
+ Cursor *cursor);
+
+static inline
+void destroy_rect_layer(RectLayer layer)
+{
+ free(layer.ids.data);
+ free(layer.rects.data);
+ free(layer.colors.data);
+ free(layer.actions.data);
+}
+
int rect_layer_render(const RectLayer *layer, const Camera *camera, int active);
int rect_layer_event(RectLayer *layer,