Mirai's Miscellaneous Misadventures
M52 / core / displays.c
1
2
3
4#include <stdlib.h>
5#include "../mimimi.h"
6
7void mimimi_camera_stamp(struct mimimi_image *target, struct mimimi_position *camera, int x, int y, int z, struct mimimi_image *source)
8{
9 z += 8;
10 if (z <= 0) return;
11
12 x -= camera->x;
13 x = mimimi_div_up(x, z);
14 x += target->width / 2;
15
16 y -= camera->y;
17 y = mimimi_div_up(y, z);
18 y += target->height / 2;
19
20 mimimi_stamp(target, x, y, source);
21}
22
23void mimimi_display_tick(struct mimimi_display *display, struct mimimi_image *target, struct mimimi_sprite *sprite)
24{
25 struct mimimi_appearance *appearance;
26 struct mimimi_position *position;
27 struct mimimi_physics *physics;
28 struct mimimi_life *life;
29 struct mimimi_walk *walk;
30 int dx, dy;
31 struct mimimi_video_set *videos;
32 struct mimimi_video *video;
33 struct mimimi_image *image;
34 int x, y;
35
36 appearance = &display->appearance;
37
38 position = &sprite->position;
39 physics = &sprite->physics;
40 life = &sprite->life;
41 walk = &sprite->walk;
42
43 x = display->width * -8;
44 y = display->height * -8;
45
46 if (life->knocked_time == 0 && walk->direction != 0)
47 display->direction = walk->direction;
48
49 dx = physics->dx;
50 dy = physics->dy;
51 videos = &appearance->right;
52
53 if (display->direction == 1)
54 {
55 videos = &appearance->left;
56 dx *= -1;
57 }
58
59 if (dx > 8191) dx = 8191;
60 if (dx < 0) dx = 0;
61
62 if (life->knocked_time == 0)
63 {
64 if (physics->airborne != 0)
65 {
66 if (dy < -8191) dy = -8191;
67 if (dy > 8191) dy = 8191;
68 dy += 8191;
69
70 video = videos->jumping + dx * videos->jumping_video_count / 8192;
71 image = video->images + dy * video->count / 16384;
72
73 mimimi_camera_stamp(target, display->camera, position->x + x, position->y + y, 0, image);
74 return;
75 }
76
77 if (physics->airborne != 0)
78 {
79 image = videos->jumping->images + dx * videos->jumping->count / 8192;
80 mimimi_camera_stamp(target, display->camera, position->x + x, position->y + y, 0, image);
81 return;
82 }
83
84 video = videos->standing + dx * videos->standing_video_count / 8192;
85 display->animation_time += dx / 1024;
86 }
87 else
88 {
89 if (physics->airborne == 0)
90 video = videos->knocked,
91 y += 212;
92 else
93 video = videos->falling,
94 y += 128;
95
96 if (dy < 0) dy = 0;
97 display->animation_time += dy / 2048;
98 }
99
100
101 display->animation_time &= 0xFF;
102
103 image = video->images + display->animation_time * video->count / 256;
104 mimimi_camera_stamp(target, display->camera, position->x + x, position->y + y, 0, image);
105}
106
107void mimimi_background_tick(struct mimimi_background *background, struct mimimi_image *image, struct mimimi_position *camera, struct mimimi_position *offset)
108{
109 mimimi_camera_stamp(image, camera, background->x + offset->x, background->y + offset->y, background->z, &background->image);
110}
111
112static void mimimi_populate_video_set(struct mimimi_video_set *set)
113{
114 static int video_count = 8;
115 static int image_count = 8;
116 static int width = 48;
117 static int height = 48;
118
119 int i, j, k;
120 struct mimimi_video *videos, *standing, *knocked, *falling, *jumping;
121 struct mimimi_image *images, *image;
122 unsigned char *colors;
123
124 videos = malloc(sizeof *videos * (video_count * 2 + 2));
125 images = malloc(sizeof *images * (image_count * video_count * 2 + 2));
126 colors = malloc((image_count * video_count * 2 + 2) * 48 * 48);
127
128 if (videos == NULL) exit(1);
129 if (images == NULL) exit(1);
130 if (colors == NULL) exit(1);
131
132 set->standing = videos;
133 set->standing_video_count = video_count;
134 videos += video_count;
135
136 set->jumping = videos;
137 set->jumping_video_count = video_count;
138 videos += video_count;
139
140 for (i = 0 ; i < video_count ; i++)
141 {
142 standing = set->standing + i;
143 standing->count = image_count;
144 standing->images = images;
145 images += image_count;
146
147 for (j = 0 ; j < image_count ; j++)
148 {
149 image = standing->images + j;
150 image->width = width;
151 image->height = height;
152 image->colors = colors;
153 colors += width * height;
154 for (k = 0 ; k < width * height ; k++) image->colors[k] = 0;
155 }
156
157 jumping = set->jumping + i;
158 jumping->count = image_count;
159 jumping->images = images;
160 images += image_count;
161
162 for (j = 0 ; j < image_count ; j++)
163 {
164 image = jumping->images + j;
165 image->width = width;
166 image->height = height;
167 image->colors = colors;
168 colors += width * height;
169 for (k = 0 ; k < width * height ; k++) image->colors[k] = 0;
170 }
171 }
172
173 knocked = videos++;
174 knocked->count = 1;
175 knocked->images = images++;
176 knocked->images[0].width = width;
177 knocked->images[0].height = height;
178 knocked->images[0].colors = colors;
179 colors += width * height;
180 for (i = 0 ; i < width * height ; i++) knocked->images[0].colors[i] = 0;
181
182 falling = videos++;
183 falling->count = 1;
184 falling->images = images++;
185 falling->images[0].width = width;
186 falling->images[0].height = height;
187 falling->images[0].colors = colors;
188 colors += width * height;
189 for (i = 0 ; i < width * height ; i++) falling->images[0].colors[i] = 0;
190
191 set->knocked = knocked;
192 set->falling = falling;
193}
194
195static void mimimi_populate_appearance(struct mimimi_display *display, struct mimimi_model *model)
196{
197 mimimi_populate_video_set(&display->appearance.left);
198 mimimi_populate_video_set(&display->appearance.right);
199
200 mimimi_appearance(&display->appearance, model, 24, 37);
201}
202
203void mimimi_display(struct mimimi_display *display, struct mimimi_model *model)
204{
205 display->animation_time = 0;
206 display->direction = 1;
207 display->width = 24;
208 display->height = 48;
209 mimimi_populate_appearance(display, model);
210}