Mirai's Miscellaneous Misadventures
M12 / game.c
1#include "game.h"
2#include "math.c"
3
4
5
6struct mirai_animation
7{
8 int count;
9 struct mirai_image *images;
10};
11
12struct mirai_direction_animation_set
13{
14 int count;
15 struct mirai_animation *standing;
16 struct mirai_animation knocked;
17};
18
19struct mirai_animation_set
20{
21 struct mirai_direction_animation_set left, right;
22};
23
24struct mirai_sprite_type
25{
26 struct mirai_animation_set animations;
27 int width;
28 int height;
29};
30
31struct mirai_sprite
32{
33 struct mirai_sprite_type *type;
34
35 int x, y;
36
37 int dx, dy;
38
39 int ax;
40
41 char airborne;
42 char moving_direction;
43 char last_moving_direction;
44
45 int attack_y;
46 int attack_width;
47 int attack_height;
48 int attack_time;
49
50 void (*behave)(struct mirai_game *game, struct mirai_sprite *sprite);
51
52 unsigned char animation_time;
53
54 unsigned char knocked_time;
55};
56
57struct mirai_rotating_image_row
58{
59 int size;
60 unsigned char count;
61 unsigned char colors[64];
62};
63
64struct mirai_rotating_image
65{
66 int count;
67 struct mirai_rotating_image_row rows[];
68};
69
70
71
72
73#include "assets.c"
74
75static int mirai_gravity = 4;
76
77static unsigned char mirai_ground_colors[16 * 16];
78
79static unsigned char mirai_colors[80686];
80
81static struct mirai_image mirai_images[145] =
82{
83 {16, 16, mirai_ground_colors},
84};
85
86static struct mirai_animation mirai_animations[9];
87
88static struct mirai_image *mirai_ground_image = mirai_images;
89
90static struct mirai_sprite_type mirai_mirai = {{}, 80, 250};
91
92static struct mirai_image *mirai_glyphs[26 * 2 + 10];
93
94
95
96
97struct mirai_game
98{
99 struct mirai_engine engine;
100 struct mirai_sprite sprites[256];
101 unsigned char sprite_count;
102
103 unsigned int left_history:16;
104 unsigned int right_history:16;
105
106 struct mirai_sprite *camera_sprite;
107 int camera_x;
108 int camera_y;
109};
110
111
112
113
114static void mirai_stamp(struct mirai_game *game, int x, int y, struct mirai_image *image)
115{
116 x -= game->camera_x;
117 x += mirai_width * 4;
118 y -= game->camera_y;
119 y += mirai_height * 4;
120
121 x -= image->width * 4;
122 y -= image->height * 8;
123
124 (*game->engine.stamp)(game->engine.data, x / 8, y / 8, image);
125}
126
127static int mirai_text(struct mirai_game *game, int x, int y, char *text)
128{
129 for (int i = 0 ; *text != '\0' ; i++)
130 {
131 char ch = *text++;
132
133 if (ch == ' ')
134 {
135 x += 4;
136 continue;
137 }
138
139 struct mirai_image *image;
140
141 if (ch >= '0' && ch <= '9')
142 {
143 image = mirai_glyphs[ch - '0' + 0];
144 }
145 else if (ch >= 'A' && ch <= 'Z')
146 {
147 image = mirai_glyphs[ch - 'A' + 10];
148 }
149 else if (ch >= 'a' && ch <= 'z')
150 {
151 image = mirai_glyphs[ch - 'a' + 36];
152 }
153 else
154 {
155 continue;
156 }
157
158 (*game->engine.stamp)(game->engine.data, x - 1, y - image->height + 5, image);
159 x += image->width - 1;
160 }
161
162 return x;
163}
164
165static void mirai_wall_physics(struct mirai_sprite *sprite)
166{
167 int x0 = sprite->x;
168 int x1 = sprite->type->width / 2;
169 int y0 = sprite->y;
170 int y1 = sprite->type->height;
171
172 int top = (y0 - y1) / 128;
173 int top2 = top - 1;
174 int bottom = (y0 - 127) / 128;
175 int bottom2 = bottom - 1;
176 int left = (x0 - x1) / 128;
177 int right = (x0 + x1) / 128;
178
179 if (
180 mirai_ground[bottom][left] != 0 && mirai_ground[bottom2][left] != 0 ||
181 mirai_ground[top][left] != 0 && mirai_ground[top2][left]
182 )
183 {
184 if (sprite->dx < 0) sprite->dx = 0;
185 sprite->x = (left + 1) * 128 + x1;
186 }
187 if (
188 mirai_ground[bottom][right] != 0 && mirai_ground[bottom2][right] != 0 ||
189 mirai_ground[top][right] != 0 && mirai_ground[top2][right]
190 )
191 {
192 if (sprite->dx > 0) sprite->dx = 0;
193 sprite->x = right * 128 - x1 - 1;
194 }
195}
196
197static void mirai_step_physics(struct mirai_sprite *sprite)
198{
199 int x0 = sprite->x;
200 int x1 = sprite->type->width / 2;
201 int y0 = sprite->y;
202 int y1 = sprite->type->height;
203
204 int top = (y0 - y1) / 128;
205 int bottom = (y0 - 127) / 128;
206 int left = (x0 - x1) / 128;
207 int right = (x0 + x1) / 128;
208
209 if (mirai_ground[bottom][left] != 0 && mirai_ground[top][left] == 0)
210 sprite->y = bottom * 128;
211 if (mirai_ground[bottom][right] != 0 && mirai_ground[top][right] == 0)
212 sprite->y = bottom * 128;
213}
214
215static void mirai_ceiling_physics(struct mirai_sprite *sprite)
216{
217 int x0 = sprite->x;
218 int x1 = sprite->type->width / 2;
219 int y0 = sprite->y;
220 int y1 = sprite->type->height;
221
222 int top = (y0 - y1) / 128;
223 int top2 = top - 1;
224 int left = (x0 - x1) / 128;
225 int right = (x0 + x1) / 128;
226
227 if (sprite->dy > 0) return;
228
229 if (mirai_ground[top][left] != 0)
230 if (mirai_ground[top][right] != 0)
231 if (mirai_ground[top2][left] != 0 || mirai_ground[top2][right] != 0)
232 {
233 sprite->dy = 0;
234 sprite->y = (top + 1) * 128 + y1;
235 }
236}
237
238static void mirai_landing_physics(struct mirai_sprite *sprite)
239{
240 int x0 = sprite->x;
241 int x1 = sprite->type->width / 2;
242 int y0 = sprite->y;
243
244 int bottom = y0 / 128;
245 int left = (x0 - x1) / 128;
246 int right = (x0 + x1) / 128;
247
248 if (sprite->dy < 0) return;
249
250 if (mirai_ground[bottom][left] != 0 || mirai_ground[bottom][right] != 0)
251 {
252 sprite->airborne = 0;
253 sprite->dy = 0;
254 sprite->y = bottom * 128;
255 }
256}
257
258static void mirai_fall_physics(struct mirai_sprite *sprite)
259{
260 int x0 = sprite->x;
261 int x1 = sprite->type->width / 2;
262 int y0 = sprite->y;
263
264 int bottom = y0 / 128;
265 int center = x0 / 128;
266 int left = (x0 - x1) / 128;
267 int right = (x0 + x1) / 128;
268
269 if (mirai_ground[bottom][left] == 0 && mirai_ground[bottom][right] == 0)
270 {
271 if (mirai_ground[bottom + 1][center] == 0)
272
273 sprite->airborne = 1;
274 else
275
276 sprite->y = (bottom + 1) * 128;
277 }
278}
279
280static void mirai_physics_dynamics(struct mirai_sprite *sprite)
281{
282 sprite->dx += sprite->ax;
283 sprite->x += sprite->dx;
284 sprite->y += sprite->dy;
285}
286
287static void mirai_ground_physics(struct mirai_sprite *sprite)
288{
289 sprite->dx *= 7;
290 sprite->dx /= 8;
291 sprite->dy = 0;
292
293 mirai_physics_dynamics(sprite);
294
295 mirai_step_physics(sprite);
296 mirai_wall_physics(sprite);
297 mirai_fall_physics(sprite);
298}
299
300static void mirai_airborne_physics(struct mirai_sprite *sprite)
301{
302 sprite->dx *= 15;
303 sprite->dx /= 16;
304 sprite->dy += mirai_gravity;
305
306 mirai_physics_dynamics(sprite);
307
308 mirai_ceiling_physics(sprite);
309 mirai_wall_physics(sprite);
310 mirai_landing_physics(sprite);
311}
312
313static void mirai_jump(struct mirai_sprite *sprite)
314{
315 if (sprite->airborne) return;
316 sprite->airborne = 1;
317 sprite->dy = -64;
318}
319
320static void mirai_damage(struct mirai_game *game, struct mirai_sprite *sprite)
321{
322
323 struct mirai_image area = {sprite->attack_width / 16, sprite->attack_height / 8};
324 int x = sprite->x + sprite->attack_width / 4;
325 int y = (sprite->y + sprite->attack_y);
326
327 if (sprite->moving_direction == 1) x -= sprite->attack_width / 2;
328
329 mirai_stamp(game, x, y, &area);
330 */
331}
332
333static void mirai_attack(struct mirai_game *game, struct mirai_sprite *sprite)
334{
335 sprite->attack_y = -16;
336 sprite->attack_width = 512;
337 sprite->attack_height = 256;
338 mirai_damage(game, sprite);
339}
340
341static void mirai_rapid_attack(struct mirai_game *game, struct mirai_sprite *sprite)
342{
343 sprite->attack_y = -128;
344 sprite->attack_width = sprite->attack_time * 16 + 64;
345 sprite->attack_height = 64;
346 if (sprite->attack_time != 0x7F) sprite->attack_time++;
347 mirai_damage(game, sprite);
348}
349
350static unsigned char mirai_count_oscillations(unsigned int history)
351{
352 unsigned char count = 0;
353 unsigned char prev = history&1;
354 for (int i = 0 ; i < 16 ; i++)
355 {
356 if ((history&1) != prev) count++;
357 prev = history&1;
358 history >>= 1;
359 }
360 return count;
361}
362
363static void mirai_controls(struct mirai_game *game, struct mirai_sprite *sprite)
364{
365 unsigned char left_oscillations = mirai_count_oscillations(game->left_history);
366 unsigned char right_oscillations = mirai_count_oscillations(game->right_history);
367
368 switch (sprite->moving_direction)
369 {
370 case 0:
371 if ((game->left_history&1) != 0)
372 sprite->moving_direction = 1;
373 if ((game->right_history&1) != 0)
374 sprite->moving_direction = 2;
375 break;
376 case 1:
377 if ((game->left_history&1) == 0)
378 sprite->moving_direction = 0;
379 else if (left_oscillations > 1)
380 mirai_jump(sprite);
381 if ((game->right_history&1) != 0)
382 {
383 if (right_oscillations == 0)
384 mirai_rapid_attack(game, sprite);
385 else
386 sprite->attack_time = 0;
387 }
388 if ((game->right_history&1) != 0 && (game->right_history&2) == 0)
389 mirai_attack(game, sprite);
390 break;
391 case 2:
392 if ((game->right_history&1) == 0)
393 sprite->moving_direction = 0;
394 else if (right_oscillations > 1)
395 mirai_jump(sprite);
396 if ((game->left_history&1) != 0)
397 {
398 if (left_oscillations == 0)
399 mirai_rapid_attack(game, sprite);
400 else
401 sprite->attack_time = 0;
402 }
403 if ((game->left_history&1) != 0 && (game->left_history&2) == 0)
404 mirai_attack(game, sprite);
405 break;
406 }
407}
408
409static void mirai_spawn(struct mirai_game *game, int x, int y, struct mirai_sprite_type *type, void (*behave)(struct mirai_game *game, struct mirai_sprite *sprite))
410{
411 if (game->sprite_count == 0xFF) return;
412 struct mirai_sprite *sprite = game->sprites + game->sprite_count;
413 game->sprite_count++;
414 sprite->type = type;
415 sprite->x = x;
416 sprite->y = y;
417 sprite->dx = 0;
418 sprite->dy = 0;
419 sprite->ax = 0;
420 sprite->airborne = 1;
421 sprite->moving_direction = 0;
422 sprite->last_moving_direction = 1;
423 sprite->attack_time = 0;
424 sprite->animation_time = 0;
425 sprite->behave = behave;
426}
427
428static void mirai_image_rotation(struct mirai_image *image, struct mirai_rotating_image *rotating_image, unsigned char angle, int x0, int y0, int tilt, int tilt_origin, int tilt_threshold, char flip)
429{
430 if (flip != 0) angle = 0x100 - angle;
431
432 int width = image->width;
433 int height = image->height;
434
435 for (int y = 0 ; y < rotating_image->count ; y++)
436 for (int x = 0 ; x < rotating_image->rows[y].size ; x++)
437 {
438 int count = rotating_image->rows[y].count;
439
440 int w = rotating_image->rows[y].size;
441 int h = rotating_image->count;
442
443 unsigned int a = angle;
444 a *= count;
445 a += 128;
446 a /= 256;
447 a += x;
448 a %= count;
449
450 if (flip != 0) a = count - a - 1;
451
452 int yy = y;
453 if (yy < tilt_threshold) yy = tilt_threshold;
454
455 int x1 = x + x0 + (width - w) / 2 + tilt * (tilt_origin - yy) / 256;
456 int y1 = y - y0 + height - h;
457
458 unsigned char color = rotating_image->rows[y].colors[a];
459 if (color == 0) continue;
460
461 image->colors[x1 + y1 * width] = color;
462 }
463}
464
465static void mirai_mirai_animation_frame(struct mirai_image *image, unsigned char **colors_pointer, int angle, int tilt, int arm_tilt)
466{
467 unsigned char *colors = *colors_pointer;
468
469 image->colors = colors;
470 image->width = 26;
471 image->height = 36;
472
473 (*colors_pointer) += image->width * image->height;
474
475 for (int x = 0 ; x < image->width ; x++)
476 for (int y = 0 ; y < image->height ; y++)
477 image->colors[x + y * image->width] = 0;
478
479 int x = mirai_sine[angle];
480 x *= 5;
481 x /= 128;
482 int left_x = x + (mirai_mirai_left_arm.count + 10) * tilt / 256;
483 int right_x = x - (mirai_mirai_right_arm.count + 10) * tilt / 256;
484
485 int height = mirai_mirai_torso.count;
486
487 mirai_image_rotation(image, &mirai_mirai_hair, angle, 0, 7, tilt, height, 11, 1);
488 if ((angle + 64) % 256 < 128)
489 {
490 mirai_image_rotation(image, &mirai_mirai_left_arm, angle, left_x, 10, tilt - arm_tilt, 0, 0, 0);
491 mirai_image_rotation(image, &mirai_mirai_torso, angle, 0, 0, tilt, height, 11, 0);
492 mirai_image_rotation(image, &mirai_mirai_right_arm, angle, -right_x, 10, tilt + arm_tilt, 0, 0, 0);
493 }
494 else
495 {
496 mirai_image_rotation(image, &mirai_mirai_right_arm, angle, -right_x, 10, tilt + arm_tilt, 0, 0, 0);
497 mirai_image_rotation(image, &mirai_mirai_torso, angle, 0, 0, tilt, height, 11, 0);
498 mirai_image_rotation(image, &mirai_mirai_left_arm, angle, left_x, 10, tilt - arm_tilt, 0, 0, 0);
499 }
500 mirai_image_rotation(image, &mirai_mirai_hair, angle, 0, 7, tilt, height, 11, 0);
501}
502
503static void mirai_mirai_animation(struct mirai_animation *animation, struct mirai_image **images, unsigned char **colors, int angle, int count, int tilt, int arm_tilt)
504{
505 animation->count = count;
506 animation->images = *images;
507
508 for (int i = 0 ; i < count ; i++)
509 mirai_mirai_animation_frame((*images)++, colors, angle, tilt, arm_tilt * mirai_sine[i * 255 / count] / 128);
510}
511
512static void mirai_mirai_animation_set(struct mirai_animation **animations, struct mirai_image **images, unsigned char **colors, int coefficient, int count, int count2, int tilt, int arm_tilt)
513{
514 for (int i = 0 ; i < count ; i++)
515 mirai_mirai_animation((*animations)++, images, colors, 64 + (12 + 34 * i / count) * coefficient, count2, -tilt * i / count * coefficient, arm_tilt * i / count);
516}
517
518
519static void mirai_transpose_image(struct mirai_image *image)
520{
521 int width = image->width;
522 int height = image->height;
523 image->width = height;
524 image->height = width;
525
526 for (int start = 0 ; start < width * height ; start++)
527 {
528 int next = start;
529 int i = 0;
530 for (;;)
531 {
532 i++;
533 next = (next % height) * width + next / height;
534 if (next <= start) break;
535 }
536
537 if (i == 1) continue;
538 if (next < start) continue;
539
540 char tmp = image->colors[next = start];
541 for (;;)
542 {
543 int i = (next % height) * width + next / height;
544 image->colors[next] = (i == start) ? tmp : image->colors[i];
545 next = i;
546 if (next <= start) break;
547 }
548 }
549}
550
551static void mirai_flip_image(struct mirai_image *image)
552{
553 for (int x = 0 ; x < image->width / 2 ; x++)
554 for (int y = 0 ; y < image->height ; y++)
555 {
556 char color = image->colors[image->width - x - 1 + y * image->width];
557 image->colors[image->width - x - 1 + y * image->width] = image->colors[x + y * image->width];
558 image->colors[x + y * image->width] = color;
559 }
560}
561
562static void mirai_rotate_image_cw(struct mirai_image *image)
563{
564 mirai_transpose_image(image);
565 mirai_flip_image(image);
566}
567
568static void mirai_rotate_image_ccw(struct mirai_image *image)
569{
570 mirai_flip_image(image);
571 mirai_transpose_image(image);
572}
573
574
575
576
577int mirai_game_size = sizeof (struct mirai_game);
578int mirai_width = 512;
579int mirai_height = 256;
580
581
582
583
584void mirai_start(struct mirai_game *game, struct mirai_engine *engine)
585{
586 game->engine = *engine;
587
588 game->left_history = 0;
589 game->right_history = 0;
590 game->sprite_count = 0;
591
592 for (int y = 0 ; y < sizeof mirai_ground / sizeof *mirai_ground ; y++)
593 for (int x = 0 ; x < sizeof *mirai_ground / sizeof **mirai_ground ; x++)
594 {
595 if (mirai_ground[y][x] == 2)
596 {
597 game->camera_x = x * 128;
598 game->camera_y = y * 128 - 512;
599 game->camera_sprite = game->sprites + game->sprite_count;
600 mirai_spawn(game, x * 128, y * 128, &mirai_mirai, &mirai_controls);
601 }
602 }
603
604 mirai_assets();
605}
606
607void mirai_step(struct mirai_game *game, struct mirai_keys keys)
608{
609 game->left_history <<= 1;
610 game->left_history |= keys.left;
611 game->right_history <<= 1;
612 game->right_history |= keys.right;
613
614 game->camera_x *= 3;
615 game->camera_y *= 3;
616 game->camera_x += game->camera_sprite->x;
617 game->camera_y += game->camera_sprite->y - 512;
618 game->camera_x /= 4;
619 game->camera_y /= 4;
620
621 for (int x0 = -16 ; x0 <= 16 ; x0++)
622 for (int y0 = -8 ; y0 <= 8 ; y0++)
623 {
624 int x = x0 + game->camera_x / 128;
625 int y = y0 + game->camera_y / 128;
626 if (mirai_ground[y][x] != 0)
627 mirai_stamp(game, x * 128 + 64, y * 128 + 128, mirai_ground_image);
628 }
629
630 for (int i = 0 ; i < game->sprite_count ; i++)
631 {
632 struct mirai_sprite *sprite = game->sprites + i;
633
634 if (sprite->dy > 128)
635 sprite->knocked_time = 64;
636 else if (sprite->knocked_time != 0)
637 sprite->knocked_time--;
638
639 sprite->ax = 0;
640 if (sprite->knocked_time == 0)
641 {
642 (*sprite->behave)(game, sprite);
643
644 if (sprite->moving_direction != 0)
645 sprite->last_moving_direction = sprite->moving_direction;
646
647 if (sprite->airborne)
648 {
649 if (sprite->moving_direction == 1)
650 sprite->ax = -3;
651 if (sprite->moving_direction == 2)
652 sprite->ax = 3;
653 }
654 else
655 {
656 if (sprite->moving_direction == 1)
657 sprite->ax = -4;
658 if (sprite->moving_direction == 2)
659 sprite->ax = 4;
660 }
661 }
662
663 if (sprite->airborne == 0)
664 mirai_ground_physics(sprite);
665 else
666 mirai_airborne_physics(sprite);
667
668 int dx;
669 int dy = sprite->dy;
670
671 struct mirai_direction_animation_set *animations;
672
673 if (sprite->last_moving_direction == 1)
674 {
675 dx = -sprite->dx;
676 animations = &sprite->type->animations.left;
677 }
678 if (sprite->last_moving_direction == 2)
679 {
680 dx = sprite->dx;
681 animations = &sprite->type->animations.right;
682 }
683
684 struct mirai_animation *animation;
685
686 if (dx > 32) dx = 32;
687 if (dx < 0) dx = 0;
688 if (dy < 0) dy = 0;
689
690 if (sprite->knocked_time == 0)
691 {
692 animation = animations->standing + dx * (animations->count - 1) / 32;
693 sprite->animation_time += dx / 4;
694 }
695 else
696 {
697 animation = &animations->knocked;
698 if (dy == 0) sprite->animation_time = 0;
699 else sprite->animation_time += dy / 8;
700 }
701
702 struct mirai_image *image = animation->images + sprite->animation_time * (animation->count - 1) / 256;
703 int y = 0;
704 if (sprite->knocked_time != 0) y = image->height * 4 - 56;
705
706 mirai_stamp(game, sprite->x, sprite->y + y, image);
707 }
708
709 mirai_text(game, 16, 16, "Mirai's Miscellaneous Misadventures M12 November 1 2021");
710 mirai_text(game, 16, 32, "a Senran Kagura fangame by zamfofex");
711}
712
713struct mirai_image *mirai_assets(void)
714{
715 static char done = 0;
716 if (done != 0) return mirai_images;
717
718 int color_count = sizeof mirai_colors / sizeof *mirai_colors;
719 unsigned char *last_color = mirai_colors + color_count - 1;
720
721 int image_count = sizeof mirai_images / sizeof *mirai_images;
722 struct mirai_image *last_image = mirai_images + image_count - 1;
723
724 int animation_count = sizeof mirai_animations / sizeof *mirai_animations;
725 struct mirai_animation *last_animation = mirai_animations + animation_count - 1;
726
727 last_image->width = 0;
728 last_image->height = 0;
729
730 for (int i = 0 ; i < 256 ; i++)
731 mirai_ground_colors[i] = 0x3B;
732
733 unsigned char *colors = mirai_colors;
734 struct mirai_image *images = mirai_images + 1;
735 struct mirai_animation *animations = mirai_animations;
736
737 mirai_mirai.animations.left.standing = animations;
738 mirai_mirai.animations.left.count = 4;
739 mirai_mirai_animation_set(&animations, &images, &colors, 1, 4, 8, 64, 128);
740
741 mirai_mirai.animations.right.standing = animations;
742 mirai_mirai.animations.right.count = 4;
743 mirai_mirai_animation_set(&animations, &images, &colors, -1, 4, 8, 64, 128);
744
745 struct mirai_image *rotated_ccw = images;
746 mirai_mirai_animation(&mirai_mirai.animations.left.knocked, &images, &colors, 64 - 16, 8, 0, 128);
747 while (rotated_ccw != images) mirai_rotate_image_ccw(rotated_ccw++);
748
749 struct mirai_image *rotated_cw = images;
750 mirai_mirai_animation(&mirai_mirai.animations.right.knocked, &images, &colors, 64 + 16, 8, 0, 128);
751 while (rotated_cw != images) mirai_rotate_image_cw(rotated_cw++);
752
753 for (int i = 0 ; i < 10 ; i++)
754 {
755 mirai_glyphs[i] = images;
756 images->colors = colors;
757 images->height = 15;
758
759 for (int x = 1 ; x < 12 ; x++)
760 {
761 int done = 1;
762 for (int y = 0 ; y < images->height ; y++)
763 {
764 if (mirai_digits[i][y][x] != 0)
765 {
766 done = 0;
767 break;
768 }
769 }
770 if (done == 0) continue;
771 images->width = x + 1;
772 break;
773 }
774
775 for (int y = 0 ; y < images->height ; y++)
776 for (int x = 0 ; x < images->width ; x++)
777 *colors++ = mirai_digits[i][y][x] == 0 ? 0 : 108;
778
779 images++;
780 }
781
782 for (int c = 0 ; c < 2 ; c++)
783 for (int i = 0 ; i < 26 ; i++)
784 {
785 mirai_glyphs[i + 26 * c + 10] = images;
786 images->colors = colors;
787 images->height = 15;
788
789 for (int x = 1 ; x < 12 ; x++)
790 {
791 int done = 1;
792 for (int y = 0 ; y < images->height ; y++)
793 {
794 if (mirai_letters[i][y * 2 + c][x] != 0)
795 {
796 done = 0;
797 break;
798 }
799 }
800 if (done == 0) continue;
801 images->width = x + 1;
802 break;
803 }
804
805 for (int y = 0 ; y < images->height ; y++)
806 for (int x = 0 ; x < images->width ; x++)
807 *colors++ = mirai_letters[i][y * 2 + c][x] == 0 ? 0 : 108;
808
809 images++;
810 }
811
812 if (colors != last_color) return 0;
813 if (images != last_image - 1) return 0;
814 if (animations != last_animation) return 0;
815
816 done = 1;
817 return mirai_images;
818}