-#include <SDL2/SDL.h>
+#include <SDL.h>
#include "system/stacktrace.h"
#include <stdio.h>
#include <stdlib.h>
#include "platforms.h"
#include "system/lt.h"
-#include "system/lt/lt_adapters.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/extrema.h"
struct Platforms {
Lt *lt;
size_t rects_size;
};
-Platforms *create_platforms_from_line_stream(LineStream *line_stream)
+Platforms *create_platforms_from_rect_layer(const RectLayer *layer)
{
- trace_assert(line_stream);
+ trace_assert(layer);
- Lt *const lt = create_lt();
- if (lt == NULL) {
- return NULL;
- }
+ Lt *lt = create_lt();
- Platforms *platforms = PUSH_LT(lt, nth_alloc(sizeof(Platforms)), free);
+ Platforms *platforms = PUSH_LT(
+ lt,
+ nth_calloc(1, sizeof(Platforms)),
+ free);
if (platforms == NULL) {
RETURN_LT(lt, NULL);
}
+ platforms->lt = lt;
- platforms->rects_size = 0;
- if (sscanf(
- line_stream_next(line_stream),
- "%lu",
- &platforms->rects_size) == EOF) {
- log_fail("Could not read amount of platforms\n");
- RETURN_LT(lt, NULL);
- }
+ platforms->rects_size = rect_layer_count(layer);
- platforms->rects = PUSH_LT(lt, nth_alloc(sizeof(Rect) * platforms->rects_size), free);
+ platforms->rects = PUSH_LT(lt, nth_calloc(1, sizeof(Rect) * platforms->rects_size), free);
if (platforms->rects == NULL) {
RETURN_LT(lt, NULL);
}
+ memcpy(platforms->rects, rect_layer_rects(layer), sizeof(Rect) * platforms->rects_size);
+
- platforms->colors = PUSH_LT(lt, nth_alloc(sizeof(Color) * platforms->rects_size), free);
+ platforms->colors = PUSH_LT(lt, nth_calloc(1, sizeof(Color) * platforms->rects_size), free);
if (platforms->colors == NULL) {
RETURN_LT(lt, NULL);
}
-
- char color[7];
- for (size_t i = 0; i < platforms->rects_size; ++i) {
- if (sscanf(line_stream_next(line_stream),
- "%f%f%f%f%6s\n",
- &platforms->rects[i].x, &platforms->rects[i].y,
- &platforms->rects[i].w, &platforms->rects[i].h,
- color) < 0) {
- log_fail("Could not read %dth platform\n", i);
- RETURN_LT(lt, NULL);
- }
- platforms->colors[i] = hexstr(color);
- }
-
- platforms->lt = lt;
+ memcpy(platforms->colors, rect_layer_colors(layer), sizeof(Color) * platforms->rects_size);
return platforms;
}
RETURN_LT0(platforms->lt);
}
-int platforms_save_to_file(const Platforms *platforms,
- const char *filename)
-{
- trace_assert(platforms);
- trace_assert(filename);
-
- Lt *const lt = create_lt();
- if (lt == NULL) {
- return -1;
- }
-
- FILE *platforms_file = PUSH_LT(lt, fopen(filename, "w"), fclose_lt);
-
- if (platforms_file == NULL) {
- log_fail("Could not open file '%s': %s\n", filename, strerror(errno));
- RETURN_LT(lt, -1);
- }
-
- for (size_t i = 0; i < platforms->rects_size; ++i) {
- if (fprintf(platforms_file, "%f %f %f %f\n",
- platforms->rects[i].x, platforms->rects[i].y,
- platforms->rects[i].w, platforms->rects[i].h) < 0) {
- log_fail("Could not read %dth platform\n", i);
- RETURN_LT(lt, -1);
- }
- }
-
- RETURN_LT(lt, 0);
-}
-
-Solid_ref platforms_as_solid(Platforms *platforms)
-{
- Solid_ref ref = {
- .tag = SOLID_PLATFORMS,
- .ptr = (void*)platforms
- };
-
- return ref;
-}
-
-/* TODO(#450): platforms do not render their ids in debug mode */
int platforms_render(const Platforms *platforms,
- Camera *camera)
+ const Camera *camera)
{
for (size_t i = 0; i < platforms->rects_size; ++i) {
+ Rect platform_rect = platforms->rects[i];
if (camera_fill_rect(
camera,
- platforms->rects[i],
+ platform_rect,
platforms->colors[i]) < 0) {
return -1;
}
+
+ char debug_text[256];
+ snprintf(debug_text, 256,
+ "id:%zd\n"
+ "x:%.2f\n"
+ "y:%.2f\n"
+ "w:%.2f\n"
+ "h:%.2f\n",
+ i, platform_rect.x, platform_rect.y, platform_rect.w, platform_rect.h);
+
+ Vec2f text_pos = (Vec2f){.x = platform_rect.x, .y = platform_rect.y};
+ Rect text_rect = sprite_font_boundary_box(text_pos, vec(2.0f, 2.0f), debug_text);
+
+ Rect world_viewport = camera_view_port(camera);
+ Rect viewport = camera_view_port_screen(camera);
+
+ if (rects_overlap(
+ camera_rect(
+ camera,
+ platform_rect),
+ viewport) &&
+ camera_is_point_visible(
+ camera,
+ text_pos) == false) {
+ if (platform_rect.w > text_rect.w){
+ text_pos.x = fmaxf(fminf(world_viewport.x, platform_rect.x + platform_rect.w - text_rect.w),
+ platform_rect.x);
+ }
+ if (platform_rect.h > text_rect.h){
+ text_pos.y = fmaxf(fminf(world_viewport.y, platform_rect.y + platform_rect.h - text_rect.h),
+ platform_rect.y);
+ }
+ }
+
+ if (camera_render_debug_text(
+ camera,
+ debug_text,
+ text_pos) < 0) {
+ return -1;
+ }
}
return 0;
}
}
-Rect platforms_snap_rect(const Platforms *platforms,
- Rect object)
+Vec2f platforms_snap_rect(const Platforms *platforms,
+ Rect *object)
{
trace_assert(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)) {
- object = rect_snap(platforms->rects[i], object);
+ if (rects_overlap(platforms->rects[i], *object)) {
+ // TODO(#1161): can we reuse the Level Editor snapping mechanism in physics snapping
+ result = vec_entry_mult(result, rect_snap(platforms->rects[i], object));
}
}
- return object;
+ return result;
}