commit
6005cbae37
|
@ -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_
|
||||
|
|
|
@ -35,4 +35,6 @@
|
|||
|
||||
#define EDIT_FIELD_CAPACITY 256
|
||||
|
||||
#define TMPMEM_CAPACITY (640 * KILO)
|
||||
|
||||
#endif // CONFIG_H_
|
||||
|
|
79
src/game.c
79
src/game.c
|
@ -19,15 +19,15 @@
|
|||
#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) {
|
||||
|
|
|
@ -11,43 +11,17 @@
|
|||
|
||||
#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)
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
@ -29,65 +27,37 @@
|
|||
#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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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"
|
||||
|
@ -21,35 +20,10 @@
|
|||
|
||||
// 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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "color_picker.h"
|
||||
#include "layer.h"
|
||||
#include "system/lt.h"
|
||||
#include "system/memory.h"
|
||||
#include "system/s.h"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue