Added additional check to scrollbar drawing.
Color color_scale(Color c, Color fc);
-static inline
-Color color_set_alpha(Color c, float a)
-{
- c.a = a;
- return c;
-}
-
#endif // COLOR_H_
#define EDIT_FIELD_CAPACITY 256
+#define TMPMEM_CAPACITY (640 * KILO)
+
#endif // CONFIG_H_
#include "game/settings.h"
#include "game/credits.h"
-
typedef struct Game {
Lt *lt;
Game_state state;
Sprite_font font;
+ Memory tmpmem;
LevelPicker level_picker;
- LevelEditor *level_editor;
- Credits *credits;
+ LevelEditor level_editor;
+ Credits credits;
Level *level;
Settings settings;
Sound_samples *sound_samples;
renderer,
"./assets/images/charmap-oldschool.bmp");
+ game->tmpmem.capacity = TMPMEM_CAPACITY;
+ game->tmpmem.buffer = malloc(TMPMEM_CAPACITY);
+ trace_assert(game->tmpmem.buffer);
+
level_picker_populate(&game->level_picker, level_folder);
- game->credits = PUSH_LT(
- lt,
- create_credits(),
- destroy_credits);
- if (game->credits == NULL) {
- RETURN_LT(lt, NULL);
- }
+ game->credits = create_credits();
game->sound_samples = PUSH_LT(
lt,
}
}
+ create_level_editor(&game->level_editor, &game->cursor);
game->console = PUSH_LT(
lt,
{
trace_assert(game);
destroy_level_picker(game->level_picker);
+ free(game->tmpmem.buffer);
RETURN_LT0(game->lt);
}
} break;
case GAME_STATE_LEVEL_EDITOR: {
- if (level_editor_render(game->level_editor, &game->camera) < 0) {
+ if (level_editor_render(&game->level_editor, &game->camera) < 0) {
return -1;
}
} break;
case GAME_STATE_CREDITS: {
- if (credits_render(game->credits, &game->camera) < 0) {
+ if (credits_render(&game->credits, &game->camera) < 0) {
return -1;
}
} break;
case GAME_STATE_LEVEL:
return level_sound(game->level, game->sound_samples);
case GAME_STATE_LEVEL_EDITOR:
- level_editor_sound(game->level_editor, game->sound_samples);
+ level_editor_sound(&game->level_editor, game->sound_samples);
return 0;
case GAME_STATE_LEVEL_PICKER:
case GAME_STATE_CREDITS:
case GAME_STATE_LEVEL_EDITOR: {
if (level_editor_focus_camera(
- game->level_editor,
+ &game->level_editor,
&game->camera) < 0) {
return -1;
}
- level_editor_update(game->level_editor, delta_time);
+ level_editor_update(&game->level_editor, delta_time);
} break;
case GAME_STATE_CREDITS: {
- if (credits_update(game->credits, &game->camera, delta_time) < 0) {
+ if (credits_update(&game->credits, &game->camera, delta_time) < 0) {
return -1;
}
} break;
game->lt,
game->level,
create_level_from_level_editor(
- game->level_editor));
+ &game->level_editor));
if (game->level == NULL) {
game_switch_state(game, GAME_STATE_QUIT);
return -1;
case SDL_KEYDOWN: {
switch(event->key.keysym.sym) {
case SDLK_n: {
- if (game->level_editor == NULL) {
- game->level_editor = PUSH_LT(
- game->lt,
- create_level_editor(&game->cursor),
- destroy_level_editor);
- } else {
- game->level_editor = RESET_LT(
- game->lt,
- game->level_editor,
- create_level_editor(&game->cursor));
- }
-
- if (game->level_editor == NULL) {
- return -1;
- }
+ level_editor_clean(&game->level_editor);
if (game->level == NULL) {
game->level = PUSH_LT(
game->lt,
create_level_from_level_editor(
- game->level_editor),
+ &game->level_editor),
destroy_level);
} else {
game->level = RESET_LT(
game->lt,
game->level,
create_level_from_level_editor(
- game->level_editor));
+ &game->level_editor));
}
if (game->level == NULL) {
game->lt,
game->level,
create_level_from_level_editor(
- game->level_editor));
+ &game->level_editor));
if (game->level == NULL) {
return -1;
}
} break;
}
- return level_editor_event(game->level_editor, event, &game->camera);
+ return level_editor_event(&game->level_editor, event, &game->camera);
}
int game_event(Game *game, const SDL_Event *event)
trace_assert(game);
trace_assert(level_filename);
- if (game->level_editor == NULL) {
- game->level_editor = PUSH_LT(
- game->lt,
- create_level_editor_from_file(level_filename, &game->cursor),
- destroy_level_editor);
- } else {
- game->level_editor = RESET_LT(
- game->lt,
- game->level_editor,
- create_level_editor_from_file(level_filename, &game->cursor));
- }
-
- if (game->level_editor == NULL) {
- return -1;
- }
+ memory_clean(&game->tmpmem);
+ level_editor_load_from_file(&game->level_editor, &game->tmpmem, level_filename);
if (game->level == NULL) {
game->level = PUSH_LT(
game->lt,
create_level_from_level_editor(
- game->level_editor),
+ &game->level_editor),
destroy_level);
} else {
game->level = RESET_LT(
game->lt,
game->level,
create_level_from_level_editor(
- game->level_editor));
+ &game->level_editor));
}
if (game->level == NULL) {
#define TITLE_MARGIN_TOP 100.0f
-struct Credits
+Credits create_credits(void)
{
- Lt *lt;
- Background background;
- Vec2f camera_position;
- WigglyText wiggly_text;
-};
-
-Credits *create_credits(void)
-{
- Lt *lt = create_lt();
- Credits *credits = PUSH_LT(
- lt,
- nth_calloc(1, sizeof(Credits)),
- free);
- if (credits == NULL) {
- RETURN_LT(lt, NULL);
- }
- credits->lt = lt;
-
- credits->background = create_background(hexstr("250741"));
-
- credits->camera_position = vec(0.0f, 0.0f);
-
- credits->wiggly_text = (WigglyText) {
+ Credits result;
+ result.background = create_background(hexstr("250741"));
+ result.camera_position = vec(0.0f, 0.0f);
+ result.wiggly_text = (WigglyText) {
.text = "Twitch Subs/Contributors",
.scale = {8.0f, 8.0f},
.color = COLOR_WHITE,
};
-
- return credits;
-}
-
-void destroy_credits(Credits *credits)
-{
- trace_assert(credits);
- RETURN_LT0(credits->lt);
+ return result;
}
int credits_render(const Credits *credits, const Camera *camera)
#include <SDL.h>
#include "game/camera.h"
+#include "game/level/background.h"
+#include "ui/wiggly_text.h"
-typedef struct Credits Credits;
+typedef struct {
+ Background background;
+ Vec2f camera_position;
+ WigglyText wiggly_text;
+} Credits;
-Credits *create_credits(void);
+
+Credits create_credits(void);
void destroy_credits(Credits *credits);
int credits_render(const Credits *credits,
const Camera *camera);
int credits_update(Credits *credits,
- Camera *camera, float dt);
+ Camera *camera, float dt);
#endif // CREDITS_H_
level->goals = PUSH_LT(
lt,
- create_goals_from_point_layer(level_editor->goals_layer),
+ create_goals_from_point_layer(&level_editor->goals_layer),
destroy_goals);
if (level->goals == NULL) {
RETURN_LT(lt, NULL);
level->labels = PUSH_LT(
lt,
- create_labels_from_label_layer(level_editor->label_layer),
+ create_labels_from_label_layer(&level_editor->label_layer),
destroy_labels);
if (level->labels == NULL) {
RETURN_LT(lt, NULL);
#include "game/camera.h"
#include "game/level/player.h"
#include "game/sound_samples.h"
+#include "game/level/level_editor/point_layer.h"
#include "config.h"
typedef struct Goals Goals;
-typedef struct PointLayer PointLayer;
Goals *create_goals_from_point_layer(const PointLayer *point_layer);
void destroy_goals(Goals *goals);
#include "math/vec.h"
#include "color.h"
#include "config.h"
+#include "game/level/level_editor/label_layer.h"
typedef struct Labels Labels;
-typedef struct LabelLayer LabelLayer;
Labels *create_labels_from_label_layer(const LabelLayer *label_layer);
void destroy_labels(Labels *label);
#include "ui/edit_field.h"
#include "system/stacktrace.h"
#include "system/nth_alloc.h"
-#include "system/lt.h"
-#include "system/lt_adapters.h"
#include "system/log.h"
#include "system/str.h"
#include "config.h"
#define LEVEL_EDITOR_NOTICE_SCALE vec(10.0f, 10.0f)
#define LEVEL_EDITOR_NOTICE_DURATION 1.0f
#define LEVEL_EDITOR_NOTICE_PADDING_TOP 100.0f
-#define LEVEL_EDITOR_TMPMEM_CAPACITY (640 * KILO)
static int level_editor_dump(LevelEditor *level_editor);
// TODO(#994): too much duplicate code between create_level_editor and create_level_editor_from_file
-LevelEditor *create_level_editor(Cursor *cursor)
+void create_level_editor(LevelEditor *level_editor, Cursor *cursor)
{
- Lt *lt = create_lt();
- LevelEditor *level_editor = PUSH_LT(
- lt,
- nth_calloc(1, sizeof(LevelEditor)),
- free);
- if (level_editor == NULL) {
- RETURN_LT(lt, NULL);
- }
- level_editor->lt = lt;
+ memset(level_editor, 0, sizeof(*level_editor));
level_editor->edit_field_filename.font_size = LEVEL_EDITOR_EDIT_FIELD_SIZE;
level_editor->edit_field_filename.font_color = LEVEL_EDITOR_EDIT_FIELD_COLOR;
level_editor->background_layer = create_background_layer(hexstr("fffda5"));
-
- level_editor->player_layer =
- create_player_layer(vec(0.0f, 0.0f), hexstr("ff8080"));
-
+ level_editor->player_layer = create_player_layer(vec(0.0f, 0.0f), hexstr("ff8080"));
level_editor->platforms_layer = create_rect_layer("platform", cursor);
-
- level_editor->goals_layer = PUSH_LT(
- lt,
- create_point_layer("goal"),
- destroy_point_layer);
- if (level_editor->goals_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
-
+ level_editor->goals_layer = create_point_layer("goal"),
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,
- create_label_layer("label"),
- destroy_label_layer);
- if (level_editor->label_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
-
+ level_editor->label_layer = create_label_layer("label");
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_GOALS] = point_layer_as_layer(level_editor->goals_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_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->layers[LAYER_PICKER_LABELS] = label_layer_as_layer(&level_editor->label_layer);
level_editor->notice = (FadingWigglyText) {
.wiggly_text = {
};
level_editor->camera_scale = 1.0f;
-
level_editor->undo_history = create_undo_history();
-
- return level_editor;
}
-LevelEditor *create_level_editor_from_file(const char *file_name, Cursor *cursor)
+void level_editor_load_from_file(LevelEditor *level_editor, Memory *tmpmem, const char *file_name)
{
trace_assert(file_name);
- Lt *lt = create_lt();
- LevelEditor *level_editor = PUSH_LT(
- lt,
- nth_calloc(1, sizeof(LevelEditor)),
- free);
- if (level_editor == NULL) {
- RETURN_LT(lt, NULL);
- }
- level_editor->lt = lt;
+ if (level_editor->file_name) free(level_editor->file_name);
+ level_editor->file_name = string_duplicate(file_name, NULL);
- level_editor->edit_field_filename.font_size = LEVEL_EDITOR_EDIT_FIELD_SIZE;
- level_editor->edit_field_filename.font_color = LEVEL_EDITOR_EDIT_FIELD_COLOR;
-
- level_editor->file_name =
- PUSH_LT(
- lt,
- string_duplicate(file_name, NULL),
- free);
-
- Memory tmpmem = {
- .capacity = LEVEL_EDITOR_TMPMEM_CAPACITY,
- .buffer = malloc(LEVEL_EDITOR_TMPMEM_CAPACITY),
- };
- trace_assert(tmpmem.buffer);
-
- String input = read_whole_file(&tmpmem, file_name);
+ String input = read_whole_file(tmpmem, file_name);
trace_assert(input.data);
String version = trim(chop_by_delim(&input, '\n'));
// Nothing
} else {
log_fail("Version `%s` is not supported. Expected version `%s`.\n",
- string_to_cstr(&tmpmem, version),
+ string_to_cstr(tmpmem, version),
VERSION);
- RETURN_LT(lt, NULL);
+ return;
}
level_editor->background_layer = chop_background_layer(&input);
- level_editor->player_layer = chop_player_layer(&tmpmem, &input);
- level_editor->platforms_layer = chop_rect_layer(&tmpmem, &input, "platform", cursor);
- level_editor->goals_layer = chop_point_layer(&tmpmem, &input, "goal");
- level_editor->lava_layer = chop_rect_layer(&tmpmem, &input, "lava", cursor);
- level_editor->back_platforms_layer = chop_rect_layer(&tmpmem, &input, "back_platform", cursor);
- level_editor->boxes_layer = chop_rect_layer(&tmpmem, &input, "box", cursor);
- 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_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_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->drag = false;
-
- level_editor->notice = (FadingWigglyText) {
- .wiggly_text = {
- .text = "Level saved",
- .color = rgba(0.0f, 0.0f, 0.0f, 0.0f),
- .scale = LEVEL_EDITOR_NOTICE_SCALE
- },
- .duration = LEVEL_EDITOR_NOTICE_DURATION,
- };
+ level_editor->player_layer = chop_player_layer(tmpmem, &input);
+ rect_layer_reload(&level_editor->platforms_layer, tmpmem, &input);
+ point_layer_reload(&level_editor->goals_layer, tmpmem, &input);
+ rect_layer_reload(&level_editor->lava_layer, tmpmem, &input);
+ rect_layer_reload(&level_editor->back_platforms_layer, tmpmem, &input);
+ rect_layer_reload(&level_editor->boxes_layer, tmpmem, &input);
+ label_layer_reload(&level_editor->label_layer, tmpmem, &input);
+ rect_layer_reload(&level_editor->regions_layer, tmpmem, &input);
+ undo_history_clean(&level_editor->undo_history);
+}
+void level_editor_clean(LevelEditor *level_editor)
+{
level_editor->camera_scale = 1.0f;
-
- level_editor->undo_history = create_undo_history();
-
- free(tmpmem.buffer);
-
- return level_editor;
+ level_editor->camera_position = vec(0.0f, 0.0f);
+ if (level_editor->file_name) {
+ free(level_editor->file_name);
+ level_editor->file_name = NULL;
+ }
+ level_editor->background_layer = create_background_layer(hexstr("fffda5"));
+ level_editor->player_layer = create_player_layer(vec(0.0f, 0.0f), hexstr("ff8080"));
+ rect_layer_clean(&level_editor->platforms_layer);
+ point_layer_clean(&level_editor->goals_layer);
+ rect_layer_clean(&level_editor->lava_layer);
+ rect_layer_clean(&level_editor->back_platforms_layer);
+ rect_layer_clean(&level_editor->boxes_layer);
+ label_layer_clean(&level_editor->label_layer);
+ rect_layer_clean(&level_editor->regions_layer);
+ undo_history_clean(&level_editor->undo_history);
}
void destroy_level_editor(LevelEditor *level_editor)
{
trace_assert(level_editor);
destroy_undo_history(level_editor->undo_history);
- RETURN_LT0(level_editor->lt);
+ destroy_rect_layer(level_editor->boxes_layer);
+ destroy_rect_layer(level_editor->platforms_layer);
+ destroy_rect_layer(level_editor->back_platforms_layer);
+ destroy_point_layer(level_editor->goals_layer);
+ destroy_rect_layer(level_editor->lava_layer);
+ destroy_rect_layer(level_editor->regions_layer);
+ destroy_label_layer(level_editor->label_layer);
+
+ if (level_editor->file_name) {
+ free(level_editor->file_name);
+ }
}
int level_editor_render(const LevelEditor *level_editor,
LEVEL_FOLDER_MAX_LENGTH,
"./assets/levels/%s.txt",
edit_field_as_text(&level_editor->edit_field_filename));
- level_editor->file_name = PUSH_LT(
- level_editor->lt,
- string_duplicate(path, NULL),
- free);
+ level_editor->file_name = string_duplicate(path, NULL);
level_editor_dump(level_editor);
SDL_StopTextInput();
level_editor->state = LEVEL_EDITOR_IDLE;
{
trace_assert(level_editor);
- FILE *filedump = PUSH_LT(
- level_editor->lt,
- fopen(level_editor->file_name, "w"),
- fclose_lt);
+ FILE *filedump = fopen(level_editor->file_name, "w");
+ trace_assert(filedump);
if (fprintf(filedump, "%s\n", VERSION) < 0) {
return -1;
}
}
- fclose(RELEASE_LT(level_editor->lt, filedump));
+ fclose(filedump);
fading_wiggly_text_reset(&level_editor->notice);
level_editor->save = 1;
#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 "game/level/level_editor/point_layer.h"
+#include "game/level/level_editor/label_layer.h"
#include "ui/wiggly_text.h"
#include "ui/cursor.h"
typedef struct LevelEditor LevelEditor;
-typedef struct PointLayer PointLayer;
-typedef struct LabelLayer LabelLayer;
typedef struct Sound_samples Sound_samples;
typedef enum {
struct LevelEditor
{
- Lt *lt;
LevelEditorState state;
Vec2f camera_position;
float camera_scale;
RectLayer boxes_layer;
RectLayer platforms_layer;
RectLayer back_platforms_layer;
- PointLayer *goals_layer;
+ PointLayer goals_layer;
PlayerLayer player_layer;
RectLayer lava_layer;
RectLayer regions_layer;
BackgroundLayer background_layer;
- LabelLayer *label_layer;
+ LabelLayer label_layer;
LayerPtr layers[LAYER_PICKER_N];
int click;
int save;
- const char *file_name;
+ char *file_name;
};
-LevelEditor *create_level_editor(Cursor *cursor);
-LevelEditor *create_level_editor_from_file(const char *file_name, Cursor *cursor);
+void create_level_editor(LevelEditor *level_editor, Cursor *cursor);
+void level_editor_load_from_file(LevelEditor *level_editor, Memory *tmpmem, const char *file_name);
+void level_editor_clean(LevelEditor *level_editor);
void destroy_level_editor(LevelEditor *level_editor);
int level_editor_render(const LevelEditor *level_editor,
#include "system/stacktrace.h"
#include "system/nth_alloc.h"
-#include "system/lt.h"
#include "system/str.h"
#include "system/log.h"
#include "math/vec.h"
// TODO(#1139): Label Layer does not support snapping
-typedef enum {
- LABEL_LAYER_IDLE = 0,
- LABEL_LAYER_MOVE,
- LABEL_LAYER_EDIT_TEXT,
- LABEL_LAYER_EDIT_ID,
- LABEL_LAYER_RECOLOR
-} LabelLayerState;
-
static int label_clipboard = 0;
static char label_clipboard_text[LABEL_LAYER_TEXT_MAX_SIZE];
static Color label_clipboard_color;
-struct LabelLayer {
- Lt *lt;
- LabelLayerState state;
- Dynarray ids;
- Dynarray positions;
- Dynarray colors;
- Dynarray texts;
- int selection;
- ColorPicker color_picker;
- Vec2f move_anchor;
- Edit_field edit_field;
- Vec2f inter_position;
- Color inter_color;
- int id_name_counter;
- const char *id_name_prefix;
-};
-
typedef enum {
LABEL_UNDO_ADD,
LABEL_UNDO_DELETE,
return layer;
}
-LabelLayer *create_label_layer(const char *id_name_prefix)
+LabelLayer create_label_layer(const char *id_name_prefix)
{
- Lt *lt = create_lt();
-
- LabelLayer *label_layer = PUSH_LT(
- lt, nth_calloc(1, sizeof(LabelLayer)), free);
- if (label_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
- label_layer->lt = lt;
-
- label_layer->ids = create_dynarray(sizeof(char) * LABEL_LAYER_ID_MAX_SIZE);
- label_layer->positions = create_dynarray(sizeof(Vec2f));
- label_layer->colors = create_dynarray(sizeof(Color));
- label_layer->texts = create_dynarray(sizeof(char) * LABEL_LAYER_TEXT_MAX_SIZE);
-
- label_layer->color_picker = create_color_picker_from_rgba(COLOR_RED);
- label_layer->selection = -1;
-
- label_layer->edit_field.font_size = LABELS_SIZE;
- label_layer->edit_field.font_color = COLOR_RED;
-
- label_layer->id_name_prefix = id_name_prefix;
-
- return label_layer;
+ LabelLayer result = {0};
+ result.ids = create_dynarray(sizeof(char) * LABEL_LAYER_ID_MAX_SIZE);
+ result.positions = create_dynarray(sizeof(Vec2f));
+ result.colors = create_dynarray(sizeof(Color));
+ result.texts = create_dynarray(sizeof(char) * LABEL_LAYER_TEXT_MAX_SIZE);
+ result.color_picker = create_color_picker_from_rgba(COLOR_RED);
+ result.selection = -1;
+ result.edit_field.font_size = LABELS_SIZE;
+ result.edit_field.font_color = COLOR_RED;
+ result.id_name_prefix = id_name_prefix;
+ return result;
}
-LabelLayer *chop_label_layer(Memory *memory,
- String *input,
- const char *id_name_prefix)
+void label_layer_reload(LabelLayer *label_layer,
+ Memory *memory,
+ String *input)
{
+ trace_assert(label_layer);
trace_assert(memory);
trace_assert(input);
- trace_assert(id_name_prefix);
- LabelLayer *label_layer = create_label_layer(id_name_prefix);
+ label_layer_clean(label_layer);
int n = atoi(string_to_cstr(memory, trim(chop_by_delim(input, '\n'))));
char id[LABEL_LAYER_ID_MAX_SIZE];
dynarray_push(&label_layer->colors, &color);
dynarray_push(&label_layer->texts, label_text);
}
-
- return label_layer;
}
-void destroy_label_layer(LabelLayer *label_layer)
+void label_layer_clean(LabelLayer *label_layer)
{
trace_assert(label_layer);
-
- free(label_layer->ids.data);
- free(label_layer->positions.data);
- free(label_layer->colors.data);
- free(label_layer->texts.data);
-
- destroy_lt(label_layer->lt);
+ dynarray_clear(&label_layer->ids);
+ dynarray_clear(&label_layer->positions);
+ dynarray_clear(&label_layer->colors);
+ dynarray_clear(&label_layer->texts);
}
static inline
#include "layer.h"
#include "color.h"
#include "math/vec.h"
+#include "dynarray.h"
+#include "game/level/level_editor/color_picker.h"
+#include "ui/edit_field.h"
#define LABELS_SIZE vec(2.0f, 2.0f)
#define LABEL_LAYER_ID_MAX_SIZE 36
#define LABEL_LAYER_TEXT_MAX_SIZE 256
-typedef struct LabelLayer LabelLayer;
+typedef enum {
+ LABEL_LAYER_IDLE = 0,
+ LABEL_LAYER_MOVE,
+ LABEL_LAYER_EDIT_TEXT,
+ LABEL_LAYER_EDIT_ID,
+ LABEL_LAYER_RECOLOR
+} LabelLayerState;
+
+typedef struct {
+ LabelLayerState state;
+ Dynarray ids;
+ Dynarray positions;
+ Dynarray colors;
+ Dynarray texts;
+ int selection;
+ ColorPicker color_picker;
+ Vec2f move_anchor;
+ Edit_field edit_field;
+ Vec2f inter_position;
+ Color inter_color;
+ int id_name_counter;
+ const char *id_name_prefix;
+} LabelLayer;
LayerPtr label_layer_as_layer(LabelLayer *label_layer);
// NOTE: create_label_layer and create_label_layer_from_line_stream do
// not own id_name_prefix
-LabelLayer *create_label_layer(const char *id_name_prefix);
-LabelLayer *chop_label_layer(Memory *memory,
- String *input,
- const char *id_name_prefix);
-void destroy_label_layer(LabelLayer *label_layer);
+LabelLayer create_label_layer(const char *id_name_prefix);
+void label_layer_reload(LabelLayer *label_layer,
+ Memory *memory,
+ String *input);
+void label_layer_clean(LabelLayer *label_layer);
+
+static inline
+void destroy_label_layer(LabelLayer label_layer)
+{
+ free(label_layer.ids.data);
+ free(label_layer.positions.data);
+ free(label_layer.colors.data);
+ free(label_layer.texts.data);
+}
int label_layer_render(const LabelLayer *label_layer,
const Camera *camera,
#include "color_picker.h"
#include "layer.h"
-#include "system/lt.h"
#include "system/memory.h"
#include "system/s.h"
#include "dynarray.h"
#include "game/camera.h"
#include "system/log.h"
-#include "system/lt.h"
#include "system/nth_alloc.h"
#include "system/stacktrace.h"
#include "system/str.h"
// TODO(#1140): PointLayer does not support snapping
-typedef enum {
- POINT_LAYER_IDLE = 0,
- POINT_LAYER_EDIT_ID,
- POINT_LAYER_MOVE,
- POINT_LAYER_RECOLOR
-} PointLayerState;
-
-struct PointLayer
-{
- Lt *lt;
- PointLayerState state;
- Dynarray/*<Vec2f>*/ positions;
- Dynarray/*<Color>*/ colors;
- Dynarray/*<char[ID_MAX_SIZE]>*/ ids;
- int selection;
- ColorPicker color_picker;
-
- Vec2f inter_position;
- Color inter_color;
- Edit_field edit_field;
-
- int id_name_counter;
- const char *id_name_prefix;
-};
-
typedef enum {
POINT_UNDO_ADD,
POINT_UNDO_DELETE,
return layer;
}
-PointLayer *create_point_layer(const char *id_name_prefix)
+PointLayer create_point_layer(const char *id_name_prefix)
{
- Lt *lt = create_lt();
-
- PointLayer *point_layer = PUSH_LT(lt, nth_calloc(1, sizeof(PointLayer)), free);
- if (point_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
- point_layer->lt = lt;
-
- point_layer->state = POINT_LAYER_IDLE;
-
- point_layer->positions = create_dynarray(sizeof(Vec2f));
- point_layer->colors = create_dynarray(sizeof(Color));
- point_layer->ids = create_dynarray(sizeof(char) * ID_MAX_SIZE);
-
- point_layer->edit_field.font_size = POINT_LAYER_ID_TEXT_SIZE;
- point_layer->edit_field.font_color = POINT_LAYER_ID_TEXT_COLOR;
-
- point_layer->id_name_prefix = id_name_prefix;
-
- return point_layer;
+ PointLayer result = {0};
+ result.state = POINT_LAYER_IDLE;
+ result.positions = create_dynarray(sizeof(Vec2f));
+ result.colors = create_dynarray(sizeof(Color));
+ result.ids = create_dynarray(sizeof(char) * ID_MAX_SIZE);
+ result.edit_field.font_size = POINT_LAYER_ID_TEXT_SIZE;
+ result.edit_field.font_color = POINT_LAYER_ID_TEXT_COLOR;
+ result.id_name_prefix = id_name_prefix;
+ return result;
}
-PointLayer *chop_point_layer(Memory *memory,
- String *input,
- const char *id_name_prefix)
+void point_layer_reload(PointLayer *point_layer,
+ Memory *memory,
+ String *input)
{
+ trace_assert(point_layer);
trace_assert(memory);
trace_assert(input);
- trace_assert(id_name_prefix);
- PointLayer *point_layer = create_point_layer(id_name_prefix);
+ point_layer_clean(point_layer);
int n = atoi(string_to_cstr(memory, trim(chop_by_delim(input, '\n'))));
char id[ENTITY_MAX_ID_SIZE];
Color color = hexs(trim(chop_word(&line)));
memset(id, 0, ENTITY_MAX_ID_SIZE);
- memcpy(
- id,
- string_id.data,
- min_size_t(ENTITY_MAX_ID_SIZE - 1, string_id.count));
+ memcpy(id, string_id.data, min_size_t(ENTITY_MAX_ID_SIZE - 1, string_id.count));
dynarray_push(&point_layer->positions, &point);
dynarray_push(&point_layer->colors, &color);
dynarray_push(&point_layer->ids, id);
}
-
- point_layer->selection = -1;
- point_layer->color_picker = create_color_picker_from_rgba(COLOR_RED);
-
- return point_layer;
}
-void destroy_point_layer(PointLayer *point_layer)
+void point_layer_clean(PointLayer *point_layer)
{
trace_assert(point_layer);
-
- free(point_layer->positions.data);
- free(point_layer->colors.data);
- free(point_layer->ids.data);
-
- RETURN_LT0(point_layer->lt);
+ dynarray_clear(&point_layer->positions);
+ dynarray_clear(&point_layer->colors);
+ dynarray_clear(&point_layer->ids);
}
static inline
#include "math/vec.h"
#include "color.h"
#include "layer.h"
+#include "dynarray.h"
+#include "game/level/level_editor/color_picker.h"
+#include "ui/edit_field.h"
#define ID_MAX_SIZE 36
-typedef struct PointLayer PointLayer;
+typedef enum {
+ POINT_LAYER_IDLE = 0,
+ POINT_LAYER_EDIT_ID,
+ POINT_LAYER_MOVE,
+ POINT_LAYER_RECOLOR
+} PointLayerState;
+
+typedef struct {
+ PointLayerState state;
+ Dynarray/*<Vec2f>*/ positions;
+ Dynarray/*<Color>*/ colors;
+ Dynarray/*<char[ID_MAX_SIZE]>*/ ids;
+ int selection;
+ ColorPicker color_picker;
+
+ Vec2f inter_position;
+ Color inter_color;
+ Edit_field edit_field;
+
+ int id_name_counter;
+ const char *id_name_prefix;
+} PointLayer;
+
LayerPtr point_layer_as_layer(PointLayer *point_layer);
// NOTE: create_point_layer and create_point_layer_from_line_stream do
// not own id_name_prefix
-PointLayer *create_point_layer(const char *id_name_prefix);
-PointLayer *chop_point_layer(Memory *memory,
- String *input,
- const char *id_name_prefix);
-void destroy_point_layer(PointLayer *point_layer);
+PointLayer create_point_layer(const char *id_name_prefix);
+void point_layer_reload(PointLayer *point_layer,
+ Memory *memory,
+ String *input);
+void point_layer_clean(PointLayer *point_layer);
+
+
+static inline
+void destroy_point_layer(PointLayer point_layer)
+{
+ free(point_layer.positions.data);
+ free(point_layer.colors.data);
+ free(point_layer.ids.data);
+}
+
int point_layer_render(const PointLayer *point_layer,
const Camera *camera,
#include <errno.h>
#include "game/camera.h"
-#include "system/lt.h"
#include "system/stacktrace.h"
#include "system/nth_alloc.h"
#include "system/log.h"
return result;
}
-RectLayer chop_rect_layer(Memory *memory,
- String *input,
- const char *id_name_prefix,
- Cursor *cursor)
+void rect_layer_reload(RectLayer *layer, Memory *memory, String *input)
{
+ trace_assert(layer);
trace_assert(memory);
trace_assert(input);
- RectLayer layer = create_rect_layer(id_name_prefix, cursor);
+ rect_layer_clean(layer);
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 rect_layer_clean(RectLayer *rect_layer)
+{
+ trace_assert(rect_layer);
+ dynarray_clear(&rect_layer->ids);
+ dynarray_clear(&rect_layer->rects);
+ dynarray_clear(&rect_layer->colors);
+ dynarray_clear(&rect_layer->actions);
}
int rect_layer_render(const RectLayer *layer, const Camera *camera, int active)
// 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 rect_layer_reload(RectLayer *rect_layer, Memory *memory, String *input);
+void rect_layer_clean(RectLayer *rect_layer);
static inline
void destroy_rect_layer(RectLayer layer)
#include <SDL.h>
#include "system/nth_alloc.h"
-#include "system/lt.h"
#include "system/stacktrace.h"
#include "undo_history.h"
#include "config.h"
ring_buffer_pop(&undo_history->actions);
}
}
+
+void undo_history_clean(UndoHistory *undo_history)
+{
+ trace_assert(undo_history);
+
+ while (undo_history->actions.count) {
+ ring_buffer_pop(&undo_history->actions);
+ }
+}
size_t context_data_size);
void undo_history_pop(UndoHistory *undo_history);
+void undo_history_clean(UndoHistory *undo_history);
+
static inline
int undo_history_empty(UndoHistory *undo_history)
{