Mirai's Miscellaneous Misadventures
M52 / core / effects.c
1
2
3
4#include <stdlib.h>
5#include "../mimimi.h"
6
7void mimimi_conveyor_tick(struct mimimi_conveyor *conveyor)
8{
9 struct mimimi_sprite *sprite;
10 struct mimimi_ground *ground;
11 unsigned char was_airborne;
12 int x1, x2, y;
13
14 sprite = conveyor->sprite;
15 ground = conveyor->ground;
16 was_airborne = conveyor->was_airborne;
17
18 conveyor->was_airborne = sprite->physics.airborne;
19
20 if (sprite->physics.airborne != 0)
21 {
22 if (was_airborne == 0)
23 sprite->physics.dx += conveyor->speed;
24 return;
25 }
26
27 x1 = (sprite->position.x - sprite->physics.width / 2) / 128;
28 x2 = (sprite->position.x + sprite->physics.width / 2) / 128;
29 y = (sprite->position.y + 64) / 128;
30
31 if (mimimi_ground_tile(ground, x1, y) != 0 || mimimi_ground_tile(ground, x2, y) != 0)
32 sprite->position.x += conveyor->speed;
33}
34
35void mimimi_positioned_physics_tick(struct mimimi_positioned_physics *physics, struct mimimi_ground *ground)
36{
37 int dx, dy;
38 unsigned char was_airborne;
39 struct mimimi_position other_position;
40 unsigned char airborne;
41
42 dx = physics->transform.x - physics->previous.x;
43 dy = physics->transform.y - physics->previous.y;
44
45 physics->previous = physics->transform;
46
47 was_airborne = physics->was_airborne;
48 physics->was_airborne = physics->other.airborne;
49
50 airborne = physics->physics->airborne;
51
52 physics->other.dx = physics->physics->dx;
53 physics->other.dy = physics->physics->dy;
54 physics->other.width = physics->physics->width;
55 physics->other.height = physics->physics->height;
56
57 other_position = *physics->position;
58 other_position.x -= physics->transform.x;
59 other_position.y -= physics->transform.y;
60
61 if (physics->other.airborne == 0)
62 {
63 other_position.x += dx;
64 other_position.y += dy;
65 }
66
67 if (physics->physics->airborne != 0) physics->other.airborne = 1;
68 mimimi_collision_physics_tick(&physics->other, &other_position, ground);
69 if (physics->other.airborne == 0) physics->physics->airborne = 0;
70
71 if (airborne == 0) return;
72
73 other_position.x += physics->transform.x;
74 other_position.y += physics->transform.y;
75
76 *physics->position = other_position;
77
78 physics->physics->dx = physics->other.dx;
79 physics->physics->dy = physics->other.dy;
80
81 if (physics->other.airborne != 0 && was_airborne == 0)
82 {
83
84
85 }
86}
87
88void mimimi_positioned_physics(struct mimimi_positioned_physics *physics, struct mimimi_physics *other, struct mimimi_position *position)
89{
90 mimimi_physics(&physics->other, 0, 0);
91 physics->physics = other;
92 physics->position = position;
93 physics->transform.x = 0;
94 physics->transform.y = 0;
95 physics->previous = *position;
96 physics->was_airborne = other->airborne;
97}
98
99void mimimi_trampoline_tick(struct mimimi_trampoline *trampoline)
100{
101 struct mimimi_sprite *sprite;
102 struct mimimi_ground *ground;
103 int dy;
104 int x1, x2, y;
105
106 sprite = trampoline->sprite;
107 ground = trampoline->ground;
108
109 dy = trampoline->dy;
110 trampoline->dy = 0;
111
112 if (sprite->physics.airborne != 0)
113 {
114 trampoline->dy = sprite->physics.dy;
115 return;
116 }
117
118 if (dy == 0) return;
119
120 x1 = (sprite->position.x - sprite->physics.width / 2) / 128;
121 x2 = (sprite->position.x + sprite->physics.width / 2) / 128;
122 y = (sprite->position.y + 64) / 128;
123
124 if (mimimi_ground_tile(ground, x1, y) != 0) return;
125 if (mimimi_ground_tile(ground, x2, y) != 0) return;
126
127 sprite->physics.airborne = 1;
128 sprite->physics.dy -= dy * trampoline->restitution / 256;
129}
130
131void mimimi_platform_display_tick(struct mimimi_platform *platform, struct mimimi_position *camera, struct mimimi_image *image)
132{
133 mimimi_camera_stamp(image, camera, platform->physics.transform.x, platform->physics.transform.y, 0, platform->image);
134}
135
136struct mimimi_platform_set *mimimi_add_platform_set(struct mimimi_stage *stage)
137{
138 int i;
139 struct mimimi_platform_set *platforms;
140
141 if (stage->platform_set_count == 0)
142 stage->platform_sets = NULL;
143
144 i = stage->platform_set_count++;
145 stage->platform_sets = realloc(stage->platform_sets, sizeof *stage->platform_sets * stage->platform_set_count);
146 if (stage->platform_sets == NULL) exit(1);
147
148 platforms = stage->platform_sets + i;
149
150 platforms->angular_platform_count = 0;
151 platforms->linear_platform_count = 0;
152 platforms->momentum.x = 0;
153 platforms->momentum.dx = 0;
154 platforms->balance = 0;
155 platforms->strength = 0;
156 platforms->linear_weight = 1024;
157 platforms->angular_weight = 1024;
158 platforms->min = -0x10000000;
159 platforms->max = 0x10000000;
160
161 return platforms;
162}
163
164void mimimi_spawn_linear_platform(struct mimimi_stage *stage, struct mimimi_platform_set *platforms, struct mimimi_ground *ground, struct mimimi_image *image, int x, int y, int scale)
165{
166 int i;
167
168 if (platforms->linear_platform_count == 0)
169 {
170 platforms->linear_platforms = NULL;
171 platforms->linear_motions = NULL;
172 }
173
174 i = platforms->linear_platform_count++;
175 platforms->linear_platforms = realloc(platforms->linear_platforms, sizeof *platforms->linear_platforms * platforms->linear_platform_count);
176 platforms->linear_motions = realloc(platforms->linear_motions, sizeof *platforms->linear_motions * platforms->linear_platform_count);
177
178 if (platforms->linear_platforms == NULL) exit(1);
179 if (platforms->linear_motions == NULL) exit(1);
180
181 mimimi_positioned_physics(&platforms->linear_platforms[i].physics, &stage->sprites[0].physics, &stage->sprites[0].position);
182 platforms->linear_platforms[i].ground = ground;
183 platforms->linear_platforms[i].image = image;
184
185 platforms->linear_platforms[i].physics.transform.x = x;
186 mimimi_linear_motion(platforms->linear_motions + i, &platforms->linear_platforms[i].physics.transform.y, y, scale);
187 mimimi_linear_motion_apply(platforms->linear_motions + i, &platforms->momentum);
188
189 for (i = 0 ; i < platforms->linear_platform_count ; i++)
190 platforms->linear_motions[i].value = &platforms->linear_platforms[i].physics.transform.y;
191}
192
193void mimimi_spawn_angular_platform(struct mimimi_stage *stage, struct mimimi_platform_set *platforms, struct mimimi_ground *ground, struct mimimi_image *image, int x, int y, int a, int scale, int height)
194{
195 int i;
196
197 if (platforms->angular_platform_count == 0)
198 {
199 platforms->angular_platforms = NULL;
200 platforms->angular_motions = NULL;
201 }
202
203 i = platforms->angular_platform_count++;
204 platforms->angular_platforms = realloc(platforms->angular_platforms, sizeof *platforms->angular_platforms * platforms->angular_platform_count);
205 platforms->angular_motions = realloc(platforms->angular_motions, sizeof *platforms->angular_motions * platforms->angular_platform_count);
206
207 if (platforms->angular_platforms == NULL) exit(1);
208 if (platforms->angular_motions == NULL) exit(1);
209
210 mimimi_positioned_physics(&platforms->angular_platforms[i].physics, &stage->sprites[0].physics, &stage->sprites[0].position);
211 platforms->angular_platforms[i].ground = ground;
212 platforms->angular_platforms[i].image = image;
213
214 mimimi_angular_motion(platforms->angular_motions + i, &platforms->angular_platforms[i].physics.transform, x, y, a, scale, height);
215 mimimi_angular_motion_apply(platforms->angular_motions + i, &platforms->momentum);
216
217 for (i = 0 ; i < platforms->angular_platform_count ; i++)
218 platforms->angular_motions[i].value = &platforms->angular_platforms[i].physics.transform;
219}
220
221static void mimimi_platforms_propagate(struct mimimi_platform_set *platforms)
222{
223 int i;
224 for (i = 0 ; i < platforms->linear_platform_count ; i++)
225 if (platforms->linear_platforms[i].physics.other.airborne == 0)
226 mimimi_linear_motion_propagate(platforms->linear_motions + i, &platforms->momentum);
227 for (i = 0 ; i < platforms->angular_platform_count ; i++)
228 if (platforms->angular_platforms[i].physics.other.airborne == 0)
229 mimimi_angular_motion_propagate(platforms->angular_motions + i, &platforms->momentum);
230}
231
232static void mimimi_platforms_apply(struct mimimi_platform_set *platforms)
233{
234 int i;
235 for (i = 0 ; i < platforms->linear_platform_count ; i++)
236 mimimi_linear_motion_apply(platforms->linear_motions + i, &platforms->momentum);
237 for (i = 0 ; i < platforms->angular_platform_count ; i++)
238 mimimi_angular_motion_apply(platforms->angular_motions + i, &platforms->momentum);
239}
240
241void mimimi_platform_set_tick(struct mimimi_platform_set *platforms)
242{
243 int i;
244 int diff;
245
246 for (i = 0 ; i < platforms->linear_platform_count ; i++)
247 if (platforms->linear_platforms[i].physics.other.airborne == 0)
248 platforms->linear_platforms[i].physics.transform.y += platforms->linear_weight;
249
250 for (i = 0 ; i < platforms->angular_platform_count ; i++)
251 if (platforms->angular_platforms[i].physics.other.airborne == 0)
252 platforms->angular_platforms[i].physics.transform.y += platforms->angular_weight * platforms->angular_motions[i].height / 2048;
253
254 mimimi_platforms_propagate(platforms);
255
256 platforms->momentum.dx *= 31;
257 platforms->momentum.dx /= 32;
258 platforms->momentum.x += platforms->momentum.dx / 256;
259
260 if (platforms->momentum.x < platforms->min)
261 {
262 platforms->momentum.x = platforms->min;
263 platforms->momentum.dx = 0;
264 }
265 if (platforms->momentum.x > platforms->max)
266 {
267 platforms->momentum.x = platforms->max;
268 platforms->momentum.dx = 0;
269 }
270
271 mimimi_platforms_apply(platforms);
272
273 for (i = 0 ; i < platforms->linear_platform_count ; i++)
274 mimimi_positioned_physics_tick(&platforms->linear_platforms[i].physics, platforms->linear_platforms[i].ground);
275 for (i = 0 ; i < platforms->angular_platform_count ; i++)
276 mimimi_positioned_physics_tick(&platforms->angular_platforms[i].physics, platforms->angular_platforms[i].ground);
277
278 diff = platforms->balance - platforms->momentum.x;
279 platforms->momentum.dx += platforms->strength * diff / 256;
280}
281
282void mimimi_platform_set_display_tick(struct mimimi_platform_set *platforms, struct mimimi_image *image, struct mimimi_position *camera)
283{
284 int i;
285 for (i = 0 ; i < platforms->linear_platform_count ; i++)
286 mimimi_platform_display_tick(platforms->linear_platforms + i, camera, image);
287 for (i = 0 ; i < platforms->angular_platform_count ; i++)
288 mimimi_platform_display_tick(platforms->angular_platforms + i, camera, image);
289}