Mirai's Miscellaneous Misadventures
M32 / core / sprites.c
1
2
3
4#include <mimimi/sprites.h>
5#include <mimimi/compound-behaviors.h>
6#include <mimimi/allocators.h>
7#include <mimimi/geometry.h>
8#include <mimimi/ground.h>
9#include <mimimi/behaviors.h>
10
11struct mimimi_physics_data
12{
13 struct mimimi_physics *physics;
14 struct mimimi_ground *ground;
15 struct mimimi_position *position;
16};
17
18#include "physics.c"
19
20static void mimimi_physics_behave(void *data)
21{
22 struct mimimi_physics_data *physics_data = data;
23 struct mimimi_physics *physics = physics_data->physics;
24
25 if (physics->airborne == 0)
26 mimimi_ground_physics(data);
27 else
28 mimimi_airborne_physics(data);
29}
30
31struct mimimi_behavior *mimimi_physics(struct mimimi_physics *physics, struct mimimi_position *position, struct mimimi_ground *ground, struct mimimi_allocator *allocator)
32{
33 physics->dx = 0;
34 physics->dy = 0;
35 physics->airborne = 1;
36 physics->width = 0;
37 physics->height = 0;
38 physics->gravity = 3;
39
40 struct mimimi_behavior *compound = mimimi_compound_behavior(allocator);
41 struct mimimi_physics_data *data = mimimi_compound_allocate(compound, sizeof *data, allocator);
42 mimimi_compound(compound, mimimi_function(data, &mimimi_physics_behave, allocator));
43
44 data->physics = physics;
45 data->ground = ground;
46 data->position = position;
47
48 return compound;
49}
50
51static void mimimi_live(void *data)
52{
53 struct mimimi_life *life = data;
54
55 if (life->knocked_time != 0)
56 {
57 life->knocked_time--;
58 life->immunity_time = life->recovery_time;
59 }
60
61 if (life->immunity_time != 0)
62 {
63 life->pristinity = life->max_pristinity;
64 life->immunity_time--;
65 }
66
67 if (life->pristinity < life->max_pristinity)
68 life->pristinity++;
69}
70
71struct mimimi_behavior *mimimi_life(struct mimimi_life *life, struct mimimi_allocator *allocator)
72{
73 life->knocked_time = 0;
74 life->immunity_time = 0;
75 life->pristinity = 256;
76 life->max_pristinity = 256;
77 life->recovery_time = 64;
78
79 return mimimi_function(life, &mimimi_live, allocator);
80}
81
82struct mimimi_fall_data
83{
84 struct mimimi_fall *fall;
85 struct mimimi_physics *physics;
86 struct mimimi_life *life;
87};
88
89static void mimimi_fall_behave(void *data)
90{
91 struct mimimi_fall_data *fall_data = data;
92
93 if (fall_data->physics->dy > fall_data->fall->max_speed)
94 if (fall_data->life->knocked_time < fall_data->fall->knocked_time)
95 fall_data->life->knocked_time = fall_data->fall->knocked_time;
96}
97
98struct mimimi_behavior *mimimi_fall(struct mimimi_fall *fall, struct mimimi_physics *physics, struct mimimi_life *life, struct mimimi_allocator *allocator)
99{
100 fall->max_speed = 128;
101 fall->knocked_time = 64;
102
103 struct mimimi_behavior *compound = mimimi_compound_behavior(allocator);
104 struct mimimi_fall_data *data = mimimi_compound_allocate(compound, sizeof *data, allocator);
105 mimimi_compound(compound, mimimi_function(data, &mimimi_fall_behave, allocator));
106
107 data->fall = fall;
108 data->physics = physics;
109 data->life = life;
110
111 return compound;
112}
113
114struct mimimi_walk_data
115{
116 struct mimimi_walk *walk;
117 struct mimimi_physics *physics;
118};
119
120static void mimimi_walk_behave(void *data)
121{
122 struct mimimi_walk_data *walk_data = data;
123 struct mimimi_walk *walk = walk_data->walk;
124 struct mimimi_physics *physics = walk_data->physics;
125
126 if (walk->direction != 0)
127 {
128 int ax;
129 if (walk_data->physics->airborne)
130 ax = walk->airborne_speed;
131 else
132 ax = walk->ground_speed;
133
134 if (walk->direction == 1)
135 physics->dx -= ax;
136 if (walk->direction == 2)
137 physics->dx += ax;
138 }
139}
140
141struct mimimi_behavior *mimimi_walk(struct mimimi_walk *walk, struct mimimi_physics *physics, struct mimimi_allocator *allocator)
142{
143 walk->ground_speed = 6;
144 walk->airborne_speed = 3;
145 walk->direction = 0;
146
147 struct mimimi_behavior *compound = mimimi_compound_behavior(allocator);
148 struct mimimi_walk_data *data = mimimi_compound_allocate(compound, sizeof *data, allocator);
149 mimimi_compound(compound, mimimi_function(data, &mimimi_walk_behave, allocator));
150
151 data->walk = walk;
152 data->physics = physics;
153
154 return compound;
155}
156
157struct mimimi_sprite_data
158{
159 struct mimimi_behavior *walk_behavior;
160 struct mimimi_sprite *sprite;
161};
162
163static void mimimi_sprite_behave(void *data0)
164{
165 struct mimimi_sprite_data *data = data0;
166 struct mimimi_sprite *sprite = data->sprite;
167 struct mimimi_behavior *walk_behavior = data->walk_behavior;
168
169 if (sprite->life->knocked_time == 0)
170 sprite->awake = 1,
171 (*walk_behavior->behave)(walk_behavior->data);
172 else
173 sprite->awake = 0;
174}
175
176struct mimimi_sprite *mimimi_sprite(struct mimimi_ground *ground, int x, int y, int width, int height, struct mimimi_allocator *allocator)
177{
178 struct mimimi_behavior *compound = mimimi_compound_behavior(allocator);
179
180 struct mimimi_position *position = mimimi_compound_allocate(compound, sizeof *position, allocator);
181
182 struct mimimi_physics *physics = mimimi_compound_allocate(compound, sizeof *physics, allocator);
183 struct mimimi_behavior *physics_behavior = mimimi_physics(physics,position, ground, allocator);
184
185 struct mimimi_life *life = mimimi_compound_allocate(compound, sizeof *life, allocator);
186 struct mimimi_behavior *life_behavior = mimimi_life(life,allocator);
187
188 struct mimimi_fall *fall = mimimi_compound_allocate(compound, sizeof *fall, allocator);
189 struct mimimi_behavior *fall_behavior = mimimi_fall(fall, physics, life, allocator);
190
191 struct mimimi_walk *walk = mimimi_compound_allocate(compound, sizeof *walk, allocator);
192 struct mimimi_behavior *walk_behavior = mimimi_walk(walk, physics, allocator);
193 mimimi_compound(compound, mimimi_finalizer(walk_behavior->data, walk_behavior->finish, allocator));
194
195 struct mimimi_sprite *sprite = mimimi_compound_allocate(compound, sizeof *sprite, allocator);
196 struct mimimi_sprite_data *sprite_data = mimimi_compound_allocate(compound, sizeof *sprite_data, allocator);
197 sprite->awake = 1;
198
199 struct mimimi_behavior *sprite_behavior = mimimi_function(sprite_data, &mimimi_sprite_behave, allocator);
200
201 position->x = x;
202 position->y = y;
203
204 physics->width = width;
205 physics->height = height;
206
207 sprite_data->walk_behavior = walk_behavior;
208 sprite_data->sprite = sprite;
209
210 sprite->position = position;
211 sprite->physics = physics;
212 sprite->life = life;
213 sprite->fall = fall;
214 sprite->walk = walk;
215 sprite->behavior = compound;
216
217 mimimi_compound(compound, sprite_behavior);
218 mimimi_compound(compound, physics_behavior);
219 mimimi_compound(compound, life_behavior);
220 mimimi_compound(compound, fall_behavior);
221
222 return sprite;
223}