]> git.lizzy.rs Git - nothing.git/blob - src/game/level/platforms.c
55b98682b6f4b191e78a448f9a1f5257adadeb11
[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/line_stream.h"
11 #include "system/nth_alloc.h"
12 #include "system/log.h"
13 #include "game/level/level_editor/rect_layer.h"
14
15 struct Platforms {
16     Lt *lt;
17
18     Rect *rects;
19     Color *colors;
20     size_t rects_size;
21 };
22
23 Platforms *create_platforms_from_rect_layer(const RectLayer *layer)
24 {
25     trace_assert(layer);
26
27     Lt *lt = create_lt();
28
29     Platforms *platforms = PUSH_LT(
30         lt,
31         nth_calloc(1, sizeof(Platforms)),
32         free);
33     if (platforms == NULL) {
34         RETURN_LT(lt, NULL);
35     }
36     platforms->lt = lt;
37
38     platforms->rects_size = rect_layer_count(layer);
39
40     platforms->rects = PUSH_LT(lt, nth_calloc(1, sizeof(Rect) * platforms->rects_size), free);
41     if (platforms->rects == NULL) {
42         RETURN_LT(lt, NULL);
43     }
44     memcpy(platforms->rects, rect_layer_rects(layer), sizeof(Rect) * platforms->rects_size);
45
46
47     platforms->colors = PUSH_LT(lt, nth_calloc(1, sizeof(Color) * platforms->rects_size), free);
48     if (platforms->colors == NULL) {
49         RETURN_LT(lt, NULL);
50     }
51     memcpy(platforms->colors, rect_layer_colors(layer), sizeof(Color) * platforms->rects_size);
52
53     return platforms;
54 }
55
56 void destroy_platforms(Platforms *platforms)
57 {
58     trace_assert(platforms);
59     RETURN_LT0(platforms->lt);
60 }
61
62 /* TODO(#450): platforms do not render their ids in debug mode */
63 int platforms_render(const Platforms *platforms,
64                      const Camera *camera)
65 {
66     for (size_t i = 0; i < platforms->rects_size; ++i) {
67         if (camera_fill_rect(
68                 camera,
69                 platforms->rects[i],
70                 platforms->colors[i]) < 0) {
71             return -1;
72         }
73     }
74
75     return 0;
76 }
77
78 void platforms_touches_rect_sides(const Platforms *platforms,
79                                   Rect object,
80                                   int sides[RECT_SIDE_N])
81 {
82     trace_assert(platforms);
83
84     for (size_t i = 0; i < platforms->rects_size; ++i) {
85         rect_object_impact(object, platforms->rects[i], sides);
86     }
87 }
88
89 Vec2f platforms_snap_rect(const Platforms *platforms,
90                          Rect *object)
91 {
92     trace_assert(platforms);
93
94     Vec2f result = vec(1.0f, 1.0f);
95     for (size_t i = 0; i < platforms->rects_size; ++i) {
96         if (rects_overlap(platforms->rects[i], *object)) {
97             // TODO(#1161): can we reuse the Level Editor snapping mechanism in physics snapping
98             result = vec_entry_mult(result, rect_snap(platforms->rects[i], object));
99         }
100     }
101
102     return result;
103 }