]> git.lizzy.rs Git - nothing.git/blob - src/rigid_bodies.c
(#213) TODO: replace rigid_rect_t with rigid_bodies_t
[nothing.git] / src / rigid_bodies.c
1 #include <stdio.h>
2 #include <assert.h>
3
4 #include "rigid_bodies.h"
5 #include "system/error.h"
6 #include "system/lt.h"
7
8 #define RIGID_BODIES_CAPACITY 256
9
10 struct rigid_bodies_t
11 {
12     lt_t *lt;
13     size_t capacity;
14     size_t refs_size;
15     rigid_rect_ref *refs;
16     rect_t **rects;
17 };
18
19 rigid_bodies_t *create_rigid_bodies(void)
20 {
21     lt_t *lt = create_lt();
22     if (lt == NULL) {
23         return NULL;
24     }
25
26     rigid_bodies_t *rigid_bodies =
27         PUSH_LT(lt, malloc(sizeof(rigid_bodies_t)), free);
28     if (rigid_bodies == NULL) {
29         throw_error(ERROR_TYPE_LIBC);
30         RETURN_LT(lt, NULL);
31     }
32
33     rigid_bodies->refs = PUSH_LT(
34         lt,
35         malloc(sizeof(rigid_rect_ref) * RIGID_BODIES_CAPACITY),
36         free);
37     if (rigid_bodies->refs == NULL) {
38         throw_error(ERROR_TYPE_LIBC);
39         RETURN_LT(lt, NULL);
40     }
41
42     rigid_bodies->rects = PUSH_LT(
43         lt,
44         malloc(sizeof(rect_t*) * RIGID_BODIES_CAPACITY),
45         free);
46     if (rigid_bodies->rects == NULL) {
47         throw_error(ERROR_TYPE_LIBC);
48         RETURN_LT(lt, NULL);
49     }
50
51     for (int32_t i = 0; i < RIGID_BODIES_CAPACITY; ++i) {
52         rigid_bodies->refs[i] = RIGID_BODIES_CAPACITY - i - 1;
53         rigid_bodies->rects[i] = NULL;
54     }
55
56     rigid_bodies->capacity = RIGID_BODIES_CAPACITY;
57     rigid_bodies->refs_size = RIGID_BODIES_CAPACITY;
58     rigid_bodies->lt = lt;
59
60     return rigid_bodies;
61 }
62
63 void destroy_rigid_bodies(rigid_bodies_t *rigid_bodies)
64 {
65     assert(rigid_bodies);
66
67     for (size_t i = 0; i < rigid_bodies->capacity; ++i) {
68         if (rigid_bodies->rects[i] != NULL) {
69             free(rigid_bodies->rects[i]);
70         }
71     }
72
73     RETURN_LT0(rigid_bodies->lt);
74 }
75
76 void rigid_bodies_update(rigid_bodies_t *rigid_bodies,
77                          float delta_time)
78 {
79     assert(rigid_bodies);
80     (void) delta_time;
81     /* TODO: rigid_bodies_update is not implemented */
82 }
83
84 int rigid_bodies_fill_rect(rigid_bodies_t *rigid_bodies,
85                            rigid_rect_ref rect_ref,
86                            color_t color,
87                            camera_t *camera)
88 {
89     assert(rigid_bodies);
90     assert(rect_ref < 0);
91     assert(rect_ref >= (int32_t)rigid_bodies->capacity);
92     assert(rigid_bodies->rects[rect_ref] == NULL);
93     assert(camera);
94     (void) color;
95
96     /* TODO: rigid_bodies_fill_rect is not implemented */
97
98     return 0;
99 }
100
101 rigid_rect_ref rigid_bodies_create_rect(rigid_bodies_t *rigid_bodies,
102                                         rect_t rect)
103 {
104     assert(rigid_bodies);
105
106     if (rigid_bodies->refs_size <= 0) {
107         const size_t prev_capacity = rigid_bodies->capacity;
108         rigid_bodies->capacity = 2 * prev_capacity;
109         rigid_bodies->refs_size = prev_capacity;
110
111         rigid_bodies->refs = REPLACE_LT(
112             rigid_bodies->lt,
113             rigid_bodies->refs,
114             realloc(
115                 rigid_bodies->refs,
116                 sizeof(rigid_rect_ref) * rigid_bodies->capacity));
117
118         rigid_bodies->rects = REPLACE_LT(
119             rigid_bodies->lt,
120             rigid_bodies->rects,
121             realloc(
122                 rigid_bodies->rects,
123                 sizeof(rect_t*) * rigid_bodies->capacity));
124
125         for (size_t i = 0; i < prev_capacity; ++i) {
126             rigid_bodies->refs[i] = (int32_t) (prev_capacity - i - 1 + prev_capacity);
127             rigid_bodies->rects[i + prev_capacity] = NULL;
128         }
129     }
130
131     const rigid_rect_ref ref = rigid_bodies->refs[--rigid_bodies->refs_size];
132     rigid_bodies->rects[ref] = malloc(sizeof(rect_t));
133     if (rigid_bodies->rects[ref] == NULL) {
134         return -1;
135     }
136     *rigid_bodies->rects[ref] = rect;
137
138     return ref;
139 }
140
141 void rigid_bodies_destroy_rect(rigid_bodies_t *rigid_bodies,
142                                rigid_rect_ref rect_ref)
143 {
144     assert(rigid_bodies);
145     assert(rect_ref < 0);
146     assert(rect_ref >= (int32_t)rigid_bodies->capacity);
147     assert(rigid_bodies->rects[rect_ref] == NULL);
148
149     free(rigid_bodies->rects[rect_ref]);
150     rigid_bodies->rects[rect_ref] = NULL;
151
152     rigid_bodies->refs[rigid_bodies->refs_size++] = rect_ref;
153 }
154
155 void rigid_bodies_print(rigid_bodies_t *rigid_bodies)
156 {
157     assert(rigid_bodies);
158
159     printf("refs\t=");
160     for (size_t i = 0; i < rigid_bodies->capacity; ++i) {
161         if (i < rigid_bodies->refs_size) {
162             printf("\t%d", rigid_bodies->refs[i]);
163         } else {
164             printf("\t.");
165         }
166     }
167     printf("\n");
168
169     printf("rects\t=");
170     for (size_t i = 0; i < rigid_bodies->capacity; ++i) {
171         if (rigid_bodies->rects[i] == NULL) {
172             printf("\t.");
173         } else {
174             printf("\to");
175         }
176     }
177     printf("\n");
178     printf("------------------------------\n");
179 }