]> git.lizzy.rs Git - nothing.git/blobdiff - src/game/level/background.c
(#639) Make rigid bodies interact with platforms
[nothing.git] / src / game / level / background.c
index 5305f5b52dd6279befae2765767ffb64c1bd6d70..eaecf20dc00e53be6e1313f910806f99e55a387c 100644 (file)
-#include <assert.h>
+#include "system/stacktrace.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"
 
-#define BACKGROUND_CHUNK_COUNT 10
-#define BACKGROUND_CHUNK_WIDTH 500.0f
-#define BACKGROUND_CHUNK_HEIGHT 500.0f
+#define BACKGROUND_CHUNK_COUNT 5
+#define BACKGROUND_CHUNK_WIDTH 250.0f
+#define BACKGROUND_CHUNK_HEIGHT 250.0f
 
-static void chunk_of_point(point_t p, int *x, int *y);
-int render_chunk(const background_t *background,
-                 const camera_t *camera,
+static void chunk_of_point(Point p, int *x, int *y);
+int render_chunk(const Background *background,
+                 Camera *camera,
                  int x, int y,
-                 color_t color,
+                 Color color,
+                 Vec position,
                  float parallax);
 
-struct background_t
+struct Background
 {
-    lt_t *lt;
-    color_t base_color;
-    vec_t position;
+    Lt *lt;
+    Color base_color;
+    Vec position;
+    int debug_mode;
 };
 
-background_t *create_background(color_t base_color)
+Background *create_background(Color base_color)
 {
-    lt_t *lt = create_lt();
+    Lt *lt = create_lt();
     if (lt == NULL) {
         return NULL;
     }
 
-    background_t *background = PUSH_LT(lt, malloc(sizeof(background_t)), free);
+    Background *background = PUSH_LT(lt, nth_alloc(sizeof(Background)), free);
     if (background == NULL) {
         RETURN_LT(lt, NULL);
     }
 
     background->base_color = base_color;
     background->position = vec(0.0f, 0.0f);
+    background->debug_mode = 0;
     background->lt = lt;
 
     return background;
 }
 
-void destroy_background(background_t *background)
+Background *create_background_from_line_stream(LineStream *line_stream)
 {
-    assert(background);
-    RETURN_LT0(background->lt);
+    char color[7];
+    if (sscanf(line_stream_next(line_stream), "%6s", color) == EOF) {
+        log_fail("Could not read background's color\n");
+        return NULL;
+    }
+
+    return create_background(hexstr(color));
 }
 
-int background_render(const background_t *background,
-                      const camera_t *camera)
+void destroy_background(Background *background)
 {
-    assert(background);
-    assert(camera);
+    trace_assert(background);
+    RETURN_LT0(background->lt);
+}
 
-    rect_t view_port = camera_view_port(camera);
+/* TODO(#182): background chunks are randomly disappearing when the size of the window is less than size of the chunk  */
+int background_render(const Background *background,
+                      Camera *camera)
+{
+    trace_assert(background);
+    trace_assert(camera);
 
-    int min_x = 0, min_y = 0;
-    chunk_of_point(vec(view_port.x, view_port.y), &min_x, &min_y);
+    if (camera_clear_background(
+            camera,
+            background->base_color) < 0) {
+        return -1;
+    }
 
-    int max_x = 0, max_y = 0;
-    chunk_of_point(vec(view_port.x + view_port.w,
-                       view_port.y + view_port.h), &max_x, &max_y);
+    const Rect view_port = camera_view_port(camera);
+    const Vec position = vec(view_port.x, view_port.y);
 
     for (int l = 0; l < 3; ++l) {
+        const float parallax = 1.0f - 0.2f * (float)l;
+
+        int min_x = 0, min_y = 0;
+        chunk_of_point(vec(view_port.x - position.x * parallax,
+                           view_port.y - position.y * parallax),
+                       &min_x, &min_y);
+
+        int max_x = 0, max_y = 0;
+        chunk_of_point(vec(view_port.x - position.x * parallax + view_port.w,
+                           view_port.y - position.y * parallax + view_port.h),
+                       &max_x, &max_y);
+
         for (int x = min_x; x <= max_x; ++x) {
             for (int y = min_y; y <= max_y; ++y) {
-                if (render_chunk(background, camera, x, y, color_darker(background->base_color, 0.2f * (float)l), 1.0f - 0.2f * (float)l) < 0) {
+                if (render_chunk(
+                        background,
+                        camera,
+                        x, y,
+                        color_darker(background->base_color, 0.05f * (float)(l + 1)),
+                        position,
+                        parallax) < 0) {
                     return -1;
                 }
             }
@@ -76,42 +112,43 @@ int background_render(const background_t *background,
     return 0;
 }
 
-void background_move_to(background_t *background,
-                        vec_t position)
-{
-    background->position = position;
-}
-
 /* Private Function */
 
-static void chunk_of_point(point_t p, int *x, int *y)
+static void chunk_of_point(Point p, int *x, int *y)
 {
-    assert(x);
-    assert(y);
-    *x = (int) roundf(p.x / BACKGROUND_CHUNK_WIDTH);
-    *y = (int) roundf(p.y / BACKGROUND_CHUNK_HEIGHT);
+    trace_assert(x);
+    trace_assert(y);
+    *x = (int) (p.x / BACKGROUND_CHUNK_WIDTH);
+    *y = (int) (p.y / BACKGROUND_CHUNK_HEIGHT);
 }
 
-int render_chunk(const background_t *background,
-                 const camera_t *camera,
-                 int x, int y,
-                 color_t color,
+int render_chunk(const Background *background,
+                 Camera *camera,
+                 int chunk_x, int chunk_y,
+                 Color color,
+                 Vec position,
                  float parallax)
 {
-    srand((unsigned int)(roundf((float)x + (float)y + parallax)));
+    (void) background;
+
+    if (background->debug_mode) {
+        return 0;
+    }
+
+    srand((unsigned int)(roundf((float)chunk_x + (float)chunk_y + parallax)));
 
     for (size_t i = 0; i < BACKGROUND_CHUNK_COUNT; ++i) {
-        const float rect_x = rand_float_range((float) x * BACKGROUND_CHUNK_WIDTH,
-                                              (float) (x + 1) * BACKGROUND_CHUNK_WIDTH);
-        const float rect_y = rand_float_range((float) y * BACKGROUND_CHUNK_HEIGHT,
-                                              (float) (y + 1) * BACKGROUND_CHUNK_HEIGHT);
+        const float rect_x = rand_float_range((float) chunk_x * BACKGROUND_CHUNK_WIDTH,
+                                              (float) (chunk_x + 1) * BACKGROUND_CHUNK_WIDTH);
+        const float rect_y = rand_float_range((float) chunk_y * BACKGROUND_CHUNK_HEIGHT,
+                                              (float) (chunk_y + 1) * BACKGROUND_CHUNK_HEIGHT);
         const float rect_w = rand_float_range(0.0f, BACKGROUND_CHUNK_WIDTH * 0.5f);
-        const float rect_h = rand_float_range(0.0f, BACKGROUND_CHUNK_HEIGHT * 0.5f);
+        const float rect_h = rand_float_range(rect_w * 0.5f, rect_w * 1.5f);
 
         if (camera_fill_rect(
                 camera,
-                rect(rect_x + background->position.x * parallax,
-                     rect_y + background->position.y * parallax,
+                rect(rect_x + position.x * parallax,
+                     rect_y + position.y * parallax,
                      rect_w,
                      rect_h),
                 color) < 0) {
@@ -121,3 +158,8 @@ int render_chunk(const background_t *background,
 
     return 0;
 }
+
+void background_toggle_debug_mode(Background *background)
+{
+    background->debug_mode = !background->debug_mode;
+}