Mirai's Miscellaneous Misadventures
M52 / core / animations.c
1
2
3
4#include <stdlib.h>
5#include "../mimimi.h"
6
7static unsigned char mimimi_layer_pixel(struct mimimi_layer *layer, unsigned char y_angle, int x, int y)
8{
9 int w, h;
10 int w0, w1;
11 int s;
12 int count;
13 int a;
14
15 h = layer->count;
16
17 if (y < 0) return 0;
18 if (y >= h) return 0;
19
20 w0 = layer->rows[y].width;
21 w1 = layer->rows[y].height;
22
23 s = 128 - mimimi_cosine[y_angle * 16 % 2048];
24 w = s * w0 + (256 - s) * w1;
25 w /= 512;
26
27 if (x < -w) return 0;
28 if (x >= w) return 0;
29
30 count = layer->rows[y].count;
31
32 a = y_angle + 64;
33 a *= count;
34 a += 128;
35 a /= 256;
36 a += x;
37 a = mimimi_mod(a, count);
38
39 return layer->rows[y].colors[a];
40}
41
42static void mimimi_swap(int *x, int *y)
43{
44 int z;
45 z = *x;
46 *x = *y;
47 *y = z;
48}
49
50static void mimimi_layer(struct mimimi_image *image, struct mimimi_layer *layer, int x0, int y0, struct mimimi_pose_layer *pose_layer, int behind)
51{
52 int width, height;
53 unsigned char y_angle;
54 int z_angle;
55 int x, y;
56 int x1, y1;
57 unsigned char color;
58
59 width = image->width;
60 height = image->height;
61
62 y_angle = pose_layer->y_angle;
63 z_angle = mimimi_mod(pose_layer->z_angle, 4);
64
65 if (behind != 0) y_angle += 128;
66
67 if (z_angle == 0)
68 {
69 for (y = 0 ; y < height ; y++)
70 for (x = 0 ; x < width ; x++)
71 {
72 x1 = x + layer->x - x0;
73 y1 = y + layer->y - y0;
74
75 x1 += pose_layer->slant * (y - y0) / 256;
76
77 if (behind != 0) x1 = -x1 - 1;
78
79 color = mimimi_layer_pixel(layer, y_angle, x1, y1);
80 if (color != 0) image->colors[x + y * width] = color;
81 }
82 }
83
84 if (z_angle == 1)
85 {
86 for (y = 0 ; y < height ; y++)
87 for (x = 0 ; x < width ; x++)
88 {
89 x1 = x - layer->y - x0;
90 y1 = y + layer->x - y0;
91
92 y1 -= pose_layer->slant * (x - x0) / 256;
93
94 if (behind != 0) y1 = -y1 - 1;
95
96 color = mimimi_layer_pixel(layer, y_angle, y1, -x1);
97 if (color != 0) image->colors[x + y * width] = color;
98 }
99
100 return;
101 }
102
103 if (z_angle == 2)
104 {
105 for (y = 0 ; y < height ; y++)
106 for (x = 0 ; x < width ; x++)
107 {
108 x1 = x - layer->x - x0;
109 y1 = y - layer->y - y0;
110
111 x1 += pose_layer->slant * (y - y0) / 256;
112
113 if (behind != 0) x1 = -x1 + 1;
114
115 color = mimimi_layer_pixel(layer, y_angle, -x1, -y1);
116 if (color != 0) image->colors[x + y * width] = color;
117 }
118
119 return;
120 }
121
122 if (z_angle == 3)
123 {
124 for (y = 0 ; y < height ; y++)
125 for (x = 0 ; x < width ; x++)
126 {
127 x1 = x + layer->y - x0;
128 y1 = y - layer->x - y0;
129
130 y1 -= pose_layer->slant * (x - x0) / 256;
131
132 if (behind != 0) y1 = -y1 + 1;
133
134 color = mimimi_layer_pixel(layer, y_angle, -y1, x1);
135 if (color != 0) image->colors[x + y * width] = color;
136 }
137
138 return;
139 }
140}
141
142static void mimimi_apply_y_angle(struct mimimi_model *model, struct mimimi_layer *layers, struct mimimi_pose_layer *pose_layers)
143{
144 int i, parent_index;
145 struct mimimi_layer *layer;
146 struct mimimi_pose_layer *pose_layer;
147 int parent_y_angle;
148 unsigned char y_angle;
149 int sin, cos;
150 int x, z;
151
152 for (i = 0 ; i < model->count ; i++)
153 {
154 layer = layers + i;
155 pose_layer = pose_layers + i;
156 parent_index = model->layers[i].parent_index;
157
158 if (i == parent_index) continue;
159
160 parent_y_angle = pose_layers[parent_index].y_angle;
161 pose_layer->y_angle += parent_y_angle;
162
163 y_angle = parent_y_angle;
164
165 sin = mimimi_sine[y_angle * 8];
166 cos = mimimi_cosine[y_angle * 8];
167
168 x = layer->x;
169 z = layer->z;
170
171 layer->x = cos*x / 128 + sin*z / 128;
172 layer->z = cos*z / 128 - sin*x / 128;
173 }
174}
175
176static void mimimi_apply_z_angle(struct mimimi_model *model, struct mimimi_layer *layers, struct mimimi_pose_layer *pose_layers)
177{
178 int *xs, *ys;
179 int i;
180 struct mimimi_layer *layer;
181 struct mimimi_pose_layer *pose_layer;
182 int parent_index;
183 int z_angle;
184 int x, y;
185
186 xs = malloc(sizeof *xs * 0x80);
187 ys = malloc(sizeof *ys * 0x80);
188
189 if (xs == NULL) exit(1);
190 if (ys == NULL) exit(1);
191
192 for (i = 0 ; i < model->count ; i++)
193 {
194 layer = layers + i;
195 pose_layer = pose_layers + i;
196 parent_index = model->layers[i].parent_index;
197
198 xs[i] = layer->x;
199 ys[i] = layer->y;
200 if (i == parent_index) continue;
201 xs[i] += xs[parent_index];
202 ys[i] += ys[parent_index];
203
204 z_angle = mimimi_mod(pose_layer->z_angle, 4);
205
206 x = xs[i];
207 y = ys[i];
208 if (z_angle == 1) x = -x, mimimi_swap(&x, &y);
209 if (z_angle == 2) x = -x, y = -y;
210 if (z_angle == 3) y = -y, mimimi_swap(&x, &y);
211 layer->x = x - xs[parent_index];
212 layer->y = y - ys[parent_index];
213
214 if (z_angle == 1) xs[i] = -xs[i], mimimi_swap(xs + i, ys + i);
215 if (z_angle == 2) xs[i] = -xs[i], ys[i] = -ys[i];
216 if (z_angle == 3) ys[i] = -ys[i], mimimi_swap(xs + i, ys + i);
217 }
218
219 free(xs);
220 free(ys);
221}
222
223static void mimimi_apply_slant(struct mimimi_model *model, struct mimimi_layer *layers, struct mimimi_pose_layer *pose_layers)
224{
225 int *ys;
226 int i;
227 struct mimimi_layer *layer;
228 struct mimimi_pose_layer *pose_layer;
229 int parent_index;
230
231 ys = malloc(sizeof *ys * 0x80);
232 if (ys == NULL) exit(1);
233
234 for (i = 0 ; i < model->count ; i++)
235 {
236 layer = layers + i;
237 pose_layer = pose_layers + i;
238 parent_index = model->layers[i].parent_index;
239
240 ys[i] = layer->y;
241 if (i == parent_index) continue;
242 ys[i] += ys[parent_index];
243
244 layer->x += pose_layer->slant * ys[i] / 256;
245 }
246
247 free(ys);
248}
249
250static void mimimi_absolutise(struct mimimi_model *model, struct mimimi_layer *layers, struct mimimi_pose_layer *pose_layers)
251{
252 int i;
253 struct mimimi_layer *layer;
254 struct mimimi_pose_layer *pose_layer;
255 int parent_index;
256
257 for (i = 0 ; i < model->count ; i++)
258 {
259 layer = layers + i;
260 pose_layer = pose_layers + i;
261 parent_index = model->layers[i].parent_index;
262 if (i == parent_index) continue;
263
264 layer->x += layers[parent_index].x;
265 layer->y += layers[parent_index].y;
266 layer->z += layers[parent_index].z;
267 layer->amplifier = layer->amplifier * layers[parent_index].amplifier / 32;
268
269 pose_layer->slant += pose_layers[parent_index].slant;
270 pose_layer->z_angle += pose_layers[parent_index].z_angle;
271 pose_layer->z_angle = mimimi_mod(pose_layer->z_angle, 4);
272 }
273}
274
275struct mimimi_half_layer
276{
277 int behind;
278 int z;
279 struct mimimi_layer *layer;
280 struct mimimi_pose_layer *pose_layer;
281};
282
283void mimimi_pose(struct mimimi_image *image, struct mimimi_model *model, struct mimimi_pose *pose)
284{
285 struct mimimi_layer *layers;
286 struct mimimi_pose_layer *pose_layers;
287 struct mimimi_half_layer *half_layers;
288 struct mimimi_layer *layer;
289 struct mimimi_pose_layer *pose_layer;
290 struct mimimi_half_layer *half_layer, half_layer0;
291 int i, j, k;
292 int x, y;
293 int a, b;
294
295 layers = malloc(sizeof *layers * model->count);
296 pose_layers = malloc(sizeof *pose_layers * model->count);
297 half_layers = malloc(sizeof *half_layers * model->count * 2);
298
299 for (i = 0 ; i < model->count ; i++)
300 {
301 layer = layers + i;
302 *layer = *model->layers[i].layer;
303
304 pose_layer = pose_layers + i;
305
306 if (i < pose->count)
307 {
308 *pose_layer = pose->layers[i];
309 }
310 else
311 {
312 pose_layer->slant = 0;
313 pose_layer->y_angle = 0;
314 pose_layer->z_angle = 0;
315 }
316 }
317
318 mimimi_apply_y_angle(model, layers, pose_layers);
319 mimimi_apply_z_angle(model, layers, pose_layers);
320 mimimi_apply_slant(model, layers, pose_layers);
321 mimimi_absolutise(model, layers, pose_layers);
322
323 for (i = 0 ; i < model->count ; i++)
324 {
325 layer = layers + i;
326 pose_layer = pose_layers + i;
327
328 half_layers[i * 2 + 0].behind = 0;
329 half_layers[i * 2 + 0].z = layer->z * layer->amplifier + layer->width * 32;
330 half_layers[i * 2 + 0].layer = layer;
331 half_layers[i * 2 + 0].pose_layer = pose_layer;
332
333 half_layers[i * 2 + 1].behind = 1;
334 half_layers[i * 2 + 1].z = layer->z * layer->amplifier - layer->width * 32;
335 half_layers[i * 2 + 1].layer = layer;
336 half_layers[i * 2 + 1].pose_layer = pose_layer;
337 }
338
339
340 for (i = 0 ; i < model->count * 2 ; i++)
341 {
342 a = half_layers[i].z;
343
344 k = i;
345 for (j = i - 1 ; j >= 0 ; j--)
346 {
347 b = half_layers[j].z;
348 if (a >= b) break;
349
350 half_layer0 = half_layers[k];
351 half_layers[k] = half_layers[j];
352 half_layers[j] = half_layer0;
353
354 k = j;
355 }
356 }
357
358 for (y = 0 ; y < image->height ; y++)
359 for (x = 0 ; x < image->width ; x++)
360 image->colors[x + y * image->width] = 0;
361
362 for (i = 0 ; i < model->count * 2 ; i++)
363 {
364 half_layer = half_layers + i;
365 mimimi_layer(image, half_layer->layer, pose->x, pose->y, half_layer->pose_layer, half_layer->behind);
366 }
367
368 free(layers);
369 free(pose_layers);
370 free(half_layers);
371}
372
373static void mimimi_interpolate_pose_layer(struct mimimi_pose_layer *a, struct mimimi_pose_layer *b, int i, int count)
374{
375 int slant, y_angle, z_angle;
376
377 slant = a->slant * (count - i) / count;
378 slant += mimimi_div(b->slant * i, count);
379
380 y_angle = a->y_angle * (count - i) / count;
381 y_angle += mimimi_div(b->y_angle * i, count);
382
383 z_angle = a->z_angle * (count - i) / count;
384 z_angle += mimimi_div(b->z_angle * i, count);
385
386 a->slant = slant;
387 a->y_angle = y_angle;
388 a->z_angle = z_angle;
389}
390
391static void mimimi_interpolate_pose(struct mimimi_pose *a, struct mimimi_pose *b, int i, int count)
392{
393 int x, y;
394 int j;
395
396 if (count == 0) return;
397
398 x = a->x * (count - i) / count;
399 x += mimimi_div(b->x * i, count);
400
401 y = a->y * (count - i) / count;
402 y += mimimi_div(b->y * i, count);
403
404 a->x = x;
405 a->y = y;
406
407 for (j = 0 ; j < a->count ; j++)
408 mimimi_interpolate_pose_layer(a->layers + j, b->layers + j, i, count);
409}
410
411void mimimi_movement(struct mimimi_video *video, struct mimimi_model *model, struct mimimi_movement *movement)
412{
413 struct mimimi_pose *pose;
414 int h, i, j, k;
415
416 pose = malloc(sizeof *pose);
417 if (pose == NULL) exit(1);
418
419 if (movement->count == 1)
420 {
421 for (i = 0 ; i < video->count ; i++)
422 mimimi_pose(video->images + i, model, movement->poses);
423 return;
424 }
425
426 for (i = 0 ; i < video->count ; i++)
427 {
428 j = i * (movement->count - 1) / video->count;
429 k = i - j * video->count / (movement->count - 1);
430
431 *pose = movement->poses[j];
432 for (h = 0 ; h < pose->count ; h++) pose->layers[h] = movement->poses[j].layers[h];
433
434 mimimi_interpolate_pose(pose, movement->poses + j + 1, k, video->count / (movement->count - 1));
435 mimimi_pose(video->images + i, model, pose);
436 }
437
438 free(pose);
439}
440
441static void mimimi_appearance_videos(struct mimimi_video_set *videos, struct mimimi_model *model, int x, int y, int coefficient)
442{
443 static struct mimimi_pose_layer layer0 = {0};
444
445 struct mimimi_pose *poses, *pose;
446 struct mimimi_movement *movement;
447 struct mimimi_pose_layer (*layers)[2][10];
448 int video_count;
449 int i, j;
450 int slant, y_angle;
451
452 poses = malloc(sizeof *poses * 4);
453 movement = malloc(sizeof *movement);
454 layers = malloc(sizeof *layers);
455
456 if (poses == NULL) exit(1);
457 if (movement == NULL) exit(1);
458 if (layers == NULL) exit(1);
459
460 pose = poses + 3;
461
462 video_count = videos->standing_video_count;
463 for (i = 0 ; i < video_count ; i++)
464 {
465 slant = 512 * i / video_count * coefficient;
466 y_angle = 64 + (20 + 20 * i / video_count) * coefficient;
467
468 for (j = 0 ; j < 10 ; j++)
469 {
470 (*layers)[0][j] = layer0;
471 (*layers)[1][j] = layer0;
472 }
473
474 (*layers)[0][0].y_angle = y_angle;
475 (*layers)[1][0].y_angle = y_angle;
476
477 (*layers)[0][0].slant = -slant / 8;
478 (*layers)[1][0].slant = -slant / 8;
479
480 (*layers)[0][1].slant = slant / 8;
481 (*layers)[1][1].slant = slant / 8;
482
483 (*layers)[1][4].slant = slant / 3;
484 (*layers)[1][8].slant = -slant / 3;
485 (*layers)[0][8].slant = -slant / 8;
486
487 (*layers)[0][5].slant = slant / 3;
488 (*layers)[0][9].slant = -slant / 3;
489 (*layers)[1][9].slant = -slant / 8;
490
491 (*layers)[0][2].slant = slant / 5;
492 (*layers)[1][2].slant = -slant / 3;
493 (*layers)[0][6].slant = slant / 4;
494 (*layers)[1][6].slant = slant / 2;
495
496 (*layers)[1][3].slant = slant / 5;
497 (*layers)[0][3].slant = -slant / 3;
498 (*layers)[1][7].slant = slant / 4;
499 (*layers)[0][7].slant = slant / 2;
500
501 for (j = 0 ; j < 3 ; j++)
502 {
503 poses[j].x = x;
504 poses[j].y = y;
505 poses[j].count = 10;
506 }
507
508 for (j = 0 ; j < 10 ; j++)
509 {
510 poses[0].layers[j] = (*layers)[0][j];
511 poses[1].layers[j] = (*layers)[1][j];
512 poses[2].layers[j] = (*layers)[0][j];
513 }
514
515 movement->count = 3;
516 movement->poses = poses;
517 mimimi_movement(videos->standing + i, model, movement);
518 }
519
520 for (i = 0 ; i < 7 ; i++) pose->layers[i] = layer0;
521
522 pose->layers[0].z_angle = coefficient;
523 pose->layers[0].y_angle = 64 + 32 * coefficient;
524 pose->layers[4].slant = 96 * coefficient;
525 pose->layers[5].slant = 96 * coefficient;
526 pose->layers[2].z_angle = coefficient;
527 pose->layers[2].slant = -96;
528 pose->layers[3].z_angle = coefficient;
529 pose->layers[3].slant = 96;
530
531 pose->x = x - 12 * coefficient;
532 pose->y = y - 12;
533 pose->count = 7;
534
535 movement->count = 1;
536 movement->poses = pose;
537
538 mimimi_movement(videos->falling, model, movement);
539
540 pose->layers[0] = layer0;
541 pose->layers[0].slant = 0;
542 pose->layers[0].z_angle = coefficient;
543 pose->layers[0].y_angle = 64 + 32 * coefficient;
544
545 pose->x = x - 12 * coefficient;
546 pose->y = y - 20;
547 pose->count = 1;
548
549 movement->count = 1;
550 movement->poses = pose;
551
552 mimimi_movement(videos->knocked, model, movement);
553
554 video_count = videos->jumping_video_count;
555 for (i = 0 ; i < video_count ; i++)
556 {
557 for (j = 0 ; j < 6 ; j++)
558 {
559 poses[0].layers[j] = layer0;
560 poses[1].layers[j] = layer0;
561 }
562
563 slant = 64 * i / videos->jumping[i].count * coefficient;
564 y_angle = 64 + (20 + 20 * i / videos->jumping[i].count) * coefficient;
565
566 poses[0].x = x;
567 poses[0].y = y;
568 poses[0].count = 6;
569 poses[0].layers[0].y_angle = y_angle;
570 poses[0].layers[0].slant = -slant * 2;
571 poses[0].layers[1].slant = slant * 2;
572 poses[0].layers[4].slant = -slant / 2;
573 poses[0].layers[5].slant = -slant / 2;
574
575 poses[1].x = x;
576 poses[1].y = y;
577 poses[1].count = 6;
578 poses[1].layers[0].y_angle = y_angle;
579 poses[1].layers[2].slant = -slant * 2;
580 poses[1].layers[3].slant = -slant * 2;
581 poses[1].layers[4].slant = slant * 2;
582 poses[1].layers[5].slant = slant * 2;
583
584 movement->count = 2;
585 movement->poses = poses;
586
587 mimimi_movement(videos->jumping + i, model, movement);
588 }
589
590 free(poses);
591 free(movement);
592 free(layers);
593}
594
595void mimimi_appearance(struct mimimi_appearance *appearance, struct mimimi_model *model, int x, int y)
596{
597 mimimi_appearance_videos(&appearance->left, model, x, y, 1);
598 mimimi_appearance_videos(&appearance->right, model, x, y, -1);
599}