]> git.lizzy.rs Git - nothing.git/blobdiff - src/game/level/platforms.c
(#639) Introduce rigid_bodies_collide_with_itself
[nothing.git] / src / game / level / platforms.c
index e9f33edd28a5158ee6183632ca14d136b5d49048..3fd99661889a5cede28ef3b373f5112c4c05e977 100644 (file)
@@ -1,64 +1,69 @@
 #include <SDL2/SDL.h>
-#include <assert.h>
+#include "system/stacktrace.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 
 #include "platforms.h"
-#include "system/error.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"
 
-struct platforms_t {
-    lt_t *lt;
+struct Platforms {
+    Lt *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_line_stream(LineStream *line_stream)
 {
-    assert(stream);
+    trace_assert(line_stream);
 
-    lt_t *const lt = create_lt();
+    Lt *const lt = create_lt();
     if (lt == NULL) {
         return NULL;
     }
 
-    platforms_t *platforms = PUSH_LT(lt, malloc(sizeof(platforms_t)), free);
+    Platforms *platforms = PUSH_LT(lt, nth_alloc(sizeof(Platforms)), free);
     if (platforms == NULL) {
-        throw_error(ERROR_TYPE_LIBC);
         RETURN_LT(lt, NULL);
     }
 
     platforms->rects_size = 0;
-    if (fscanf(stream, "%lu", &platforms->rects_size) == EOF) {
-        throw_error(ERROR_TYPE_LIBC);
+    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 = PUSH_LT(lt, malloc(sizeof(rect_t) * platforms->rects_size), free);
+    platforms->rects = PUSH_LT(lt, nth_alloc(sizeof(Rect) * platforms->rects_size), free);
     if (platforms->rects == NULL) {
-        throw_error(ERROR_TYPE_LIBC);
         RETURN_LT(lt, NULL);
     }
 
-    platforms->colors = PUSH_LT(lt, malloc(sizeof(color_t) * platforms->rects_size), free);
+    platforms->colors = PUSH_LT(lt, nth_alloc(sizeof(Color) * platforms->rects_size), free);
     if (platforms->colors == NULL) {
-        throw_error(ERROR_TYPE_LIBC);
         RETURN_LT(lt, NULL);
     }
 
     char color[7];
     for (size_t i = 0; i < platforms->rects_size; ++i) {
-        if (fscanf(stream, "%f%f%f%f%6s\n",
+        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) {
-            throw_error(ERROR_TYPE_LIBC);
+            log_fail("Could not read %dth platform\n", i);
             RETURN_LT(lt, NULL);
         }
-        platforms->colors[i] = color_from_hexstr(color);
+        platforms->colors[i] = hexstr(color);
     }
 
     platforms->lt = lt;
@@ -66,47 +71,27 @@ platforms_t *create_platforms_from_stream(FILE *stream)
     return platforms;
 }
 
-platforms_t *create_platforms_from_file(const char *filename)
+void destroy_platforms(Platforms *platforms)
 {
-    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)
-{
-    assert(platforms);
+    trace_assert(platforms);
     RETURN_LT0(platforms->lt);
 }
 
-int platforms_save_to_file(const platforms_t *platforms,
+int platforms_save_to_file(const Platforms *platforms,
                            const char *filename)
 {
-    assert(platforms);
-    assert(filename);
+    trace_assert(platforms);
+    trace_assert(filename);
 
-    lt_t *const lt = create_lt();
+    Lt *const lt = create_lt();
     if (lt == NULL) {
         return -1;
     }
 
-    FILE *platforms_file = PUSH_LT(lt, fopen(filename, "w"), fclose);
+    FILE *platforms_file = PUSH_LT(lt, fopen(filename, "w"), fclose_lt);
 
     if (platforms_file == NULL) {
-        throw_error(ERROR_TYPE_LIBC);
+        log_fail("Could not open file '%s': %s\n", filename, strerror(errno));
         RETURN_LT(lt, -1);
     }
 
@@ -114,7 +99,7 @@ int platforms_save_to_file(const platforms_t *platforms,
         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);
+            log_fail("Could not read %dth platform\n", i);
             RETURN_LT(lt, -1);
         }
     }
@@ -122,15 +107,25 @@ int platforms_save_to_file(const platforms_t *platforms,
     RETURN_LT(lt, 0);
 }
 
-int platforms_render(const platforms_t *platforms,
-                     const camera_t *camera)
+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)
 {
     for (size_t i = 0; i < platforms->rects_size; ++i) {
         if (camera_fill_rect(
                 camera,
                 platforms->rects[i],
                 platforms->colors[i]) < 0) {
-            throw_error(ERROR_TYPE_SDL2);
             return -1;
         }
     }
@@ -138,15 +133,13 @@ int platforms_render(const platforms_t *platforms,
     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);
-
-    memset(sides, 0, sizeof(int) * RECT_SIDE_N);
+    trace_assert(platforms);
 
     for (size_t i = 0; i < platforms->rects_size; ++i) {
-        rect_object_impact(&object, &platforms->rects[i], sides);
+        rect_object_impact(object, platforms->rects[i], sides);
     }
 }