src/game/level/level_editor/undo_history.c
src/game/level/level_editor/action_picker.h
src/game/level/level_editor/action_picker.c
- src/system/line_stream.h
- src/system/line_stream.c
src/system/log.h
src/system/log.c
src/system/lt.h
#include "src/game/level/level_editor/background_layer.c"
#include "src/game/level/level_editor/undo_history.c"
#include "src/game/level/level_editor/action_picker.c"
-#include "src/system/line_stream.c"
#include "src/system/log.c"
#include "src/system/lt_adapters.c"
#include "src/system/nth_alloc.c"
1.0f);
}
+Color hexs(String input)
+{
+ if (input.count < 6) return COLOR_BLACK;
+
+ return rgba(
+ parse_color_component(input.data) / 255.0f,
+ parse_color_component(input.data + 2) / 255.0f,
+ parse_color_component(input.data + 4) / 255.0f,
+ 1.0f);
+}
+
SDL_Color color_for_sdl(Color color)
{
const SDL_Color result = {
#include <stdio.h>
#include <SDL.h>
+#include "./system/s.h"
#define COLOR_BLACK rgba(0.0f, 0.0f, 0.0f, 1.0f)
#define COLOR_WHITE rgba(1.0f, 1.0f, 1.0f, 1.0f)
Color hsla(float h, float s, float l, float a);
Color rgba_to_hsla(Color color);
Color hexstr(const char *hexstr);
+Color hexs(String input);
SDL_Color color_for_sdl(Color color);
int color_hex_to_stream(Color color, FILE *stream);
#include "system/nth_alloc.h"
#include "dynarray.h"
-#define DYNARRAY_INIT_CAPACITY 8
-
void *dynarray_pointer_at(const Dynarray *dynarray, size_t index)
{
trace_assert(index < dynarray->count);
dynarray->count = 0;
}
-static
-int dynarray_grow(Dynarray *dynarray)
-{
- if (dynarray->count < dynarray->capacity) {
- return 0;
- }
-
- if (dynarray->capacity == 0) {
- dynarray->capacity = DYNARRAY_INIT_CAPACITY;
- } else {
- dynarray->capacity *= 2;
- }
-
- dynarray->data = nth_realloc(
- dynarray->data,
- dynarray->capacity * dynarray->element_size * 2);
-
- return 0;
-}
-
int dynarray_push(Dynarray *dynarray, const void *element)
{
trace_assert(dynarray);
trace_assert(element);
-
- if (dynarray_grow(dynarray) < 0) {
- return -1;
- }
+ trace_assert(dynarray->count < DYNARRAY_CAPACITY);
memcpy(
(char*) dynarray->data + dynarray->count * dynarray->element_size,
{
trace_assert(dynarray);
trace_assert(element);
- trace_assert(index <= dynarray->count);
-
- dynarray_grow(dynarray);
+ trace_assert(index < dynarray->count);
memmove(
(uint8_t*) dynarray->data + (index + 1) * dynarray->element_size,
int dynarray_push_empty(Dynarray *dynarray)
{
trace_assert(dynarray);
-
- if (dynarray_grow(dynarray) < 0) {
- return -1;
- }
+ trace_assert(dynarray->count < DYNARRAY_CAPACITY);
memset(
(char*) dynarray->data + dynarray->count * dynarray->element_size,
#include <stdbool.h>
#include <stdint.h>
+#define DYNARRAY_CAPACITY 256
+
typedef struct {
size_t element_size;
- size_t capacity;
size_t count;
void *data;
} Dynarray;
{
Dynarray result = {
.element_size = element_size,
- .capacity = 0,
.count = 0,
- .data = NULL
+ .data = malloc(DYNARRAY_CAPACITY * element_size)
};
return result;
}
#include "game/level/level_editor/player_layer.h"
#include "game/level/level_editor/label_layer.h"
#include "game/level/level_editor/background_layer.h"
-#include "system/line_stream.h"
#include "system/log.h"
#include "system/lt.h"
#include "system/nth_alloc.h"
#include "game/level/background.h"
#include "math/rand.h"
#include "math/rect.h"
-#include "system/line_stream.h"
#include "system/lt.h"
#include "system/nth_alloc.h"
#include "system/log.h"
#include "game/level/player.h"
#include "game/level/rigid_bodies.h"
#include "math/rand.h"
-#include "system/line_stream.h"
#include "system/log.h"
#include "system/lt.h"
#include "system/nth_alloc.h"
#include "goals.h"
#include "math/pi.h"
#include "math/triangle.h"
-#include "system/line_stream.h"
#include "system/log.h"
#include "system/lt.h"
#include "system/nth_alloc.h"
#include "game/camera.h"
#include "game/level/labels.h"
#include "game/level/level_editor/label_layer.h"
-#include "system/line_stream.h"
#include "system/log.h"
#include "system/lt.h"
#include "system/nth_alloc.h"
#include "lava.h"
#include "math/rect.h"
#include "system/lt.h"
-#include "system/line_stream.h"
#include "system/nth_alloc.h"
#include "system/log.h"
#include "game/level/level_editor/rect_layer.h"
#include <time.h>
#include "math/pi.h"
-#include "system/line_stream.h"
#include "system/log.h"
#include "system/lt.h"
#include "system/nth_alloc.h"
#include "system/str.h"
#include "config.h"
#include "math/extrema.h"
+#include "system/file.h"
#include "level_editor.h"
#define LEVEL_FOLDER_MAX_LENGTH 512
-#define LEVEL_LINE_MAX_LENGTH 512
#define LEVEL_EDITOR_EDIT_FIELD_SIZE vec(5.0f, 5.0f)
#define LEVEL_EDITOR_EDIT_FIELD_COLOR COLOR_BLACK
#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);
string_duplicate(file_name, NULL),
free);
- LineStream *level_stream = PUSH_LT(
- lt,
- create_line_stream(
- file_name,
- "r",
- LEVEL_LINE_MAX_LENGTH),
- destroy_line_stream);
- if (level_stream == NULL) {
- RETURN_LT(lt, NULL);
- }
+ Memory tmpmem = {
+ .capacity = LEVEL_EDITOR_TMPMEM_CAPACITY,
+ .buffer = malloc(LEVEL_EDITOR_TMPMEM_CAPACITY),
+ };
+ trace_assert(tmpmem.buffer);
- const char *line = line_stream_next(level_stream);
- if (line == NULL) {
- RETURN_LT(lt, NULL);
- }
+ String input = read_whole_file(&tmpmem, file_name);
+ trace_assert(input.data);
+
+ String version = trim(chop_by_delim(&input, '\n'));
- char version[METADATA_VERSION_MAX_SIZE] = {0};
- memcpy(version, line,
- MIN(size_t,
- strlen(line),
- METADATA_VERSION_MAX_SIZE - 1));
- trim_endline(version);
-
- if (strcmp(version, "1") == 0) {
- if (line_stream_next(level_stream) == NULL)
- RETURN_LT(lt, NULL);
- } else if (strcmp(version, "2") == 0) {
+ if (string_equal(version, STRING_LIT("1"))) {
+ chop_by_delim(&input, '\n');
+ } else if (string_equal(version, STRING_LIT("2"))) {
// Nothing
} else {
log_fail("Version `%s` is not supported. Expected version `%s`.\n",
- version, VERSION);
- RETURN_LT(lt, NULL);
- }
-
- if (background_layer_read_from_line_stream(
- &level_editor->background_layer,
- level_stream) < 0) {
- RETURN_LT(lt, NULL);
- }
-
- level_editor->player_layer =
- create_player_layer_from_line_stream(level_stream);
-
- level_editor->platforms_layer =
- PUSH_LT(
- lt,
- create_rect_layer_from_line_stream(level_stream, "platform", cursor),
- destroy_rect_layer);
- if (level_editor->platforms_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
-
- level_editor->goals_layer = PUSH_LT(
- lt,
- create_point_layer_from_line_stream(level_stream, "goal"),
- destroy_point_layer);
- if (level_editor->goals_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
-
- level_editor->lava_layer =
- PUSH_LT(
- lt,
- create_rect_layer_from_line_stream(level_stream, "lava", cursor),
- destroy_rect_layer);
- if (level_editor->lava_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
-
- level_editor->back_platforms_layer =
- PUSH_LT(
- lt,
- create_rect_layer_from_line_stream(level_stream, "back_platform", cursor),
- destroy_rect_layer);
- if (level_editor->back_platforms_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
-
- level_editor->boxes_layer =
- PUSH_LT(
- lt,
- create_rect_layer_from_line_stream(level_stream, "box", cursor),
- destroy_rect_layer);
- if (level_editor->boxes_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
-
- level_editor->label_layer =
- PUSH_LT(
- lt,
- create_label_layer_from_line_stream(level_stream, "label"),
- destroy_label_layer);
- if (level_editor->label_layer == NULL) {
+ string_to_cstr(&tmpmem, version),
+ VERSION);
RETURN_LT(lt, NULL);
}
- level_editor->regions_layer =
- PUSH_LT(
- lt,
- create_rect_layer_from_line_stream(level_stream, "region", cursor),
- destroy_rect_layer);
- if (level_editor->regions_layer == NULL) {
- RETURN_LT(lt, NULL);
- }
+ 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->camera_scale = 1.0f;
+ log_info("%ld bytes of tmp memory consumed during parsing the level\n", tmpmem.size);
+
+ free(tmpmem.buffer);
+
return level_editor;
}
return layer;
}
-int background_layer_read_from_line_stream(BackgroundLayer *layer,
- LineStream *line_stream)
+BackgroundLayer chop_background_layer(String *input)
{
- if (color_picker_read_from_line_stream(
- &layer->color_picker,
- line_stream) < 0) {
- return -1;
- }
-
- layer->prev_color = color_picker_rgba(&layer->color_picker);
-
- return 0;
+ String line = trim(chop_by_delim(input, '\n'));
+ return create_background_layer(hexs(line));
}
int background_layer_render(BackgroundLayer *layer,
#define BACKGROUND_LAYER_H_
#include "color_picker.h"
+#include "system/s.h"
typedef struct {
ColorPicker color_picker;
} BackgroundLayer;
BackgroundLayer create_background_layer(Color color);
-int background_layer_read_from_line_stream(BackgroundLayer *layer,
- LineStream *line_stream);
+BackgroundLayer chop_background_layer(String *input);
static inline
LayerPtr background_layer_as_layer(BackgroundLayer *layer)
#include "game/level/boxes.h"
#include "system/stacktrace.h"
-#include "system/line_stream.h"
#include "system/log.h"
#include "game/camera.h"
#include "color_picker.h"
return color_picker;
}
-int color_picker_read_from_line_stream(ColorPicker *color_picker,
- LineStream *line_stream)
-{
- char color[7];
- const char *line = line_stream_next(line_stream);
- if (line == NULL) {
- return -1;
- }
-
- if (sscanf(line, "%6s", color) == EOF) {
- log_fail("Could not read color\n");
- }
-
- *color_picker = create_color_picker_from_rgba(hexstr(color));
-
- return 0;
-}
-
int color_picker_render(const ColorPicker *color_picker,
const Camera *camera)
{
Slider sliders[COLOR_SLIDER_N];
} ColorPicker;
-typedef struct LineStream LineStream;
ColorPicker create_color_picker_from_rgba(Color color);
-int color_picker_read_from_line_stream(ColorPicker *color_picker,
- LineStream *line_stream);
-
int color_picker_render(const ColorPicker *color_picker,
const Camera *camera);
int color_picker_event(ColorPicker *color_picker,
#include <SDL.h>
-#include "system/line_stream.h"
#include "system/stacktrace.h"
#include "system/nth_alloc.h"
#include "system/lt.h"
return label_layer;
}
-LabelLayer *create_label_layer_from_line_stream(LineStream *line_stream, const char *id_name_prefix)
+LabelLayer *chop_label_layer(Memory *memory,
+ String *input,
+ const char *id_name_prefix)
{
- trace_assert(line_stream);
- LabelLayer *label_layer = create_label_layer(id_name_prefix);
+ trace_assert(memory);
+ trace_assert(input);
+ trace_assert(id_name_prefix);
- if (label_layer == NULL) {
- RETURN_LT(label_layer->lt, NULL);
- }
-
- const char *line = line_stream_next(line_stream);
- if (line == NULL) {
- log_fail("Could not read amount of labels\n");
- RETURN_LT(label_layer->lt, NULL);
- }
+ LabelLayer *label_layer = create_label_layer(id_name_prefix);
- size_t n = 0;
- if (sscanf(line, "%zu", &n) == EOF) {
- log_fail("Could not parse amount of labels\n");
- RETURN_LT(label_layer->lt, NULL);
- }
+ int n = atoi(string_to_cstr(memory, trim(chop_by_delim(input, '\n'))));
+ char id[LABEL_LAYER_ID_MAX_SIZE];
+ char label_text[LABEL_LAYER_TEXT_MAX_SIZE];
+ for (int i = 0; i < n; ++i) {
+ String meta = trim(chop_by_delim(input, '\n'));
- for (size_t i = 0; i < n; ++i) {
- char hex[7];
- char id[LABEL_LAYER_ID_MAX_SIZE];
+ String string_id = trim(chop_word(&meta));
Vec2f position;
-
- line = line_stream_next(line_stream);
- if (line == NULL) {
- log_fail("Could not read label meta info\n");
- RETURN_LT(label_layer->lt, NULL);
- }
-
- if (sscanf(
- line,
- "%"STRINGIFY(LABEL_LAYER_ID_MAX_SIZE)"s%f%f%6s\n",
- id, &position.x, &position.y, hex) == EOF) {
- log_fail("Could not parse label meta info\n");
- RETURN_LT(label_layer->lt, NULL);
- }
-
- Color color = hexstr(hex);
+ position.x = strtof(string_to_cstr(memory, trim(chop_word(&meta))), NULL);
+ position.y = strtof(string_to_cstr(memory, trim(chop_word(&meta))), NULL);
+ Color color = hexs(trim(chop_word(&meta)));
+
+ memset(id, 0, LABEL_LAYER_ID_MAX_SIZE);
+ memcpy(
+ id,
+ string_id.data,
+ min_size_t(LABEL_LAYER_ID_MAX_SIZE - 1, string_id.count));
+
+ String label_text_string =
+ trim(chop_by_delim(input, '\n'));
+ memset(label_text, 0, LABEL_LAYER_TEXT_MAX_SIZE);
+ memcpy(
+ label_text,
+ label_text_string.data,
+ min_size_t(LABEL_LAYER_TEXT_MAX_SIZE - 1,
+ label_text_string.count));
dynarray_push(&label_layer->ids, id);
dynarray_push(&label_layer->positions, &position);
dynarray_push(&label_layer->colors, &color);
-
- line = line_stream_next(line_stream);
- if (line == NULL) {
- log_fail("Could not read label text\n");
- }
-
- char label_text[LABEL_LAYER_TEXT_MAX_SIZE] = {0};
- memcpy(label_text, line, LABEL_LAYER_TEXT_MAX_SIZE - 1);
- trim_endline(label_text);
- dynarray_push(&label_layer->texts, &label_text);
+ dynarray_push(&label_layer->texts, label_text);
}
return label_layer;
#define LABEL_LAYER_TEXT_MAX_SIZE 256
typedef struct LabelLayer LabelLayer;
-typedef struct LineStream LineStream;
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 *create_label_layer_from_line_stream(LineStream *line_stream,
- 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);
int label_layer_render(const LabelLayer *label_layer,
#include "system/nth_alloc.h"
#include "system/log.h"
#include "undo_history.h"
+#include "system/memory.h"
typedef struct {
PlayerLayer *layer;
};
}
-PlayerLayer create_player_layer_from_line_stream(LineStream *line_stream)
+PlayerLayer chop_player_layer(Memory *memory, String *input)
{
- trace_assert(line_stream);
+ trace_assert(memory);
+ trace_assert(input);
- const char *line = line_stream_next(line_stream);
- trace_assert(line);
+ String line = chop_by_delim(input, '\n');
+ float x = strtof(string_to_cstr(memory, chop_word(&line)), NULL);
+ float y = strtof(string_to_cstr(memory, chop_word(&line)), NULL);
+ Color color = hexs(chop_word(&line));
- char colorstr[7] = "000000";
- Vec2f position = vec(0.0f, 0.0f);
-
- const int bound =
- sscanf(line, "%f%f%6s", &position.x, &position.y, colorstr);
-
-#define BOUND_EXPECTED 3
- if (bound != BOUND_EXPECTED) {
- log_fail("Could not read Player Layer properly. Parsed tokens: %d. Expected: %d\n",
- bound, BOUND_EXPECTED);
- }
-#undef BOUND_EXPECTED
-
- return create_player_layer(position, hexstr(colorstr));
+ return create_player_layer(vec(x, y), color);
}
LayerPtr player_layer_as_layer(PlayerLayer *player_layer)
#include "color_picker.h"
#include "layer.h"
#include "system/lt.h"
-#include "system/line_stream.h"
+#include "system/memory.h"
+#include "system/s.h"
typedef struct {
Vec2f position;
} PlayerLayer;
PlayerLayer create_player_layer(Vec2f position, Color color);
-PlayerLayer create_player_layer_from_line_stream(LineStream *line_stream);
+PlayerLayer chop_player_layer(Memory *memory, String *input);
LayerPtr player_layer_as_layer(PlayerLayer *player_layer);
int player_layer_render(const PlayerLayer *player_layer,
#include "dynarray.h"
#include "game/camera.h"
-#include "system/line_stream.h"
#include "system/log.h"
#include "system/lt.h"
#include "system/nth_alloc.h"
return point_layer;
}
-PointLayer *create_point_layer_from_line_stream(LineStream *line_stream,
- const char *id_name_prefix)
+PointLayer *chop_point_layer(Memory *memory,
+ String *input,
+ const char *id_name_prefix)
{
- trace_assert(line_stream);
+ trace_assert(memory);
+ trace_assert(input);
+ trace_assert(id_name_prefix);
PointLayer *point_layer = create_point_layer(id_name_prefix);
- size_t count = 0;
- if (sscanf(
- line_stream_next(line_stream),
- "%zu",
- &count) == EOF) {
- log_fail("Could not read amount of points");
- RETURN_LT(point_layer->lt, NULL);
- }
-
- char color_name[7];
- char id[ID_MAX_SIZE];
- float x, y;
- for (size_t i = 0; i < count; ++i) {
- if (sscanf(
- line_stream_next(line_stream),
- "%"STRINGIFY(ID_MAX_SIZE)"s%f%f%6s",
- id, &x, &y, color_name) < 0) {
- log_fail("Could not read %dth goal\n", i);
- RETURN_LT(point_layer->lt, NULL);
- }
- const Color color = hexstr(color_name);
- const Vec2f point = vec(x, y);
+ int n = atoi(string_to_cstr(memory, trim(chop_by_delim(input, '\n'))));
+ char id[ENTITY_MAX_ID_SIZE];
+ for (int i = 0; i < n; ++i) {
+ String line = trim(chop_by_delim(input, '\n'));
+ String string_id = trim(chop_word(&line));
+ Vec2f point;
+ point.x = strtof(string_to_cstr(memory, trim(chop_word(&line))), NULL);
+ point.y = strtof(string_to_cstr(memory, trim(chop_word(&line))), NULL);
+ 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));
- dynarray_push(&point_layer->colors, &color);
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;
#define ID_MAX_SIZE 36
typedef struct PointLayer PointLayer;
-typedef struct LineStream LineStream;
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 *create_point_layer_from_line_stream(LineStream *line_stream,
- 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);
int point_layer_render(const PointLayer *point_layer,
#include "color.h"
#include "rect_layer.h"
#include "dynarray.h"
-#include "system/line_stream.h"
#include "color_picker.h"
#include "system/str.h"
#include "ui/edit_field.h"
#include "game/level/action.h"
#include "action_picker.h"
#include "game.h"
+#include "math/extrema.h"
#define RECT_LAYER_SELECTION_THICCNESS 15.0f
#define RECT_LAYER_ID_LABEL_SIZE vec(3.0f, 3.0f)
return layer;
}
-RectLayer *create_rect_layer_from_line_stream(LineStream *line_stream,
- const char *id_name_prefix,
- Cursor *cursor)
+RectLayer *chop_rect_layer(Memory *memory,
+ String *input,
+ const char *id_name_prefix,
+ Cursor *cursor)
{
- trace_assert(line_stream);
+ trace_assert(memory);
+ trace_assert(input);
RectLayer *layer = create_rect_layer(id_name_prefix, cursor);
- if (layer == NULL) {
- return NULL;
- }
-
- const char *line = line_stream_next(line_stream);
- if (line == NULL) {
- RETURN_LT(layer->lt, NULL);
- }
-
- size_t count = 0;
- if (sscanf(line, "%zu", &count) < 0) {
- RETURN_LT(layer->lt, NULL);
- }
-
- for (size_t i = 0; i < count; ++i) {
- line = line_stream_next(line_stream);
- if (line == NULL) {
- RETURN_LT(layer->lt, NULL);
- }
+ trace_assert(layer);
- char hex[7];
+ int n = atoi(string_to_cstr(memory, trim(chop_by_delim(input, '\n'))));
+ char id[ENTITY_MAX_ID_SIZE];
+ for (int i = 0; i < n; ++i) {
Rect rect;
- char id[ENTITY_MAX_ID_SIZE];
-
- int n = 0;
- if (sscanf(line,
- "%"STRINGIFY(ENTITY_MAX_ID_SIZE)"s%f%f%f%f%6s%n",
- id,
- &rect.x, &rect.y,
- &rect.w, &rect.h,
- hex, &n) <= 0) {
- log_fail("%s\n", strerror(errno));
- RETURN_LT(layer->lt, NULL);
- }
- line += n;
+ String line = trim(chop_by_delim(input, '\n'));
+ String string_id = trim(chop_word(&line));
+ rect.x = strtof(string_to_cstr(memory, trim(chop_word(&line))), NULL);
+ rect.y = strtof(string_to_cstr(memory, trim(chop_word(&line))), NULL);
+ rect.w = strtof(string_to_cstr(memory, trim(chop_word(&line))), NULL);
+ rect.h = strtof(string_to_cstr(memory, trim(chop_word(&line))), NULL);
+ 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));
- Color color = hexstr(hex);
dynarray_push(&layer->rects, &rect);
- dynarray_push(&layer->ids, id);
dynarray_push(&layer->colors, &color);
+ dynarray_push(&layer->ids, id);
Action action = {
.type = ACTION_NONE,
.entity_id = {0}
};
- if (sscanf(line, "%d%n", (int*)&action.type, &n) > 0) {
- line += n;
+ String action_string = trim(chop_word(&line));
+ if (action_string.count > 0) {
+ action.type = (ActionType)atol(string_to_cstr(memory, action_string));
switch (action.type) {
case ACTION_NONE: break;
-
case ACTION_TOGGLE_GOAL:
case ACTION_HIDE_LABEL: {
- if (sscanf(line, "%"STRINGIFY(ENTITY_MAX_ID_SIZE)"s", action.entity_id) <= 0) {
- log_fail("%s\n", strerror(errno));
- RETURN_LT(layer->lt, NULL);
- }
+ String label_id = trim(chop_word(&line));
+ trace_assert(label_id.count > 0);
+ memset(action.entity_id, 0, ENTITY_MAX_ID_SIZE);
+ memcpy(action.entity_id,
+ label_id.data,
+ min_size_t(
+ ENTITY_MAX_ID_SIZE - 1,
+ label_id.count));
} break;
case ACTION_N: break;
#include "ui/cursor.h"
typedef struct RectLayer RectLayer;
-typedef struct LineStream LineStream;
LayerPtr rect_layer_as_layer(RectLayer *layer);
// NOTE: create_rect_layer and create_rect_layer_from_line_stream does
// not own id_name_prefix
RectLayer *create_rect_layer(const char *id_name_prefix,
Cursor *cursor);
-RectLayer *create_rect_layer_from_line_stream(
- LineStream *line_stream,
- const char *id_name_prefix,
- Cursor *cursor);
+RectLayer *chop_rect_layer(Memory *memory,
+ String *input,
+ const char *id_name_prefix,
+ Cursor *cursor);
void destroy_rect_layer(RectLayer *layer);
int rect_layer_render(const RectLayer *layer, const Camera *camera, int active);
#include "platforms.h"
#include "system/lt.h"
-#include "system/line_stream.h"
#include "system/nth_alloc.h"
#include "system/log.h"
#include "game/level/level_editor/rect_layer.h"
#include "math/vec.h"
#include "platforms.h"
#include "player.h"
-#include "system/line_stream.h"
#include "system/log.h"
#include "system/lt.h"
#include "system/nth_alloc.h"
#include "player.h"
#include "regions.h"
#include "system/str.h"
-#include "system/line_stream.h"
#include "system/log.h"
#include "system/lt.h"
#include "system/nth_alloc.h"
#include "system/lt.h"
#include "system/nth_alloc.h"
#include "system/stacktrace.h"
-#include "system/line_stream.h"
#include "system/str.h"
#include "system/log.h"
return -1;
}
- snprintf(text_buffer, 256,
+ snprintf(text_buffer, 256,
"id: %zd\n"
"p:(%.2f, %.2f)\n"
"v:(%.2f, %.2f)\n"
#endif
-String read_whole_file(const char *filepath)
+String read_whole_file(Memory *memory, const char *filepath)
{
trace_assert(filepath);
if (fseek(f, 0, SEEK_END) < 0) goto end;
long m = ftell(f);
if (m < 0) goto end;
+ if (fseek(f, 0, SEEK_SET) < 0) goto end;
result.count = (size_t) m;
- char *buffer = nth_calloc(1, result.count);
+ char *buffer = memory_alloc(memory, result.count);
size_t n = fread(buffer, 1, result.count, f);
trace_assert(n == result.count);
result.data = buffer;
void closedir(DIR *dirp);
#endif
-String read_whole_file(const char *filepath);
+String read_whole_file(Memory *memory, const char *filepath);
#endif // FILE_H_
+++ /dev/null
-#include "system/stacktrace.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <stdbool.h>
-
-#include "line_stream.h"
-#include "lt.h"
-#include "lt_adapters.h"
-#include "system/nth_alloc.h"
-#include "system/log.h"
-#include "system/str.h"
-
-struct LineStream
-{
- Lt *lt;
- FILE *stream;
- char *buffer;
- size_t capacity;
- bool unfinished;
-};
-
-// TODO(#905): create_line_stream probably does not need mode
-// Because LineStream interface doesn't even have anything
-// for writing to files. So we can just hardcode the mode
-// inside of the ctor.
-LineStream *create_line_stream(const char *filename,
- const char *mode,
- size_t capacity)
-{
- trace_assert(filename);
- trace_assert(mode);
-
- Lt *lt = create_lt();
-
- LineStream *line_stream = PUSH_LT(
- lt,
- nth_calloc(1, sizeof(LineStream)),
- free);
- if (line_stream == NULL) {
- RETURN_LT(lt, NULL);
- }
- line_stream->lt = lt;
-
- line_stream->stream = PUSH_LT(
- lt,
- fopen(filename, mode),
- fclose_lt);
- if (line_stream->stream == NULL) {
- log_fail("Could not open file '%s': %s\n", filename, strerror(errno));
- RETURN_LT(lt, NULL);
- }
-
- line_stream->buffer = PUSH_LT(
- lt,
- nth_calloc(1, sizeof(char) * capacity),
- free);
- if (line_stream->buffer == NULL) {
- RETURN_LT(lt, NULL);
- }
-
- line_stream->capacity = capacity;
- line_stream->unfinished = false;
-
- return line_stream;
-}
-
-void destroy_line_stream(LineStream *line_stream)
-{
- trace_assert(line_stream);
-
- RETURN_LT0(line_stream->lt);
-}
-
-
-const char *line_stream_next_chunk(LineStream *line_stream)
-{
- trace_assert(line_stream);
-
- const char *s = fgets(line_stream->buffer,
- (int) line_stream->capacity,
- line_stream->stream);
- if (s == NULL) {
- return NULL;
- }
- size_t n = strlen(s);
- line_stream->unfinished = s[n - 1] != '\n';
-
- return s;
-}
-
-const char *line_stream_next(LineStream *line_stream)
-{
- trace_assert(line_stream);
-
- while (line_stream->unfinished) {
- line_stream_next_chunk(line_stream);
- }
-
- return line_stream_next_chunk(line_stream);
-}
-
-char *line_stream_collect_n_lines(LineStream *line_stream, size_t n)
-{
- char *result = string_append(NULL, "");
- for (size_t i = 0; i < n; ++i) {
- const char *line = line_stream_next(line_stream);
- if (line == NULL) {
- free(result);
- return NULL;
- }
-
- result = string_append(result, line);
- }
-
- return result;
-}
-
-char *line_stream_collect_until_end(LineStream *line_stream)
-{
- char *result = string_append(NULL, "");
- const char *line = line_stream_next(line_stream);
-
- /* TODO(#906): line_stream_collect_until_end does not distinguish between EOF and error during reading */
- while (line != NULL) {
- result = string_append(result, line);
- line = line_stream_next(line_stream);
- }
-
- return result;
-}
+++ /dev/null
-#ifndef LINE_STREAM_H_
-#define LINE_STREAM_H_
-
-#include <stdlib.h>
-
-typedef struct LineStream LineStream;
-
-LineStream *create_line_stream(const char *filename,
- const char *mode,
- size_t capacity);
-void destroy_line_stream(LineStream *line_stream);
-
-const char *line_stream_next_chunk(LineStream *line_stream);
-const char *line_stream_next(LineStream *line_stream);
-char *line_stream_collect_n_lines(LineStream *line_stream, size_t n);
-char *line_stream_collect_until_end(LineStream *line_stream);
-
-#endif // LINE_STREAM_H_
--- /dev/null
+#ifndef MEMORY_H_
+#define MEMORY_H_
+
+#include <assert.h>
+#include <stdint.h>
+
+#define KILO 1024L
+#define MEGA (1024L * KILO)
+#define GIGA (1024L * MEGA)
+
+typedef struct {
+ size_t capacity;
+ size_t size;
+ uint8_t *buffer;
+} Memory;
+
+static inline
+void *memory_alloc(Memory *memory, size_t size)
+{
+ assert(memory);
+ assert(memory->size + size <= memory->capacity);
+
+
+ void *result = memory->buffer + memory->size;
+ memory->size += size;
+
+ return result;
+}
+
+static inline
+void memory_clean(Memory *memory)
+{
+ assert(memory);
+ memory->size = 0;
+}
+
+#endif // MEMORY_H_
#ifndef S_H_
#define S_H_
+#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include "system/stacktrace.h"
+#include "system/memory.h"
typedef struct {
size_t count;
return memcmp(a.data, b.data, a.count) == 0;
}
+static inline
+String trim_begin(String input)
+{
+ while (input.count > 0 && isspace(*input.data)) {
+ input.data += 1;
+ input.count -= 1;
+ }
+
+ return input;
+}
+
+static inline
+String trim_end(String input)
+{
+ while (input.count > 0 && isspace(*(input.data + input.count - 1))) {
+ input.count -= 1;
+ }
+
+ return input;
+}
+
+static inline
+String trim(String input)
+{
+ return trim_end(trim_begin(input));
+}
+
+static inline
+String chop_word(String *input)
+{
+ trace_assert(input);
+
+ *input = trim_begin(*input);
+
+ size_t i = 0;
+ while (i < input->count && !isspace(input->data[i]))
+ i++;
+
+ String result = string(i, input->data);
+ input->data += i;
+ input->count -= i;
+ return result;
+}
+
+static inline
+char *string_to_cstr(Memory *memory, String s)
+{
+ trace_assert(memory);
+
+ char *result = memory_alloc(memory, s.count + 1);
+ memset(result, 0, s.count + 1);
+ memcpy(result, s.data, s.count);
+ return result;
+}
+
#endif // S_H_
return s;
}
-
-char *string_append(char *prefix, const char *suffix)
-{
- trace_assert(suffix);
-
- if (prefix == NULL) {
- return string_duplicate(suffix, NULL);
- }
-
- prefix = nth_realloc(prefix, strlen(prefix) + strlen(suffix) + 1);
- return strcat(prefix, suffix);
-}
char *string_duplicate(const char *str,
const char *str_end);
-char *string_append(char *prefix,
- const char *suffix);
char *trim_endline(char *s);
#endif // STR_H_
#define CONSOLE_FOREGROUND (rgba(0.80f, 0.80f, 0.80f, CONSOLE_ALPHA))
#define CONSOLE_ERROR (rgba(0.80f, 0.50f, 0.50f, CONSOLE_ALPHA))
-typedef struct {
- const char *begin;
- const char *end;
-} Token;
-
-
-static inline
-Token token(const char *begin, const char *end)
-{
- Token t = {begin, end};
- return t;
-}
-
-static inline
-int token_equals_str(Token t, const char *s)
-{
- trace_assert(t.begin <= t.end);
- size_t n1 = (size_t) (t.end - t.begin);
- size_t n2 = strlen(s);
- if (n1 != n2) return 0;
- return memcmp(t.begin, s, n1) == 0;
-}
-
-static inline
-Token token_nt(const char *s)
-{
- return token(s, s + strlen(s));
-}
-
-static inline
-void ltrim(Token *t)
-{
- while (t->begin < t->end && isspace(*t->begin)) {
- t->begin++;
- }
-}
-
-static inline
-Token chop_word(Token *t)
-{
- ltrim(t);
- const char *end = t->begin;
- while (end < t->end && !isspace(*end)) {
- end++;
- }
- Token result = token(t->begin, end);
- t->begin = end;
- return result;
-}
-
struct Console
{
Lt *lt;
{
const char *input_text = edit_field_as_text(console->edit_field);
- Token input = token_nt(input_text);
- Token command = chop_word(&input);
+ String input = string_nt(input_text);
+ String command = chop_word(&input);
- if (token_equals_str(command, "")) {
+ if (string_equal(command, STRING_LIT(""))) {
edit_field_clean(console->edit_field);
return 0;
}
return -1;
}
- if (token_equals_str(command, "load")) {
- Token level = chop_word(&input);
+ if (string_equal(command, STRING_LIT("load"))) {
+ String level = chop_word(&input);
console_log_push_line(console->console_log, "Loading level:", NULL, CONSOLE_FOREGROUND);
- console_log_push_line(console->console_log, level.begin, level.end, CONSOLE_FOREGROUND);
+ console_log_push_line(console->console_log, level.data, level.data + level.count, CONSOLE_FOREGROUND);
char level_name[256];
memset(level_name, 0, 256);
- memcpy(level_name, level.begin, min_size_t((size_t)(level.end - level.begin), 255));
+ memcpy(level_name, level.data, min_size_t(level.count, 255));
if (game_load_level(console->game, level_name) < 0) {
console_log_push_line(console->console_log, "Could not load level", NULL, CONSOLE_ERROR);
}
- } else if (token_equals_str(command, "menu")) {
+ } else if (string_equal(command, STRING_LIT("menu"))) {
console_log_push_line(console->console_log, "Loading menu", NULL, CONSOLE_FOREGROUND);
game_switch_state(console->game, GAME_STATE_LEVEL_PICKER);
} else {