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