]> git.lizzy.rs Git - nothing.git/blob - src/level.c
Remove the wave state (#90)
[nothing.git] / src / level.c
1 #include <assert.h>
2 #include <SDL2/SDL.h>
3
4 #include "./lt.h"
5 #include "./player.h"
6 #include "./platforms.h"
7 #include "./level.h"
8 #include "./camera.h"
9 #include "./error.h"
10 #include "./goals.h"
11
12 struct level_t
13 {
14     lt_t *lt;
15     player_t *player;
16     platforms_t *platforms;
17     camera_t *camera;
18     goals_t *goals;
19 };
20
21 level_t *create_level_from_file(const char *file_name)
22 {
23     assert(file_name);
24
25     lt_t *const lt = create_lt();
26     if (lt == NULL) {
27         return NULL;
28     }
29
30     level_t *const level = PUSH_LT(lt, malloc(sizeof(level_t)), free);
31     if (level == NULL) {
32         throw_error(ERROR_TYPE_LIBC);
33         RETURN_LT(lt, NULL);
34     }
35
36     FILE *level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose);
37     if (level_file == NULL) {
38         throw_error(ERROR_TYPE_LIBC);
39         RETURN_LT(lt, NULL);
40     }
41
42     level->player = PUSH_LT(lt, create_player_from_stream(level_file), destroy_player);
43     if (level->player == NULL) {
44         RETURN_LT(lt, NULL);
45     }
46
47     level->platforms = PUSH_LT(lt, create_platforms_from_stream(level_file), destroy_platforms);
48     if (level->platforms == NULL) {
49         RETURN_LT(lt, NULL);
50     }
51
52     level->goals = PUSH_LT(lt, create_goals_from_stream(level_file), destroy_goals);
53     if (level->goals == NULL) {
54         RETURN_LT(lt, NULL);
55     }
56
57     level->camera = PUSH_LT(lt, create_camera(vec(0.0f, 0.0f)), destroy_camera);
58     if (level->camera == NULL) {
59         RETURN_LT(lt, NULL);
60     }
61
62     level->lt = lt;
63
64     fclose(RELEASE_LT(lt, level_file));
65
66     return level;
67 }
68
69 void destroy_level(level_t *level)
70 {
71     assert(level);
72     RETURN_LT0(level->lt);
73 }
74
75 int level_render(const level_t *level, SDL_Renderer *renderer)
76 {
77     assert(level);
78     assert(renderer);
79
80     if (player_render(level->player, renderer, level->camera) < 0) {
81         return -1;
82     }
83
84     if (platforms_render(level->platforms, renderer, level->camera) < 0) {
85         return -1;
86     }
87
88     if (goals_render(level->goals, renderer, level->camera) < 0) {
89         return -1;
90     }
91
92     return 0;
93 }
94
95 int level_update(level_t *level, Uint32 delta_time)
96 {
97     assert(level);
98     assert(delta_time > 0);
99
100     player_update(level->player, level->platforms, delta_time);
101     goals_update(level->goals, delta_time);
102     player_focus_camera(level->player, level->camera);
103     player_hide_goals(level->player, level->goals);
104
105     return 0;
106 }
107
108 int level_event(level_t *level, const SDL_Event *event)
109 {
110     assert(level);
111     assert(event);
112
113     switch (event->type) {
114     case SDL_KEYDOWN:
115         switch (event->key.keysym.sym) {
116         case SDLK_SPACE:
117             player_jump(level->player);
118             break;
119         }
120         break;
121
122     case SDL_JOYBUTTONDOWN:
123         if (event->jbutton.button == 1) {
124             player_jump(level->player);
125         }
126         break;
127     }
128
129     return 0;
130 }
131
132 int level_input(level_t *level,
133                 const Uint8 *const keyboard_state,
134                 SDL_Joystick *the_stick_of_joy)
135 {
136     assert(level);
137     assert(keyboard_state);
138     (void) the_stick_of_joy;
139
140     if (keyboard_state[SDL_SCANCODE_A]) {
141         player_move_left(level->player);
142     } else if (keyboard_state[SDL_SCANCODE_D]) {
143         player_move_right(level->player);
144     } else if (the_stick_of_joy && SDL_JoystickGetAxis(the_stick_of_joy, 0) < 0) {
145         player_move_left(level->player);
146     } else if (the_stick_of_joy && SDL_JoystickGetAxis(the_stick_of_joy, 0) > 0) {
147         player_move_right(level->player);
148     } else {
149         player_stop(level->player);
150     }
151
152     return 0;
153 }
154
155 void level_toggle_debug_mode(level_t *level)
156 {
157     camera_toggle_debug_mode(level->camera);
158 }
159
160 int level_reload_preserve_player(level_t *level, const char *file_name)
161 {
162     lt_t *lt = create_lt();
163     if (lt == NULL) {
164         return -1;
165     }
166
167     FILE *level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose);
168     if (level_file == NULL) {
169         throw_error(ERROR_TYPE_LIBC);
170         RETURN_LT(lt, -1);
171     }
172
173     player_t *skipped_player = create_player_from_stream(level_file);
174     if (skipped_player == NULL) {
175         RETURN_LT(lt, -1);
176     }
177     destroy_player(skipped_player);
178
179     platforms_t *platforms = create_platforms_from_stream(level_file);
180     if (platforms == NULL) {
181         RETURN_LT(lt, -1);
182     }
183     level->platforms = RESET_LT(level->lt, level->platforms, platforms);
184
185     goals_t *goals = create_goals_from_stream(level_file);
186     if (goals == NULL) {
187         RETURN_LT(lt, -1);
188     }
189     level->goals = RESET_LT(level->lt, level->goals, goals);
190
191     RETURN_LT(lt, 0);
192 }