]> git.lizzy.rs Git - nothing.git/blob - src/platforms.c
Rename goal -> goals (#58)
[nothing.git] / src / platforms.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <string.h>
5
6 #include <SDL2/SDL.h>
7
8 #include "./platforms.h"
9 #include "./error.h"
10 #include "./lt.h"
11
12 struct platforms_t {
13     lt_t *lt;
14
15     rect_t *rects;
16     size_t rects_size;
17 };
18
19 platforms_t *create_platforms(const rect_t *rects, size_t rects_size)
20 {
21     assert(rects);
22     assert(rects_size > 0);
23
24     lt_t *const lt = create_lt();
25     if (lt == NULL) {
26         return NULL;
27     }
28
29     platforms_t *platforms = PUSH_LT(lt, malloc(sizeof(platforms_t)), free);
30     if (platforms == NULL) {
31         throw_error(ERROR_TYPE_LIBC);
32         RETURN_LT(lt, NULL);
33     }
34
35     platforms->rects = PUSH_LT(lt, malloc(sizeof(rect_t) * rects_size), free);
36     if (platforms->rects == NULL) {
37         throw_error(ERROR_TYPE_LIBC);
38         RETURN_LT(lt, NULL);
39     }
40
41     platforms->rects = memcpy(platforms->rects, rects, sizeof(rect_t) * rects_size);
42     platforms->rects_size = rects_size;
43     platforms->lt = lt;
44
45     return platforms;
46 }
47
48 platforms_t *create_platforms_from_stream(FILE *stream)
49 {
50     assert(stream);
51
52     lt_t *const lt = create_lt();
53     if (lt == NULL) {
54         return NULL;
55     }
56
57     platforms_t *platforms = PUSH_LT(lt, malloc(sizeof(platforms_t)), free);
58     if (platforms == NULL) {
59         throw_error(ERROR_TYPE_LIBC);
60         RETURN_LT(lt, NULL);
61     }
62
63     platforms->rects_size = 0;
64     if (fscanf(stream, "%lu", &platforms->rects_size) == EOF) {
65         throw_error(ERROR_TYPE_LIBC);
66         RETURN_LT(lt, NULL);
67     }
68
69     platforms->rects = PUSH_LT(lt, malloc(sizeof(rect_t) * platforms->rects_size), free);
70     if (platforms->rects == NULL) {
71         throw_error(ERROR_TYPE_LIBC);
72         RETURN_LT(lt, NULL);
73     }
74
75     for (size_t i = 0; i < platforms->rects_size; ++i) {
76         if (fscanf(stream, "%f%f%f%f\n",
77                    &platforms->rects[i].x, &platforms->rects[i].y,
78                    &platforms->rects[i].w, &platforms->rects[i].h) < 0) {
79             throw_error(ERROR_TYPE_LIBC);
80             RETURN_LT(lt, NULL);
81         }
82     }
83
84     platforms->lt = lt;
85
86     return platforms;
87 }
88
89 platforms_t *create_platforms_from_file(const char *filename)
90 {
91     assert(filename);
92
93     FILE *platforms_file = fopen(filename, "r");
94     if (platforms_file == NULL) {
95         throw_error(ERROR_TYPE_LIBC);
96         return NULL;
97     }
98
99     platforms_t *platforms = create_platforms_from_stream(platforms_file);
100     if (platforms != NULL) {
101         fclose(platforms_file);
102         return NULL;
103     }
104
105     fclose(platforms_file);
106     return platforms;
107 }
108
109 void destroy_platforms(platforms_t *platforms)
110 {
111     assert(platforms);
112     RETURN_LT0(platforms->lt);
113 }
114
115 int save_platforms_to_file(const platforms_t *platforms,
116                            const char *filename)
117 {
118     assert(platforms);
119     assert(filename);
120
121     lt_t *const lt = create_lt();
122     if (lt == NULL) {
123         return -1;
124     }
125
126     FILE *platforms_file = PUSH_LT(lt, fopen(filename, "w"), fclose);
127
128     if (platforms_file == NULL) {
129         throw_error(ERROR_TYPE_LIBC);
130         RETURN_LT(lt, -1);
131     }
132
133     for (size_t i = 0; i < platforms->rects_size; ++i) {
134         if (fprintf(platforms_file, "%f %f %f %f\n",
135                     platforms->rects[i].x, platforms->rects[i].y,
136                     platforms->rects[i].w, platforms->rects[i].h) < 0) {
137             throw_error(ERROR_TYPE_LIBC);
138             RETURN_LT(lt, -1);
139         }
140     }
141
142     RETURN_LT(lt, 0);
143 }
144
145 int render_platforms(const platforms_t *platforms,
146                      SDL_Renderer *renderer,
147                      const camera_t *camera)
148 {
149     if (SDL_SetRenderDrawColor(renderer, 255, 96, 96, 255) < 0) {
150         throw_error(ERROR_TYPE_SDL2);
151         return -1;
152     }
153
154     for (size_t i = 0; i < platforms->rects_size; ++i) {
155         if (camera_fill_rect(camera, renderer, &platforms->rects[i]) < 0) {
156             throw_error(ERROR_TYPE_SDL2);
157             return -1;
158         }
159     }
160
161     return 0;
162 }
163
164 void platforms_rect_object_collide(const platforms_t *platforms,
165                                    rect_t object,
166                                    int sides[RECT_SIDE_N])
167 {
168     assert(platforms);
169
170     memset(sides, 0, sizeof(int) * RECT_SIDE_N);
171
172     for (size_t i = 0; i < platforms->rects_size; ++i) {
173         rect_object_impact(&object, &platforms->rects[i], sides);
174     }
175 }