+#include <SDL.h>
+#include "system/stacktrace.h"
#include <stdio.h>
#include <stdlib.h>
-#include <assert.h>
#include <string.h>
+#include <errno.h>
-#include <SDL2/SDL.h>
+#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 "./platforms.h"
-#include "./system/error.h"
-#include "./lt.h"
+struct Platforms {
+ Lt *lt;
-struct platforms_t {
- lt_t *lt;
-
- rect_t *rects;
- color_t *colors;
+ Rect *rects;
+ Color *colors;
size_t rects_size;
};
-platforms_t *create_platforms_from_stream(FILE *stream)
+Platforms *create_platforms_from_rect_layer(const RectLayer *layer)
{
- assert(stream);
+ trace_assert(layer);
- lt_t *const lt = create_lt();
- if (lt == NULL) {
- return NULL;
- }
+ Lt *lt = create_lt();
- platforms_t *platforms = PUSH_LT(lt, malloc(sizeof(platforms_t)), free);
+ Platforms *platforms = PUSH_LT(
+ lt,
+ nth_calloc(1, sizeof(Platforms)),
+ free);
if (platforms == NULL) {
- throw_error(ERROR_TYPE_LIBC);
RETURN_LT(lt, NULL);
}
+ platforms->lt = lt;
- platforms->rects_size = 0;
- if (fscanf(stream, "%lu", &platforms->rects_size) == EOF) {
- throw_error(ERROR_TYPE_LIBC);
- RETURN_LT(lt, NULL);
- }
+ platforms->rects_size = rect_layer_count(layer);
- platforms->rects = PUSH_LT(lt, malloc(sizeof(rect_t) * platforms->rects_size), free);
+ platforms->rects = PUSH_LT(lt, nth_calloc(1, sizeof(Rect) * platforms->rects_size), free);
if (platforms->rects == NULL) {
- throw_error(ERROR_TYPE_LIBC);
RETURN_LT(lt, NULL);
}
+ memcpy(platforms->rects, rect_layer_rects(layer), sizeof(Rect) * platforms->rects_size);
+
- platforms->colors = PUSH_LT(lt, malloc(sizeof(color_t) * platforms->rects_size), free);
+ platforms->colors = PUSH_LT(lt, nth_calloc(1, sizeof(Color) * platforms->rects_size), free);
if (platforms->colors == NULL) {
- throw_error(ERROR_TYPE_LIBC);
RETURN_LT(lt, NULL);
}
+ memcpy(platforms->colors, rect_layer_colors(layer), sizeof(Color) * platforms->rects_size);
- char color[7];
- for (size_t i = 0; i < platforms->rects_size; ++i) {
- if (fscanf(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) {
- throw_error(ERROR_TYPE_LIBC);
- RETURN_LT(lt, NULL);
- }
- platforms->colors[i] = color_from_hexstr(color);
- }
-
- platforms->lt = lt;
-
- return platforms;
-}
-
-platforms_t *create_platforms_from_file(const char *filename)
-{
- assert(filename);
-
- FILE *platforms_file = fopen(filename, "r");
- if (platforms_file == NULL) {
- throw_error(ERROR_TYPE_LIBC);
- return NULL;
- }
-
- platforms_t *platforms = create_platforms_from_stream(platforms_file);
- if (platforms != NULL) {
- fclose(platforms_file);
- return NULL;
- }
-
- fclose(platforms_file);
return platforms;
}
-void destroy_platforms(platforms_t *platforms)
+void destroy_platforms(Platforms *platforms)
{
- assert(platforms);
+ trace_assert(platforms);
RETURN_LT0(platforms->lt);
}
-int platforms_save_to_file(const platforms_t *platforms,
- const char *filename)
-{
- assert(platforms);
- assert(filename);
-
- lt_t *const lt = create_lt();
- if (lt == NULL) {
- return -1;
- }
-
- FILE *platforms_file = PUSH_LT(lt, fopen(filename, "w"), fclose);
-
- if (platforms_file == NULL) {
- throw_error(ERROR_TYPE_LIBC);
- 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) {
- throw_error(ERROR_TYPE_LIBC);
- RETURN_LT(lt, -1);
- }
- }
-
- RETURN_LT(lt, 0);
-}
-
-int platforms_render(const platforms_t *platforms,
- SDL_Renderer *renderer,
- const camera_t *camera)
+/* TODO(#450): platforms do not render their ids in debug mode */
+int platforms_render(const Platforms *platforms,
+ Camera *camera)
{
for (size_t i = 0; i < platforms->rects_size; ++i) {
if (camera_fill_rect(
camera,
- renderer,
platforms->rects[i],
platforms->colors[i]) < 0) {
- throw_error(ERROR_TYPE_SDL2);
return -1;
}
}
return 0;
}
-void platforms_rect_object_collide(const platforms_t *platforms,
- rect_t object,
- int sides[RECT_SIDE_N])
+void platforms_touches_rect_sides(const Platforms *platforms,
+ Rect object,
+ int sides[RECT_SIDE_N])
{
- assert(platforms);
+ trace_assert(platforms);
+
+ for (size_t i = 0; i < platforms->rects_size; ++i) {
+ rect_object_impact(object, platforms->rects[i], sides);
+ }
+}
- memset(sides, 0, sizeof(int) * RECT_SIDE_N);
+Vec platforms_snap_rect(const Platforms *platforms,
+ Rect *object)
+{
+ trace_assert(platforms);
+ Vec result = vec(1.0f, 1.0f);
for (size_t i = 0; i < platforms->rects_size; ++i) {
- rect_object_impact(&object, &platforms->rects[i], sides);
+ if (rects_overlap(platforms->rects[i], *object)) {
+ result = vec_entry_mult(result, rect_snap(platforms->rects[i], object));
+ }
}
+
+ return result;
}