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