Mirai's Miscellaneous Misadventures
M53 / core / displays.c
1
2
3
4
5
6
7#include <stdlib.h>
8#include "../mimimi.h"
9
10void mimimi_camera_stamp(struct mimimi_image *target,
11 struct mimimi_position *camera, int x, int y, int z,
12 struct mimimi_image *source)
13{
14 z += 8;
15 if (z <= 0) return;
16
17 x -= camera->x;
18 x = mimimi_div_up(x, z);
19 x += target->width / 2;
20
21 y -= camera->y;
22 y = mimimi_div_up(y, z);
23 y += target->height / 2;
24
25 mimimi_stamp(target, x, y, source);
26}
27
28static void mimimi_sprite_jumping(struct mimimi_image *image,
29 struct mimimi_sprite *sprite)
30{
31 static struct mimimi_pose pose0 = { 0 };
32 static struct mimimi_pose poses[2] = { 0 };
33
34 int slant;
35 int n;
36 int dx, dy;
37 int y_angle;
38
39 n = sprite->direction == 1 ? 1 : -1;
40
41 dx = sprite->physics.dx * -n;
42 dy = sprite->physics.dy;
43
44 if (dx < 0)
45 dx = 0;
46 if (dx > 8191)
47 dx = 8191;
48
49 dy += 8192;
50 if (dy < 0)
51 dy = 0;
52 if (dy > 16383)
53 dy = 16383;
54
55 slant = 64 * dx / 8192 * n;
56 y_angle = 64 + (20 + 20 * dx / 8192) * n;
57
58 poses[0] = pose0;
59 poses[1] = pose0;
60
61 poses[0].layers[0].y_angle = y_angle;
62 poses[0].layers[0].slant = -slant * 2;
63 poses[0].layers[1].slant = slant * 2;
64 poses[0].layers[4].slant = -slant / 2;
65 poses[0].layers[5].slant = -slant / 2;
66
67 poses[1].layers[0].y_angle = y_angle;
68 poses[1].layers[2].slant = -slant * 2;
69 poses[1].layers[3].slant = -slant * 2;
70 poses[1].layers[4].slant = slant * 2;
71 poses[1].layers[5].slant = slant * 2;
72
73 poses[0].x = image->width / 2;
74 poses[0].y = image->height - 15;
75 poses[1].x = image->width / 2;
76 poses[1].y = image->height - 15;
77
78 mimimi_interpolate(poses, poses + 1, dy, 16384);
79 mimimi_pose(image, sprite->model, poses);
80}
81
82static void mimimi_sprite_falling(struct mimimi_image *image,
83 struct mimimi_sprite *sprite)
84{
85 static struct mimimi_pose pose = { 0 };
86
87 int n;
88
89 n = sprite->direction == 1 ? 1 : -1;
90
91 pose.layers[0].z_angle = n;
92 pose.layers[0].y_angle = 64 + 32 * n;
93 pose.layers[4].slant = 96 * n;
94 pose.layers[5].slant = 96 * n;
95 pose.layers[2].z_angle = n;
96 pose.layers[2].slant = -96;
97 pose.layers[3].z_angle = n;
98 pose.layers[3].slant = 96;
99
100 image->width = 48;
101 image->height = 24;
102
103 pose.x = image->width / 2 - 4 * n;
104 pose.y = image->height - 8;
105 mimimi_pose(image, sprite->model, &pose);
106}
107
108static void mimimi_sprite_knocked(struct mimimi_image *image,
109 struct mimimi_sprite *sprite)
110{
111 static struct mimimi_pose pose = { 0 };
112
113 int n;
114
115 n = sprite->direction == 1 ? 1 : -1;
116
117 pose.layers[0].slant = 0;
118 pose.layers[0].z_angle = n;
119 pose.layers[0].y_angle = 64 + 32 * n;
120
121 image->width = 48;
122 image->height = 24;
123
124 pose.x = image->width / 2 - 4 * n;
125 pose.y = image->height - 8;
126 mimimi_pose(image, sprite->model, &pose);
127}
128
129static void mimimi_sprite_walking(struct mimimi_image *image,
130 struct mimimi_sprite *sprite)
131{
132 static struct mimimi_pose pose0 = { 0 };
133 static struct mimimi_pose poses[2] = { 0 };
134
135 int slant, y_angle;
136 int intent;
137 int n;
138 int dx;
139 struct mimimi_pose *a, *b;
140 int i;
141 int y;
142
143 n = sprite->direction == 1 ? 1 : -1;
144
145 dx = sprite->physics.dx * -n;
146 if (dx < 0)
147 dx = 0;
148 if (dx > 8191)
149 dx = 8191;
150
151 intent = dx / 16;
152 slant = intent * n;
153 y_angle = 64 + (20 + 20 * dx / 8192) * n;
154
155 poses[0] = pose0;
156 poses[1] = pose0;
157
158 poses[0].layers[0].y_angle = y_angle;
159 poses[1].layers[0].y_angle = y_angle;
160
161 poses[0].layers[0].slant = -slant / 8;
162 poses[1].layers[0].slant = -slant / 8;
163
164 poses[0].layers[1].slant = slant / 8;
165 poses[1].layers[1].slant = slant / 8;
166
167 poses[1].layers[4].slant = slant / 2;
168 poses[0].layers[4].slant = -slant / 3;
169 poses[1].layers[8].slant = -slant / 8;
170 poses[0].layers[8].slant = -slant / 16;
171
172 poses[0].layers[5].slant = slant / 2;
173 poses[1].layers[5].slant = -slant / 4;
174 poses[0].layers[9].slant = -slant / 8;
175 poses[1].layers[9].slant = -slant / 16;
176
177 poses[0].layers[2].slant = slant / 6;
178 poses[1].layers[2].slant = -slant / 2;
179 poses[0].layers[6].slant = slant / 6;
180 poses[1].layers[6].slant = slant / 2;
181 poses[1].layers[6].y = intent / 128;
182
183 poses[1].layers[3].slant = slant / 6;
184 poses[0].layers[3].slant = -slant / 2;
185 poses[1].layers[7].slant = slant / 6;
186 poses[0].layers[7].slant = slant / 2;
187 poses[0].layers[7].y = intent / 128;
188
189 sprite->animation_time += dx / 1024;
190
191
192 sprite->animation_time &= 0xFF;
193
194 if (sprite->animation_time < 128) {
195 a = poses;
196 b = poses + 1;
197 i = sprite->animation_time;
198 } else {
199 a = poses + 1;
200 b = poses;
201 i = sprite->animation_time - 128;
202 }
203
204 y = sprite->landing_time * dx / 0x8000;
205
206 a->layers[8].y = 128 + mimimi_sine[sprite->animation_time * 8];
207 a->layers[8].y *= intent;
208 a->layers[8].y /= 0x8000;
209 a->layers[8].y += y;
210 b->layers[8].y = a->layers[8].y;
211
212 a->layers[9].y = 128 - mimimi_sine[sprite->animation_time * 8];
213 a->layers[9].y *= intent;
214 a->layers[9].y /= 0x8000;
215 a->layers[9].y += y;
216 b->layers[9].y = a->layers[9].y;
217
218 poses[0].layers[0].y = 128 + mimimi_cosine[i * 16];
219 poses[0].layers[0].y *= intent * (16 - sprite->landing_time);
220 poses[0].layers[0].y /= 0x8000 * 16;
221 poses[0].layers[0].y -= y;
222 poses[1].layers[0].y = poses[0].layers[0].y;
223
224 a->x = image->width / 2;
225 a->y = image->height - 15;
226 b->x = a->x;
227 b->y = a->y;
228
229 mimimi_interpolate(a, b, i, 128);
230 mimimi_pose(image, sprite->model, a);
231}
232
233void mimimi_display_tick(struct mimimi_image *target,
234 struct mimimi_sprite *sprite, struct mimimi_position *camera)
235{
236 static unsigned char colors[24 * 48];
237
238 struct mimimi_physics *physics;
239 struct mimimi_life *life;
240 struct mimimi_walk *walk;
241 struct mimimi_image image;
242 int x, y;
243 int trail;
244
245 physics = &sprite->physics;
246 life = &sprite->life;
247 walk = &sprite->walk;
248
249 image.width = 24;
250 image.height = 48;
251 image.colors = colors;
252
253 for (y = 0; y < image.height; y++)
254 for (x = 0; x < image.width; x++)
255 colors[x + y * image.width] = 0;
256
257 if (life->knocked_time == 0 && walk->direction != 0)
258 sprite->direction = walk->direction;
259
260 if (physics->airborne != 0)
261 sprite->landing_time = 16;
262 else if (sprite->landing_time > 0)
263 sprite->landing_time--;
264
265 if (life->knocked_time == 0) {
266 if (physics->airborne == 0)
267 mimimi_sprite_walking(&image, sprite);
268 else
269 mimimi_sprite_jumping(&image, sprite);
270 } else {
271 if (physics->airborne == 0)
272 mimimi_sprite_knocked(&image, sprite);
273 else
274 mimimi_sprite_falling(&image, sprite);
275 }
276
277 trail = sprite->trail;
278 sprite->trailing_y = mimimi_div(sprite->trailing_y * trail, 256);
279 sprite->trailing_y += mimimi_div(sprite->position.y * (256 - trail), 256);
280 sprite->trail = trail * 3 / 4;
281
282 mimimi_camera_stamp(target, camera, sprite->position.x - image.width * 4,
283 sprite->trailing_y - image.height * 8 + 32, 0, &image);
284}
285
286void mimimi_background_tick(struct mimimi_background *background,
287 struct mimimi_image *image, struct mimimi_position *camera,
288 struct mimimi_position *offset)
289{
290 mimimi_camera_stamp(image, camera, background->x + offset->x,
291 background->y + offset->y, background->z, &background->image);
292}