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