]> git.lizzy.rs Git - nothing.git/blob - src/game/level/background.c
Merge pull request #1210 from ozy/450
[nothing.git] / src / game / level / background.c
1 #include <stdio.h>
2
3 #include "game/level/background.h"
4 #include "math/rand.h"
5 #include "math/rect.h"
6 #include "system/line_stream.h"
7 #include "system/lt.h"
8 #include "system/nth_alloc.h"
9 #include "system/log.h"
10 #include "system/stacktrace.h"
11 #include "config.h"
12
13 static inline
14 Vec2i chunk_of_point(Vec2f p)
15 {
16     return vec2i(
17         (int) floorf(p.x / BACKGROUND_CHUNK_WIDTH),
18         (int) floorf(p.y / BACKGROUND_CHUNK_HEIGHT));
19 }
20
21 int render_chunk(const Camera *camera,
22                  Vec2i chunk,
23                  Color color);
24
25 int background_render(const Background *background,
26                       const Camera *camera0)
27 {
28     trace_assert(background);
29     trace_assert(camera0);
30
31     Camera camera = *camera0;
32
33     if (camera_clear_background(
34             &camera,
35             background->base_color) < 0) {
36         return -1;
37     }
38
39     camera.scale = 1.0f - BACKGROUND_LAYERS_STEP * BACKGROUND_LAYERS_COUNT;
40
41     for (int l = 0; l < BACKGROUND_LAYERS_COUNT; ++l) {
42         const Rect view_port = camera_view_port(&camera);
43         const Vec2f position = vec(view_port.x, view_port.y);
44
45         Vec2i min = chunk_of_point(position);
46         Vec2i max = chunk_of_point(vec_sum(position, vec(view_port.w, view_port.h)));
47
48         for (int x = min.x - 1; x <= max.x; ++x) {
49             for (int y = min.y - 1; y <= max.y; ++y) {
50                 if (render_chunk(
51                         &camera,
52                         vec2i(x, y),
53                         color_darker(background->base_color, 0.05f * (float)(l + 1))) < 0) {
54                     return -1;
55                 }
56             }
57         }
58
59         camera.scale += BACKGROUND_LAYERS_STEP;
60     }
61
62     return 0;
63 }
64
65 /* Private Function */
66
67 int render_chunk(const Camera *camera,
68                  Vec2i chunk,
69                  Color color)
70 {
71     trace_assert(camera);
72
73     if (camera->debug_mode) {
74         return 0;
75     }
76
77     srand((unsigned int)(roundf((float)chunk.x + (float)chunk.y + camera->scale * 10.0f)));
78
79     for (size_t i = 0; i < BACKGROUND_TURDS_PER_CHUNK; ++i) {
80         const float rect_x = rand_float_range(0.0f, BACKGROUND_CHUNK_WIDTH);
81         const float rect_y = rand_float_range(0.0f, BACKGROUND_CHUNK_HEIGHT);
82
83         const float rect_w = rand_float_range(0.0f, BACKGROUND_CHUNK_WIDTH * 0.5f);
84         const float rect_h = rand_float_range(rect_w * 0.5f, rect_w * 1.5f);
85
86         if (camera_fill_rect(
87                 camera,
88                 rect((float) chunk.x * BACKGROUND_CHUNK_WIDTH + rect_x,
89                      (float) chunk.y * BACKGROUND_CHUNK_HEIGHT + rect_y,
90                      rect_w,
91                      rect_h),
92                 color) < 0) {
93             return -1;
94         }
95     }
96
97     return 0;
98 }
99
100 Color background_base_color(const Background *background)
101 {
102     return background->base_color;
103 }