]> git.lizzy.rs Git - nothing.git/commitdiff
Merge pull request #1240 from aodhneine/1234
authorAlexey Kutepov <reximkut@gmail.com>
Sat, 11 Jan 2020 16:28:17 +0000 (23:28 +0700)
committerGitHub <noreply@github.com>
Sat, 11 Jan 2020 16:28:17 +0000 (23:28 +0700)
Added additional check to scrollbar drawing.

19 files changed:
src/color.h
src/config.h
src/game.c
src/game/credits.c
src/game/credits.h
src/game/level.c
src/game/level/goals.h
src/game/level/labels.h
src/game/level/level_editor.c
src/game/level/level_editor.h
src/game/level/level_editor/label_layer.c
src/game/level/level_editor/label_layer.h
src/game/level/level_editor/player_layer.h
src/game/level/level_editor/point_layer.c
src/game/level/level_editor/point_layer.h
src/game/level/level_editor/rect_layer.c
src/game/level/level_editor/rect_layer.h
src/game/level/level_editor/undo_history.c
src/game/level/level_editor/undo_history.h

index cffb7cf613f7e787d84fc6d76f58cb3447a27935..338a068dd14013388b52c41d6e841948255014a1 100644 (file)
@@ -31,11 +31,4 @@ Color color_invert(Color c);
 
 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_
index 59b4e9820b21bea818ad11e9c975d4f4d69a02d7..f26ea0d2564d3231ba2a21159cf3d007dc4fae88 100644 (file)
@@ -35,4 +35,6 @@
 
 #define EDIT_FIELD_CAPACITY 256
 
+#define TMPMEM_CAPACITY (640 * KILO)
+
 #endif  // CONFIG_H_
index 7e59f094b5dccccd2476bb10a8a54adf6f105bdb..d009528332486d6850404fb6abb5707874d11ecc 100644 (file)
 #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;
@@ -67,15 +67,13 @@ Game *create_game(const char *level_folder,
         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,
@@ -111,6 +109,7 @@ Game *create_game(const char *level_folder,
         }
     }
 
+    create_level_editor(&game->level_editor, &game->cursor);
 
     game->console = PUSH_LT(
         lt,
@@ -130,6 +129,7 @@ void destroy_game(Game *game)
 {
     trace_assert(game);
     destroy_level_picker(game->level_picker);
+    free(game->tmpmem.buffer);
     RETURN_LT0(game->lt);
 }
 
@@ -151,13 +151,13 @@ int game_render(const Game *game)
     } 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;
@@ -188,7 +188,7 @@ int game_sound(Game *game)
     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:
@@ -248,16 +248,16 @@ int game_update(Game *game, float delta_time)
 
     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;
@@ -290,7 +290,7 @@ static int game_event_running(Game *game, const SDL_Event *event)
                     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;
@@ -323,34 +323,20 @@ static int game_event_level_picker(Game *game, const SDL_Event *event)
     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) {
@@ -387,7 +373,7 @@ static int game_event_level_editor(Game *game, const SDL_Event *event)
                 game->lt,
                 game->level,
                 create_level_from_level_editor(
-                    game->level_editor));
+                    &game->level_editor));
             if (game->level == NULL) {
                 return -1;
             }
@@ -397,7 +383,7 @@ static int game_event_level_editor(Game *game, const SDL_Event *event)
     } 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)
@@ -540,34 +526,21 @@ int game_load_level(Game *game, const char *level_filename)
     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) {
index 9cbe82181e68ad8602664f34e25d70f708775032..41d42d1cbe2c8e8f71cf01360b7b7194d6242854 100644 (file)
 
 #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)
index acff02ef1b4d580cb5dbbb363be62d9a920cc2e0..866593c9bdbbd639ad0e2552b49e91cbb2f6e54b 100644 (file)
@@ -4,15 +4,22 @@
 #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_
index c1ffff77d533961464201f1469e442ea3828e20a..a65d621912ea56f4aea0532ea334d3227410af6d 100644 (file)
@@ -94,7 +94,7 @@ Level *create_level_from_level_editor(const LevelEditor *level_editor)
 
     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);
@@ -126,7 +126,7 @@ Level *create_level_from_level_editor(const LevelEditor *level_editor)
 
     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);
index 013fbd41d610997240aa39021b19014398d9b225..935d55e56bc0d3ffa1f8778c5b4b98569c2716a4 100644 (file)
@@ -6,10 +6,10 @@
 #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);
index 2291bc65d732d6b2cc65ccfb6ee7821f7c33b897..ef12bc387050a4d585d3141b0611d79b4300bfab 100644 (file)
@@ -4,9 +4,9 @@
 #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);
index 021cdd5664c249a37c3bf55a35ca01dd4c6da227..0a434caec56b09df5e064160e142972db5069b43 100644 (file)
@@ -12,8 +12,6 @@
 #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 = {
@@ -99,42 +69,17 @@ LevelEditor *create_level_editor(Cursor *cursor)
     };
 
     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'));
@@ -145,56 +90,58 @@ LevelEditor *create_level_editor_from_file(const char *file_name, Cursor *cursor
         // 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,
@@ -287,10 +234,7 @@ int level_editor_saveas_event(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;
@@ -453,10 +397,8 @@ static int level_editor_dump(LevelEditor *level_editor)
 {
     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;
@@ -470,7 +412,7 @@ static int level_editor_dump(LevelEditor *level_editor)
         }
     }
 
-    fclose(RELEASE_LT(level_editor->lt, filedump));
+    fclose(filedump);
 
     fading_wiggly_text_reset(&level_editor->notice);
     level_editor->save = 1;
index 4f6dac3adaadb94ee5857839560c74b5ce9a37cd..3750e748cbf389a64c2ab02ae1c7086ee0b811dd 100644 (file)
@@ -5,12 +5,12 @@
 #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 {
@@ -20,7 +20,6 @@ typedef enum {
 
 struct LevelEditor
 {
-    Lt *lt;
     LevelEditorState state;
     Vec2f camera_position;
     float camera_scale;
@@ -31,12 +30,12 @@ struct LevelEditor
     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];
 
@@ -47,11 +46,12 @@ struct LevelEditor
     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,
index 487b949cf985d7f8f7f3fa781d02e749095849d3..b4fa65022cdfb6c78ff2a8dd873a0607703b6f63 100644 (file)
@@ -4,7 +4,6 @@
 
 #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,
@@ -167,42 +141,30 @@ LayerPtr label_layer_as_layer(LabelLayer *label_layer)
     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];
@@ -236,20 +198,15 @@ LabelLayer *chop_label_layer(Memory *memory,
         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
index 00454a1bbf159f72f9fea845f8eb19d856d23246..718a57f44d960e8d044b5940e6fa3565bee2cedb 100644 (file)
@@ -4,22 +4,56 @@
 #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,
index 6144f3ff0ffa50d56c06a3e0cf99ebdea122e3f9..dd40d220dfa58cc3ea40ef300130c73932a9d2ca 100644 (file)
@@ -3,7 +3,6 @@
 
 #include "color_picker.h"
 #include "layer.h"
-#include "system/lt.h"
 #include "system/memory.h"
 #include "system/s.h"
 
index 89f3daa68c23b30699aa9dc7826c1522ddd3c729..735c3240866bd206c75c43a200bf9abadc1e1945 100644 (file)
@@ -5,7 +5,6 @@
 #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"
@@ -25,31 +24,6 @@ static Color point_clipboard_color;
 
 // 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,
@@ -165,39 +139,28 @@ LayerPtr point_layer_as_layer(PointLayer *point_layer)
     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];
@@ -210,31 +173,20 @@ PointLayer *chop_point_layer(Memory *memory,
         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
index d08df7104b541a4f8e86edd2faa9f61f4b1fa9cb..0505fb7ef1ce7db181d15b389511a48fc2cce6fb 100644 (file)
@@ -4,19 +4,54 @@
 #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,
index 65ce1d809ee478b4ba222d95e0913c654c8caa6a..447ecf7735ebe32d4006082c0387ffb203d2b76f 100644 (file)
@@ -2,7 +2,6 @@
 #include <errno.h>
 
 #include "game/camera.h"
-#include "system/lt.h"
 #include "system/stacktrace.h"
 #include "system/nth_alloc.h"
 #include "system/log.h"
@@ -817,15 +816,13 @@ RectLayer create_rect_layer(const char *id_name_prefix, Cursor *cursor)
     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];
@@ -845,9 +842,9 @@ RectLayer chop_rect_layer(Memory *memory,
             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,
@@ -875,10 +872,17 @@ RectLayer chop_rect_layer(Memory *memory,
             }
         }
 
-        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)
index f1cb7ddba930b9110d89db43d4bd29bd6d709785..682ab33e072c0e8befe617953ecee9aca3987e9d 100644 (file)
@@ -47,10 +47,8 @@ LayerPtr rect_layer_as_layer(RectLayer *layer);
 // 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)
index e5b6d428bb3c0bb4d25f96840e0cde87901545b4..1909686310d3b5de7ba8b3ea3a0c7d864163837f 100644 (file)
@@ -4,7 +4,6 @@
 #include <SDL.h>
 
 #include "system/nth_alloc.h"
-#include "system/lt.h"
 #include "system/stacktrace.h"
 #include "undo_history.h"
 #include "config.h"
@@ -59,3 +58,12 @@ void undo_history_pop(UndoHistory *undo_history)
         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);
+    }
+}
index e5af7ccbefd655566bf38133f085426640bf0a2d..061d55e9ec9da5676ececfa344f3136eadb8c099 100644 (file)
@@ -23,6 +23,8 @@ void undo_history_push(UndoHistory *undo_history,
                        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)
 {