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