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