From c57a799e27f8811047caf2e8d519ab0db17b88bb Mon Sep 17 00:00:00 2001 From: rexim Date: Mon, 25 Nov 2019 00:56:44 +0700 Subject: [PATCH 01/10] (#1139) Get rid of the libsystem --- CMakeLists.txt | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3e9a67ad..055274ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,28 +50,6 @@ include_directories(src/) include_directories(${SDL2_INCLUDE_DIRS}) -add_library(system STATIC - src/system/line_stream.h - src/system/line_stream.c - src/system/log.h - src/system/log.c - src/system/lt.h - src/system/lt_adapters.h - src/system/lt_adapters.c - src/system/nth_alloc.h - src/system/nth_alloc.c - src/system/stacktrace.h - src/system/stacktrace.c - src/system/str.h - src/system/str.c - src/dynarray.h - src/dynarray.c - src/hashset.h - src/hashset.c - src/system/file.h - src/system/file.c - ) - add_executable(nothing src/color.h src/color.c @@ -173,8 +151,27 @@ add_executable(nothing 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 + src/system/lt_adapters.h + src/system/lt_adapters.c + src/system/nth_alloc.h + src/system/nth_alloc.c + src/system/stacktrace.h + src/system/stacktrace.c + src/system/str.h + src/system/str.c + src/dynarray.h + src/dynarray.c + src/hashset.h + src/hashset.c + src/system/file.h + src/system/file.c ) -target_link_libraries(nothing ${SDL2_LIBRARIES} system) +target_link_libraries(nothing ${SDL2_LIBRARIES}) ADD_CUSTOM_TARGET(link_assets ALL COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_CURRENT_SOURCE_DIR}/assets ${CMAKE_BINARY_DIR}/assets) From f5aa86697539880a05d64a789fd34a7dba1d1801 Mon Sep 17 00:00:00 2001 From: rexim Date: Mon, 25 Nov 2019 01:09:14 +0700 Subject: [PATCH 02/10] (#1139) Move rect snapping stuff to rect translation unit --- src/game/level/level_editor/rect_layer.c | 37 ----------------------- src/game/level/platforms.c | 1 + src/math/rect.h | 38 ++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/game/level/level_editor/rect_layer.c b/src/game/level/level_editor/rect_layer.c index 9a940257..e9d67558 100644 --- a/src/game/level/level_editor/rect_layer.c +++ b/src/game/level/level_editor/rect_layer.c @@ -535,43 +535,6 @@ static int rect_layer_event_create(RectLayer *layer, return 0; } -static inline -int segment_overlap(Vec2f a, Vec2f b) -{ - trace_assert(a.x <= a.y); - trace_assert(b.x <= b.y); - return a.y >= b.x && b.y >= a.x; -} - -static -void snap_var(float *x, // the value we are snapping - float y, // the target we are snapping x to - float xo, // x offset - float yo, // y offset - float st) // snap threshold -{ - if (fabsf((*x + xo) - (y + yo)) < st) - *x = y + yo - xo; -} - -static -void snap_var2seg(float *x, float y, - float xo, float yo, - float st) -{ - snap_var(x, y, xo, 0, st); - snap_var(x, y, xo, yo, st); -} - -static -void snap_seg2seg(float *x, float y, float xo, float yo, float st) -{ - snap_var(x, y, 0, 0, st); - snap_var(x, y, 0, yo, st); - snap_var(x, y, xo, 0, st); - snap_var(x, y, xo, yo, st); -} - static int rect_layer_event_resize(RectLayer *layer, const SDL_Event *event, const Camera *camera, diff --git a/src/game/level/platforms.c b/src/game/level/platforms.c index aacb51b7..f4ab91b7 100644 --- a/src/game/level/platforms.c +++ b/src/game/level/platforms.c @@ -94,6 +94,7 @@ Vec2f platforms_snap_rect(const Platforms *platforms, Vec2f result = vec(1.0f, 1.0f); for (size_t i = 0; i < platforms->rects_size; ++i) { if (rects_overlap(platforms->rects[i], *object)) { + // TODO: can we reuse the Level Editor snapping mechanism in physics snapping result = vec_entry_mult(result, rect_snap(platforms->rects[i], object)); } } diff --git a/src/math/rect.h b/src/math/rect.h index 12f919ac..79902147 100644 --- a/src/math/rect.h +++ b/src/math/rect.h @@ -115,4 +115,42 @@ float rect_side_distance(Rect rect, Vec2f point, Rect_side side) return 0; } +static inline +int segment_overlap(Vec2f a, Vec2f b) +{ + trace_assert(a.x <= a.y); + trace_assert(b.x <= b.y); + return a.y >= b.x && b.y >= a.x; +} + +static inline +void snap_var(float *x, // the value we are snapping + float y, // the target we are snapping x to + float xo, // x offset + float yo, // y offset + float st) // snap threshold +{ + if (fabsf((*x + xo) - (y + yo)) < st) + *x = y + yo - xo; +} + +static inline +void snap_var2seg(float *x, float y, + float xo, float yo, + float st) +{ + snap_var(x, y, xo, 0, st); + snap_var(x, y, xo, yo, st); +} + +static inline +void snap_seg2seg(float *x, float y, float xo, float yo, float st) +{ + snap_var(x, y, 0, 0, st); + snap_var(x, y, 0, yo, st); + snap_var(x, y, xo, 0, st); + snap_var(x, y, xo, yo, st); +} + + #endif // RECT_H_ From e62149607d167030155cb4da22853df2c9be4548 Mon Sep 17 00:00:00 2001 From: rexim Date: Mon, 25 Nov 2019 01:31:49 +0700 Subject: [PATCH 03/10] (#1139) Implement Centralized Boundary Calculation (CBC) --- src/game/level/level_editor/label_layer.c | 70 +++++++++++++---------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/src/game/level/level_editor/label_layer.c b/src/game/level/level_editor/label_layer.c index 31fa377b..5751b653 100644 --- a/src/game/level/level_editor/label_layer.c +++ b/src/game/level/level_editor/label_layer.c @@ -286,6 +286,32 @@ void destroy_label_layer(LabelLayer *label_layer) destroy_lt(label_layer->lt); } +static inline +Rect boundary_of_element(const LabelLayer *label_layer, + const Sprite_font *font, + size_t i, + Vec2f position) +{ + trace_assert(i < dynarray_count(label_layer->texts)); + + char *ids = dynarray_data(label_layer->ids); + char *texts = dynarray_data(label_layer->texts); + + return rect_boundary2( + sprite_font_boundary_box( + font, + position, + LABELS_SIZE, + texts + i * LABEL_LAYER_TEXT_MAX_SIZE), + sprite_font_boundary_box( + font, + vec_sub( + position, + vec(0.0f, FONT_CHAR_HEIGHT)), + vec(1.0f, 1.0f), + ids + i * LABEL_LAYER_ID_MAX_SIZE)); +} + int label_layer_render(const LabelLayer *label_layer, const Camera *camera, int active) @@ -364,19 +390,11 @@ int label_layer_render(const LabelLayer *label_layer, rect_pad( camera_rect( camera, - rect_boundary2( - sprite_font_boundary_box( - camera_font(camera), - position, - LABELS_SIZE, - texts + label_layer->selection * LABEL_LAYER_TEXT_MAX_SIZE), - sprite_font_boundary_box( - camera_font(camera), - vec_sub( - position, - vec(0.0f, FONT_CHAR_HEIGHT)), - vec(1.0f, 1.0f), - ids + label_layer->selection * LABEL_LAYER_ID_MAX_SIZE))), + boundary_of_element( + label_layer, + camera->font, + i, + position)), LABEL_LAYER_SELECTION_THICCNESS * 0.5f); @@ -401,27 +419,17 @@ int label_layer_element_at(LabelLayer *label_layer, { trace_assert(label_layer); - const int n = (int) dynarray_count(label_layer->texts); - char *ids = dynarray_data(label_layer->ids); - char *texts = dynarray_data(label_layer->texts); Vec2f *positions = dynarray_data(label_layer->positions); + const int n = (int) dynarray_count(label_layer->texts); for (int i = n - 1; i >= 0; --i) { - Rect boundary = rect_boundary2( - sprite_font_boundary_box( - font, - positions[i], - LABELS_SIZE, - texts + i * LABEL_LAYER_TEXT_MAX_SIZE), - sprite_font_boundary_box( - font, - vec_sub( - positions[i], - vec(0.0f, FONT_CHAR_HEIGHT)), - vec(1.0f, 1.0f), - ids + i * LABEL_LAYER_ID_MAX_SIZE)); - - if (rect_contains_point(boundary, position)) { + if (rect_contains_point( + boundary_of_element( + label_layer, + font, + (size_t) i, + positions[i]), + position)) { return i; } } From 14a80ed176781fd0b02e95287441cb1956770fc9 Mon Sep 17 00:00:00 2001 From: rexim Date: Mon, 25 Nov 2019 02:09:24 +0700 Subject: [PATCH 04/10] (#1139) Decouple sprite_font_boundary_box from Sprite_font --- src/game.c | 4 ++-- src/game/camera.c | 18 +----------------- src/game/camera.h | 5 ----- src/game/credits.c | 2 +- src/game/level/level_editor.c | 4 +--- src/game/level/level_editor/label_layer.c | 11 ++--------- src/game/level_picker.c | 7 +++---- src/game/level_picker.h | 3 +-- src/game/sprite_font.c | 13 ------------- src/game/sprite_font.h | 12 ++++++++---- src/ui/list_selector.c | 9 +++------ src/ui/wiggly_text.c | 7 +++---- src/ui/wiggly_text.h | 7 +++---- 13 files changed, 28 insertions(+), 74 deletions(-) diff --git a/src/game.c b/src/game.c index 0924a244..818af559 100644 --- a/src/game.c +++ b/src/game.c @@ -382,7 +382,7 @@ static int game_event_level_picker(Game *game, const SDL_Event *event) } break; } - return level_picker_event(game->level_picker, event, &game->camera); + return level_picker_event(game->level_picker, event); } static int game_event_level_editor(Game *game, const SDL_Event *event) @@ -511,7 +511,7 @@ int game_event(Game *game, const SDL_Event *event) // TODO(#1145): get rid of keyboard_state and introduce *_joystick methods // -// keyboard_state is a global var and can be check anywhere anyway +// keyboard_state is a global var and can be check anywhere anyway int game_input(Game *game, const Uint8 *const keyboard_state, SDL_Joystick *the_stick_of_joy) diff --git a/src/game/camera.c b/src/game/camera.c index a044ea31..59c71610 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -304,11 +304,7 @@ int camera_is_text_visible(const Camera *camera, return rects_overlap( camera_rect( camera, - sprite_font_boundary_box( - camera->font, - position, - size, - text)), + sprite_font_boundary_box(position, size, strlen(text))), rect_from_sdl(&view_port)); } @@ -519,18 +515,6 @@ const Sprite_font *camera_font(const Camera *camera) return camera->font; } -Rect camera_text_boundary_box(const Camera *camera, - Vec2f position, - Vec2f scale, - const char *text) -{ - trace_assert(camera); - trace_assert(text); - - return sprite_font_boundary_box( - camera->font, position, scale, text); -} - int camera_draw_line(const Camera *camera, Vec2f begin, Vec2f end, Color color) diff --git a/src/game/camera.h b/src/game/camera.h index abc7532d..71943de9 100644 --- a/src/game/camera.h +++ b/src/game/camera.h @@ -65,11 +65,6 @@ int camera_render_text_screen(const Camera *camera, Color color, Vec2f position); -Rect camera_text_boundary_box(const Camera *camera, - Vec2f position, - Vec2f scale, - const char *text); - int camera_render_debug_text(const Camera *camera, const char *text, Vec2f position); diff --git a/src/game/credits.c b/src/game/credits.c index 1203c0aa..8d657c63 100644 --- a/src/game/credits.c +++ b/src/game/credits.c @@ -61,7 +61,7 @@ int credits_render(const Credits *credits, const Camera *camera) return -1; } - const Vec2f title_size = wiggly_text_size(&credits->wiggly_text, camera); + const Vec2f title_size = wiggly_text_size(&credits->wiggly_text); if (wiggly_text_render( &credits->wiggly_text, diff --git a/src/game/level/level_editor.c b/src/game/level/level_editor.c index 855078ca..d0a99a9c 100644 --- a/src/game/level/level_editor.c +++ b/src/game/level/level_editor.c @@ -365,9 +365,7 @@ int level_editor_render(const LevelEditor *level_editor, } const Rect screen_viewport = camera_view_port_screen(camera); - const Vec2f text_size = fading_wiggly_text_size( - &level_editor->notice, - camera); + const Vec2f text_size = fading_wiggly_text_size(&level_editor->notice); fading_wiggly_text_render( &level_editor->notice, camera, diff --git a/src/game/level/level_editor/label_layer.c b/src/game/level/level_editor/label_layer.c index 5751b653..1fb11f13 100644 --- a/src/game/level/level_editor/label_layer.c +++ b/src/game/level/level_editor/label_layer.c @@ -288,7 +288,6 @@ void destroy_label_layer(LabelLayer *label_layer) static inline Rect boundary_of_element(const LabelLayer *label_layer, - const Sprite_font *font, size_t i, Vec2f position) { @@ -299,17 +298,15 @@ Rect boundary_of_element(const LabelLayer *label_layer, return rect_boundary2( sprite_font_boundary_box( - font, position, LABELS_SIZE, - texts + i * LABEL_LAYER_TEXT_MAX_SIZE), + strlen(texts + i * LABEL_LAYER_TEXT_MAX_SIZE)), sprite_font_boundary_box( - font, vec_sub( position, vec(0.0f, FONT_CHAR_HEIGHT)), vec(1.0f, 1.0f), - ids + i * LABEL_LAYER_ID_MAX_SIZE)); + strlen(ids + i * LABEL_LAYER_ID_MAX_SIZE))); } int label_layer_render(const LabelLayer *label_layer, @@ -392,7 +389,6 @@ int label_layer_render(const LabelLayer *label_layer, camera, boundary_of_element( label_layer, - camera->font, i, position)), LABEL_LAYER_SELECTION_THICCNESS * 0.5f); @@ -414,7 +410,6 @@ int label_layer_render(const LabelLayer *label_layer, static int label_layer_element_at(LabelLayer *label_layer, - const Sprite_font *font, Vec2f position) { trace_assert(label_layer); @@ -426,7 +421,6 @@ int label_layer_element_at(LabelLayer *label_layer, if (rect_contains_point( boundary_of_element( label_layer, - font, (size_t) i, positions[i]), position)) { @@ -547,7 +541,6 @@ int label_layer_idle_event(LabelLayer *label_layer, const int element = label_layer_element_at( label_layer, - camera_font(camera), position); if (element >= 0) { diff --git a/src/game/level_picker.c b/src/game/level_picker.c index ac3c78ed..06baacc3 100644 --- a/src/game/level_picker.c +++ b/src/game/level_picker.c @@ -92,7 +92,7 @@ int level_picker_render(const LevelPicker *level_picker, return -1; } - const Vec2f title_size = wiggly_text_size(&level_picker->wiggly_text, camera); + const Vec2f title_size = wiggly_text_size(&level_picker->wiggly_text); if (wiggly_text_render( &level_picker->wiggly_text, @@ -142,8 +142,7 @@ int level_picker_update(LevelPicker *level_picker, } int level_picker_event(LevelPicker *level_picker, - const SDL_Event *event, - const Camera *camera) + const SDL_Event *event) { trace_assert(level_picker); trace_assert(event); @@ -159,7 +158,7 @@ int level_picker_event(LevelPicker *level_picker, int width; SDL_GetWindowSize(SDL_GetWindowFromID(event->window.windowID), &width, NULL); - const Vec2f title_size = wiggly_text_size(&level_picker->wiggly_text, camera); + const Vec2f title_size = wiggly_text_size(&level_picker->wiggly_text); const Vec2f selector_size = list_selector_size( level_picker->list_selector, diff --git a/src/game/level_picker.h b/src/game/level_picker.h index 7c661404..70bd8960 100644 --- a/src/game/level_picker.h +++ b/src/game/level_picker.h @@ -16,8 +16,7 @@ int level_picker_render(const LevelPicker *level_picker, int level_picker_update(LevelPicker *level, float delta_time); int level_picker_event(LevelPicker *level_picker, - const SDL_Event *event, - const Camera *camera); + const SDL_Event *event); int level_picker_input(LevelPicker *level_picker, const Uint8 *const keyboard_state, SDL_Joystick *the_stick_of_joy); diff --git a/src/game/sprite_font.c b/src/game/sprite_font.c index 0c32f307..de785e80 100644 --- a/src/game/sprite_font.c +++ b/src/game/sprite_font.c @@ -123,16 +123,3 @@ int sprite_font_render_text(const Sprite_font *sprite_font, return 0; } - -Rect sprite_font_boundary_box(const Sprite_font *sprite_font, - Vec2f position, - Vec2f size, - const char *text) -{ - trace_assert(sprite_font); - trace_assert(text); - return rect( - position.x, position.y, - size.x * FONT_CHAR_WIDTH * (float) strlen(text), - size.y * FONT_CHAR_HEIGHT); -} diff --git a/src/game/sprite_font.h b/src/game/sprite_font.h index 9cd11ac6..b09d5c70 100644 --- a/src/game/sprite_font.h +++ b/src/game/sprite_font.h @@ -21,9 +21,13 @@ int sprite_font_render_text(const Sprite_font *sprite_font, Color color, const char *text); -Rect sprite_font_boundary_box(const Sprite_font *sprite_font, - Vec2f position, - Vec2f size, - const char *text); +static inline +Rect sprite_font_boundary_box(Vec2f position, Vec2f size, size_t text_size) +{ + return rect( + position.x, position.y, + size.x * FONT_CHAR_WIDTH * (float) text_size, + size.y * FONT_CHAR_HEIGHT); +} #endif // SPRITE_FONT_H_ diff --git a/src/ui/list_selector.c b/src/ui/list_selector.c index 09e167da..d224e282 100644 --- a/src/ui/list_selector.c +++ b/src/ui/list_selector.c @@ -83,10 +83,9 @@ int list_selector_render(const ListSelector *list_selector, if (i == list_selector->cursor) { SDL_Rect boundary_box = rect_for_sdl( sprite_font_boundary_box( - list_selector->sprite_font, current_position, list_selector->font_scale, - list_selector->items[i])); + strlen(list_selector->items[i]))); if (SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255) < 0) { return -1; } @@ -110,10 +109,9 @@ Vec2f list_selector_size(const ListSelector *list_selector, for (size_t i = 0; i < list_selector->count; ++i) { Rect boundary_box = sprite_font_boundary_box( - list_selector->sprite_font, vec(0.0f, 0.0f), font_scale, - list_selector->items[i]); + strlen(list_selector->items[i])); result.x = fmaxf(result.x, boundary_box.w); result.y += boundary_box.y + padding_bottom; @@ -160,10 +158,9 @@ int list_selector_event(ListSelector *list_selector, const SDL_Event *event) for (size_t i = 0; i < list_selector->count; ++i) { Rect boundary_box = sprite_font_boundary_box( - list_selector->sprite_font, position, list_selector->font_scale, - list_selector->items[i]); + strlen(list_selector->items[i])); if (rect_contains_point(boundary_box, mouse_pos)) { list_selector->cursor = i; diff --git a/src/ui/wiggly_text.c b/src/ui/wiggly_text.c index 64305a82..b6633f54 100644 --- a/src/ui/wiggly_text.c +++ b/src/ui/wiggly_text.c @@ -46,15 +46,14 @@ int wiggly_text_update(WigglyText *wiggly_text, float delta_time) return 0; } -Vec2f wiggly_text_size(const WigglyText *wiggly_text, const Camera *camera) +Vec2f wiggly_text_size(const WigglyText *wiggly_text) { trace_assert(wiggly_text); - const Rect boundary = camera_text_boundary_box( - camera, + const Rect boundary = sprite_font_boundary_box( vec(0.0f, 0.0f), wiggly_text->scale, - wiggly_text->text); + strlen(wiggly_text->text)); return vec(boundary.w, boundary.h); } diff --git a/src/ui/wiggly_text.h b/src/ui/wiggly_text.h index 1162a293..40e4cd08 100644 --- a/src/ui/wiggly_text.h +++ b/src/ui/wiggly_text.h @@ -18,7 +18,7 @@ int wiggly_text_render(const WigglyText *wiggly_text, const Camera *camera, Vec2f position); int wiggly_text_update(WigglyText *wiggly_text, float delta_time); -Vec2f wiggly_text_size(const WigglyText *wiggly_text, const Camera *camera); +Vec2f wiggly_text_size(const WigglyText *wiggly_text); typedef struct { WigglyText wiggly_text; @@ -56,10 +56,9 @@ void fading_wiggly_text_reset(FadingWigglyText *fading_wiggly_text) } static inline -Vec2f fading_wiggly_text_size(const FadingWigglyText *fading_wiggly_text, - const Camera *camera) +Vec2f fading_wiggly_text_size(const FadingWigglyText *fading_wiggly_text) { - return wiggly_text_size(&fading_wiggly_text->wiggly_text, camera); + return wiggly_text_size(&fading_wiggly_text->wiggly_text); } #endif // WIGGLY_TEXT_H_ From 4f374fb87282a33e60514914ae5d533b2d1b06c9 Mon Sep 17 00:00:00 2001 From: rexim Date: Mon, 25 Nov 2019 02:25:05 +0700 Subject: [PATCH 05/10] (#1139) Put label id below label text --- src/game/level/level_editor/label_layer.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/game/level/level_editor/label_layer.c b/src/game/level/level_editor/label_layer.c index 1fb11f13..7743f964 100644 --- a/src/game/level/level_editor/label_layer.c +++ b/src/game/level/level_editor/label_layer.c @@ -302,9 +302,11 @@ Rect boundary_of_element(const LabelLayer *label_layer, LABELS_SIZE, strlen(texts + i * LABEL_LAYER_TEXT_MAX_SIZE)), sprite_font_boundary_box( - vec_sub( + vec_sum( position, - vec(0.0f, FONT_CHAR_HEIGHT)), + vec_mult( + vec(0.0f, FONT_CHAR_HEIGHT), + LABELS_SIZE)), vec(1.0f, 1.0f), strlen(ids + i * LABEL_LAYER_ID_MAX_SIZE))); } @@ -363,9 +365,11 @@ int label_layer_render(const LabelLayer *label_layer, if (edit_field_render_world( label_layer->edit_field, camera, - vec_sub( + vec_sum( position, - vec(0.0f, FONT_CHAR_HEIGHT))) < 0) { + vec_mult( + vec(0.0f, FONT_CHAR_HEIGHT), + LABELS_SIZE))) < 0) { return -1; } } else { @@ -376,7 +380,11 @@ int label_layer_render(const LabelLayer *label_layer, color_scale( color_invert(color), rgba(1.0f, 1.0f, 1.0f, active ? 1.0f : 0.5f)), - vec_sub(position, vec(0.0f, FONT_CHAR_HEIGHT))) < 0) { + vec_sum( + position, + vec_mult( + vec(0.0f, FONT_CHAR_HEIGHT), + LABELS_SIZE))) < 0) { return -1; } } From dfbfad94ef1d888cc4ca93b1fe6623b50d98273c Mon Sep 17 00:00:00 2001 From: rexim Date: Mon, 25 Nov 2019 02:51:35 +0700 Subject: [PATCH 06/10] (#1139) Implement Move snap for Label Layer --- src/config.h | 2 ++ src/game/level/level_editor/label_layer.c | 36 +++++++++++++++++++++++ src/game/level/level_editor/rect_layer.c | 1 - src/math/rect.h | 8 ++--- 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/config.h b/src/config.h index d1610ea6..c5bf63c4 100644 --- a/src/config.h +++ b/src/config.h @@ -17,4 +17,6 @@ #define ENTITY_MAX_ID_SIZE 36 +#define SNAPPING_THRESHOLD 10.0f + #endif // CONFIG_H_ diff --git a/src/game/level/level_editor/label_layer.c b/src/game/level/level_editor/label_layer.c index 7743f964..7c640814 100644 --- a/src/game/level/level_editor/label_layer.c +++ b/src/game/level/level_editor/label_layer.c @@ -16,6 +16,7 @@ #include "color_picker.h" #include "ui/edit_field.h" #include "math/extrema.h" +#include "config.h" #define LABEL_LAYER_SELECTION_THICCNESS 5.0f @@ -389,6 +390,7 @@ int label_layer_render(const LabelLayer *label_layer, } } + // TODO: Label Selection has to be internal (just like in Rect Layer) // Label Selection if (active && label_layer->selection == (int) i) { Rect selection = @@ -675,6 +677,38 @@ int label_layer_idle_event(LabelLayer *label_layer, return 0; } +static +void snap_inter_position(LabelLayer *label_layer, float snap_threshold) +{ + trace_assert(label_layer); + trace_assert(label_layer->selection >= 0); + trace_assert(label_layer->state == LABEL_LAYER_MOVE); + + const size_t n = dynarray_count(label_layer->positions); + Vec2f *positions = dynarray_data(label_layer->positions); + + Rect a = boundary_of_element( + label_layer, + (size_t) label_layer->selection, + label_layer->inter_position); + + for (size_t i = 0; i < n; ++i) { + if (i == (size_t) label_layer->selection) continue; + + const Rect b = boundary_of_element(label_layer, i, positions[i]); + + if (segment_overlap(vec(a.x, a.x + a.w), vec(b.x, b.x + b.w))) { + snap_seg2seg(&label_layer->inter_position.y, + b.y, a.h, b.h, snap_threshold); + } + + if (segment_overlap(vec(a.y, a.y + a.h), vec(b.y, b.y + b.h))) { + snap_seg2seg(&label_layer->inter_position.x, + b.x, a.w, b.w, snap_threshold); + } + } +} + static int label_layer_move_event(LabelLayer *label_layer, const SDL_Event *event, @@ -712,6 +746,8 @@ int label_layer_move_event(LabelLayer *label_layer, label_layer->inter_position = vec(label_pos.x, mouse_pos.y); } } + + snap_inter_position(label_layer, SNAPPING_THRESHOLD); } break; case SDL_MOUSEBUTTONUP: { diff --git a/src/game/level/level_editor/rect_layer.c b/src/game/level/level_editor/rect_layer.c index e9d67558..79634c8c 100644 --- a/src/game/level/level_editor/rect_layer.c +++ b/src/game/level/level_editor/rect_layer.c @@ -24,7 +24,6 @@ #define CREATE_AREA_THRESHOLD 10.0 #define RECT_LAYER_GRID_ROWS 3 #define RECT_LAYER_GRID_COLUMNS 4 -#define SNAPPING_THRESHOLD 10.0f static int clipboard = 0; static Rect clipboard_rect; diff --git a/src/math/rect.h b/src/math/rect.h index 79902147..fd138222 100644 --- a/src/math/rect.h +++ b/src/math/rect.h @@ -130,14 +130,15 @@ void snap_var(float *x, // the value we are snapping float yo, // y offset float st) // snap threshold { - if (fabsf((*x + xo) - (y + yo)) < st) + if (fabsf((*x + xo) - (y + yo)) < st) { *x = y + yo - xo; + } } static inline void snap_var2seg(float *x, float y, - float xo, float yo, - float st) + float xo, float yo, + float st) { snap_var(x, y, xo, 0, st); snap_var(x, y, xo, yo, st); @@ -152,5 +153,4 @@ void snap_seg2seg(float *x, float y, float xo, float yo, float st) snap_var(x, y, xo, yo, st); } - #endif // RECT_H_ From c53fb9ecf4a5527d5a9d0590f89c637e03020517 Mon Sep 17 00:00:00 2001 From: rexim Date: Mon, 25 Nov 2019 02:53:31 +0700 Subject: [PATCH 07/10] Add TODO(#1160) --- src/game/level/level_editor/label_layer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/level/level_editor/label_layer.c b/src/game/level/level_editor/label_layer.c index 7c640814..6267c885 100644 --- a/src/game/level/level_editor/label_layer.c +++ b/src/game/level/level_editor/label_layer.c @@ -390,8 +390,8 @@ int label_layer_render(const LabelLayer *label_layer, } } - // TODO: Label Selection has to be internal (just like in Rect Layer) // Label Selection + // TODO(#1160): Label Selection has to be internal (just like in Rect Layer) if (active && label_layer->selection == (int) i) { Rect selection = rect_pad( From 2d7f1561b448f0872d613546f610e50cac01a860 Mon Sep 17 00:00:00 2001 From: rexim Date: Mon, 25 Nov 2019 02:53:32 +0700 Subject: [PATCH 08/10] Add TODO(#1161) --- src/game/level/platforms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/level/platforms.c b/src/game/level/platforms.c index f4ab91b7..55b98682 100644 --- a/src/game/level/platforms.c +++ b/src/game/level/platforms.c @@ -94,7 +94,7 @@ Vec2f platforms_snap_rect(const Platforms *platforms, Vec2f result = vec(1.0f, 1.0f); for (size_t i = 0; i < platforms->rects_size; ++i) { if (rects_overlap(platforms->rects[i], *object)) { - // TODO: can we reuse the Level Editor snapping mechanism in physics snapping + // TODO(#1161): can we reuse the Level Editor snapping mechanism in physics snapping result = vec_entry_mult(result, rect_snap(platforms->rects[i], object)); } } From 9b0e3d58fa38bfe50cb6409d9ae4472b071937da Mon Sep 17 00:00:00 2001 From: rexim Date: Sat, 30 Nov 2019 23:21:48 +0700 Subject: [PATCH 09/10] (#1139) Add labels to the test level --- assets/levels/platforms.txt | 61 +++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/assets/levels/platforms.txt b/assets/levels/platforms.txt index 914bfdaf..9a0e857d 100644 --- a/assets/levels/platforms.txt +++ b/assets/levels/platforms.txt @@ -1,37 +1,40 @@ Platforms 073642 -117.10616 417.59192 b58900 +117.106163 417.591919 b58900 22 -rect6 0 658.81897 1617.7523 1014.819 657b83 -rect4-3-3 -1609.375 0 1659.375 1673.6379 657b83 -rect4-3-3-7 895.57068 0 50 680.31897 657b83 -rect4-3-3-7-5-3 829.6087 585.28345 65.961945 20 657b83 -rect4-3-3-7-5-3-6 669.13647 508.79398 65.961945 20 657b83 -rect4-3-3-7-5-3-5 829.6087 443.09402 65.961945 20 657b83 -rect4-3-3-7-5-3-6-3 669.13654 366.60455 65.961945 20 657b83 -rect4-3-3-7-5-3-56 829.6087 288.23764 65.961945 20 657b83 -rect4-3-3-7-5-3-6-2 669.13654 211.74818 65.961945 20 657b83 -rect4-3-3-7-5-3-9 829.6087 129.84573 65.961945 20 657b83 -rect4-3-3-7-5-3-6-1 669.13654 53.356262 65.961945 20 657b83 -rect4-3-3-7-5-3-2 945.57068 585.78259 65.961945 20 657b83 -rect4-3-3-7-5-3-6-37 1088.0984 509.29309 65.961945 20 657b83 -rect4-3-3-7-5-3-5-5 945.57068 443.59314 65.961945 20 657b83 -rect4-3-3-7-5-3-6-3-9 1088.0985 367.1037 65.961945 20 657b83 -rect4-3-3-7-5-3-56-2 945.57068 288.73676 65.961945 20 657b83 -rect4-3-3-7-5-3-6-2-2 1088.0985 212.24731 65.961945 20 657b83 -rect4-3-3-7-5-3-9-8 945.57068 130.34485 65.961945 20 657b83 -rect4-3-3-7-5-3-6-1-9 1088.0985 53.855385 65.961945 20 657b83 -rect4-3-3-7-7 1768.5708 -1131.3708 1356 2805.0088 657b83 -rect4-3-3-7-5-3-6-36 358.7562 617.80682 65.961945 82.024391 657b83 -rect4-3-3-7-5-3-6-7 508.66281 617.80682 65.961945 82.024391 657b83 +rect6 0.000000 658.818970 1617.752319 1014.818970 657b83 +rect4-3-3 -1609.375000 0.000000 1659.375000 1673.637939 657b83 +rect4-3-3-7 895.570679 0.000000 50.000000 680.318970 657b83 +rect4-3-3-7-5-3 829.608704 585.283447 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-6 669.136475 508.793976 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-5 829.608704 443.094025 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-6-3 669.136536 366.604553 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-56 829.608704 288.237640 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-6-2 669.136536 211.748184 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-9 829.608704 129.845734 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-6-1 669.136536 53.356262 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-2 945.570679 585.782593 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-6-37 1088.098389 509.293091 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-5-5 945.570679 443.593140 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-6-3-9 1088.098511 367.103699 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-56-2 945.570679 288.736755 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-6-2-2 1088.098511 212.247314 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-9-8 945.570679 130.344849 65.961945 20.000000 657b83 +rect4-3-3-7-5-3-6-1-9 1088.098511 53.855385 65.961945 20.000000 657b83 +rect4-3-3-7-7 1768.570801 -1131.370850 1356.000000 2805.008789 657b83 +rect4-3-3-7-5-3-6-36 358.756195 617.806824 65.961945 82.024391 657b83 +rect4-3-3-7-5-3-6-7 508.662811 617.806824 65.961945 82.024391 657b83 2 -goal2 973.78259 631.06897 d33682 -goal3 -103.3381 -136.98125 d33682 +goal2 973.782593 631.068970 d33682 +goal3 -103.338097 -136.981247 d33682 2 -lava1 413.91043 628.4342 105.55992 38.384777 000000 -lava1-3 225.22003 152.62662 357.55994 245.38478 ff9955 -0 -0 +lava1 413.910431 628.434204 105.559921 38.384777 000000 +lava1-3 225.220032 152.626617 357.559937 245.384781 ff9955 0 0 +2 +label_0 150.416733 691.458435 bfe34f +Label Test +label_1 290.416748 691.458435 bfe34f +Label Test 0 From c7497e39973303ab777fd573d4de1114ab7bc2dd Mon Sep 17 00:00:00 2001 From: rexim Date: Sat, 30 Nov 2019 23:23:12 +0700 Subject: [PATCH 10/10] (#1139) Fix MSVC build --- src/game/camera.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/game/camera.c b/src/game/camera.c index 59c71610..fe05bbe4 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -1,13 +1,15 @@ -#include -#include "system/stacktrace.h" #include #include #include +#include + +#include #include "camera.h" #include "sdl/renderer.h" #include "system/nth_alloc.h" #include "system/log.h" +#include "system/stacktrace.h" #define RATIO_X 16.0f #define RATIO_Y 9.0f