1 #include "system/stacktrace.h"
3 #include "game/level/background.h"
6 #include "system/line_stream.h"
8 #include "system/nth_alloc.h"
9 #include "system/log.h"
11 #define BACKGROUND_CHUNK_COUNT 5
12 #define BACKGROUND_CHUNK_WIDTH 250.0f
13 #define BACKGROUND_CHUNK_HEIGHT 250.0f
15 static void chunk_of_point(Point p, int *x, int *y);
16 int render_chunk(const Background *background,
31 Background *create_background(Color base_color)
35 Background *background = PUSH_LT(lt, nth_calloc(1, sizeof(Background)), free);
36 if (background == NULL) {
40 background->base_color = base_color;
41 background->position = vec(0.0f, 0.0f);
42 background->debug_mode = 0;
48 Background *create_background_from_line_stream(LineStream *line_stream)
51 if (sscanf(line_stream_next(line_stream), "%6s", color) == EOF) {
52 log_fail("Could not read background's color\n");
56 return create_background(hexstr(color));
59 void destroy_background(Background *background)
61 trace_assert(background);
62 RETURN_LT0(background->lt);
65 /* TODO(#182): background chunks are randomly disappearing when the size of the window is less than size of the chunk */
66 int background_render(const Background *background,
69 trace_assert(background);
72 if (camera_clear_background(
74 background->base_color) < 0) {
78 const Rect view_port = camera_view_port(camera);
79 const Vec position = vec(view_port.x, view_port.y);
81 for (int l = 0; l < 3; ++l) {
82 const float parallax = 1.0f - 0.2f * (float)l;
84 int min_x = 0, min_y = 0;
85 chunk_of_point(vec(view_port.x - position.x * parallax,
86 view_port.y - position.y * parallax),
89 int max_x = 0, max_y = 0;
90 chunk_of_point(vec(view_port.x - position.x * parallax + view_port.w,
91 view_port.y - position.y * parallax + view_port.h),
94 for (int x = min_x; x <= max_x; ++x) {
95 for (int y = min_y; y <= max_y; ++y) {
100 color_darker(background->base_color, 0.05f * (float)(l + 1)),
112 /* Private Function */
114 static void chunk_of_point(Point p, int *x, int *y)
118 *x = (int) (p.x / BACKGROUND_CHUNK_WIDTH);
119 *y = (int) (p.y / BACKGROUND_CHUNK_HEIGHT);
122 int render_chunk(const Background *background,
124 int chunk_x, int chunk_y,
131 if (background->debug_mode) {
135 srand((unsigned int)(roundf((float)chunk_x + (float)chunk_y + parallax)));
137 for (size_t i = 0; i < BACKGROUND_CHUNK_COUNT; ++i) {
138 const float rect_x = rand_float_range((float) chunk_x * BACKGROUND_CHUNK_WIDTH,
139 (float) (chunk_x + 1) * BACKGROUND_CHUNK_WIDTH);
140 const float rect_y = rand_float_range((float) chunk_y * BACKGROUND_CHUNK_HEIGHT,
141 (float) (chunk_y + 1) * BACKGROUND_CHUNK_HEIGHT);
142 const float rect_w = rand_float_range(0.0f, BACKGROUND_CHUNK_WIDTH * 0.5f);
143 const float rect_h = rand_float_range(rect_w * 0.5f, rect_w * 1.5f);
145 if (camera_fill_rect(
147 rect(rect_x + position.x * parallax,
148 rect_y + position.y * parallax,
159 void background_toggle_debug_mode(Background *background)
161 background->debug_mode = !background->debug_mode;