]> git.lizzy.rs Git - nothing.git/blob - src/game/level/platforms.c
460e77d712115d2c39ac029f5c509d8eb62607a9
[nothing.git] / src / game / level / platforms.c
1 #include <SDL.h>
2 #include "system/stacktrace.h"
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <errno.h>
7
8 #include "platforms.h"
9 #include "system/lt.h"
10 #include "system/nth_alloc.h"
11 #include "system/log.h"
12 #include "game/level/level_editor/rect_layer.h"
13 #include "math/extrema.h"
14
15 Platforms create_platforms_from_rect_layer(const RectLayer *layer)
16 {
17     trace_assert(layer);
18
19     Platforms platforms = {0};
20     platforms.rects_size = rect_layer_count(layer);
21
22     platforms.rects = nth_calloc(1, sizeof(Rect) * platforms.rects_size);
23     memcpy(
24         platforms.rects,
25         rect_layer_rects(layer),
26         sizeof(Rect) * platforms.rects_size);
27
28     platforms.colors = nth_calloc(1, sizeof(Color) * platforms.rects_size);
29     memcpy(
30         platforms.colors,
31         rect_layer_colors(layer),
32         sizeof(Color) * platforms.rects_size);
33
34     return platforms;
35 }
36
37 void destroy_platforms(Platforms platforms)
38 {
39     free(platforms.rects);
40     free(platforms.colors);
41 }
42
43 int platforms_render(const Platforms *platforms,
44                      const Camera *camera)
45 {
46     for (size_t i = 0; i < platforms->rects_size; ++i) {
47         Rect platform_rect = platforms->rects[i];
48         if (camera_fill_rect(
49                 camera,
50                 platform_rect,
51                 platforms->colors[i]) < 0) {
52             return -1;
53         }
54
55         char debug_text[256];
56         snprintf(debug_text, 256,
57             "id:%zd\n"
58             "x:%.2f\n"
59             "y:%.2f\n"
60             "w:%.2f\n"
61             "h:%.2f\n",
62             i, platform_rect.x, platform_rect.y, platform_rect.w, platform_rect.h);
63
64         Vec2f text_pos = (Vec2f){.x = platform_rect.x, .y = platform_rect.y};
65         Rect text_rect = sprite_font_boundary_box(text_pos, vec(2.0f, 2.0f), debug_text);
66
67         Rect world_viewport = camera_view_port(camera);
68         Rect viewport = camera_view_port_screen(camera);
69
70         if (rects_overlap(
71                 camera_rect(
72                     camera,
73                     platform_rect),
74                 viewport) &&
75             camera_is_point_visible(
76                 camera,
77                 text_pos) == false) {
78             if (platform_rect.w > text_rect.w){
79                 text_pos.x = fmaxf(fminf(world_viewport.x, platform_rect.x + platform_rect.w - text_rect.w),
80                                    platform_rect.x);
81             }
82             if (platform_rect.h > text_rect.h){
83                 text_pos.y = fmaxf(fminf(world_viewport.y, platform_rect.y + platform_rect.h - text_rect.h),
84                                    platform_rect.y);
85             }
86         }
87
88         if (camera_render_debug_text(
89                 camera,
90                 debug_text,
91                 text_pos) < 0) {
92             return -1;
93         }
94     }
95
96     return 0;
97 }
98
99 void platforms_touches_rect_sides(const Platforms *platforms,
100                                   Rect object,
101                                   int sides[RECT_SIDE_N])
102 {
103     trace_assert(platforms);
104
105     for (size_t i = 0; i < platforms->rects_size; ++i) {
106         rect_object_impact(object, platforms->rects[i], sides);
107     }
108 }
109
110 Vec2f platforms_snap_rect(const Platforms *platforms,
111                          Rect *object)
112 {
113     trace_assert(platforms);
114
115     Vec2f result = vec(1.0f, 1.0f);
116     for (size_t i = 0; i < platforms->rects_size; ++i) {
117         if (rects_overlap(platforms->rects[i], *object)) {
118             // TODO(#1161): can we reuse the Level Editor snapping mechanism in physics snapping
119             result = vec_entry_mult(result, rect_snap(platforms->rects[i], object));
120         }
121     }
122
123     return result;
124 }