Mirai's Miscellaneous Misadventures
M45 / chapters / chapter-I / setup.c
1
2
3
4#include <mimimi-chapters.h>
5
6#include "ground.c"
7#include "background.c"
8#include "foreground.c"
9
10static void mimimi_chapter_I_video_set(struct mimimi_test_video_set *tset, struct mimimi_video_set *set)
11{
12 static int video_count = 8;
13 static int image_count = 8;
14 static int width = 48;
15 static int height = 48;
16
17 int i, j, k;
18 struct mimimi_video *videos, *standing, *knocked, *falling, *jumping;
19 struct mimimi_image *images, *image;
20 unsigned char *colors;
21 void **textures;
22
23 videos = tset->videos;
24 images = tset->images;
25 colors = tset->colors;
26 textures = tset->textures;
27
28 set->standing = videos;
29 set->standing_video_count = video_count;
30 videos += video_count;
31
32 set->jumping = videos;
33 set->jumping_video_count = video_count;
34 videos += video_count;
35
36 for (i = 0 ; i < video_count ; i++)
37 {
38 standing = set->standing + i;
39 standing->count = image_count;
40 standing->images = images;
41 images += image_count;
42 standing->textures = textures;
43 textures += image_count;
44
45 for (j = 0 ; j < image_count ; j++)
46 {
47 image = standing->images + j;
48 image->width = width;
49 image->height = height;
50 image->colors = colors;
51 colors += width * height;
52 for (k = 0 ; k < width * height ; k++) image->colors[k] = 0;
53 }
54
55 jumping = set->jumping + i;
56 jumping->count = image_count;
57 jumping->images = images;
58 images += image_count;
59 jumping->textures = textures;
60 textures += image_count;
61
62 for (j = 0 ; j < image_count ; j++)
63 {
64 image = jumping->images + j;
65 image->width = width;
66 image->height = height;
67 image->colors = colors;
68 colors += width * height;
69 for (k = 0 ; k < width * height ; k++) image->colors[k] = 0;
70 }
71 }
72
73 knocked = videos++;
74 knocked->count = 1;
75 knocked->images = images++;
76 knocked->images[0].width = width;
77 knocked->images[0].height = height;
78 knocked->images[0].colors = colors;
79 knocked->textures = textures++;
80 colors += width * height;
81 for (i = 0 ; i < width * height ; i++) knocked->images[0].colors[i] = 0;
82
83 falling = videos++;
84 falling->count = 1;
85 falling->images = images++;
86 falling->images[0].width = width;
87 falling->images[0].height = height;
88 falling->images[0].colors = colors;
89 colors += width * height;
90 falling->textures = textures++;
91 for (i = 0 ; i < width * height ; i++) falling->images[0].colors[i] = 0;
92
93 set->knocked = knocked;
94 set->falling = falling;
95}
96
97static void mimimi_chapter_I_appearance(struct mimimi_test_sprite *sprite, struct mimimi_engine *engine)
98{
99 mimimi_chapter_I_video_set(&sprite->left, &sprite->appearance.left);
100 mimimi_chapter_I_video_set(&sprite->right, &sprite->appearance.right);
101
102 mimimi_appearance(&sprite->appearance, sprite->model, 24, 37);
103 mimimi_prepare_appearance(&sprite->appearance, engine);
104}
105
106static void mimimi_chapter_I_origin(struct mimimi_ground *ground, struct mimimi_position *position)
107{
108 for (position->y = 0 ; position->y < ground->height ; position->y++)
109 for (position->x = 0 ; position->x < ground->width ; position->x++)
110 {
111 if (ground->tiles[position->x + position->y * ground->width] == 2)
112 return;
113 }
114}
115
116static void mimimi_chapter_I_sprite(struct mimimi_test_sprite *sprite, struct mimimi_model *model, struct mimimi_chapter_I *chapter)
117{
118 sprite->model = model;
119 sprite->display.camera = &chapter->clamped_camera.output;
120 sprite->display.sprite = &sprite->sprite;
121 sprite->display.appearance = &sprite->appearance;
122 sprite->display.animation_time = 0;
123 sprite->display.direction = 1;
124 sprite->display.width = 24;
125 sprite->display.height = 48;
126 mimimi_sprite(&sprite->sprite, mimimi_chapter_I_ground, 0, 0, 80, 250);
127 mimimi_chapter_I_appearance(sprite, chapter->engine);
128}
129
130static void mimimi_chapter_I_player_tick(struct mimimi_chapter_I *chapter)
131{
132 mimimi_controls_tick(&chapter->player.sprite.walk, &chapter->history, &mimimi_jump, &chapter->player.sprite);
133 mimimi_sprite_tick(&chapter->player.sprite);
134}
135
136static void mimimi_chapter_I_unpack_bits(int size, unsigned char *unpacked, unsigned char *packed)
137{
138 int i, j, k, n;
139
140 i = 0;
141 j = 0;
142
143 while (j < size)
144 {
145 n = packed[i++];
146 if (n == 128) continue;
147 if (n > 128) n -= 256;
148
149 if (n > 0)
150 {
151 for (k = 0 ; k <= n ; k++)
152 unpacked[j++] = packed[i++];
153 }
154 else
155 {
156 for (k = 0 ; k <= -n ; k++)
157 unpacked[j++] = packed[i];
158 i++;
159 }
160 }
161}
162
163static void mimimi_chapter_I_stamp(struct mimimi_image *image, struct mimimi_image *source, int x, int y)
164{
165 int x0, y0;
166 for (y0 = 0 ; y0 < source->height ; y0++)
167 for (x0 = 0 ; x0 < source->width ; x0++)
168 image->colors[(x0 + x) + (y0 + y) * image->width] = source->colors[x0 + y0 * source->width];
169}
170
171static void mimimi_chapter_I_background(struct mimimi_chapter_I *chapter)
172{
173 static unsigned char colors[] = {6, 2, 2};
174
175 int x, y;
176 unsigned char color;
177 int size;
178
179 chapter->background_image.colors = chapter->background_colors;
180 chapter->background_image.width = mimimi_chapter_I_ground->width * 16;
181 chapter->background_image.height = mimimi_chapter_I_ground->height * 16;
182
183 for (y = 0 ; y < chapter->background_image.height ; y++)
184 for (x = 0 ; x < chapter->background_image.width ; x++)
185 {
186 color = colors[mimimi_ground_tile(mimimi_chapter_I_ground, x / 16, y / 16)];
187 chapter->background_image.colors[x + y * chapter->background_image.width] = color;
188 }
189
190 chapter->custom_background.colors = chapter->colors;
191 chapter->custom_background.width = mimimi_chapter_I_background_width;
192 chapter->custom_background.height = mimimi_chapter_I_background_height;
193 size = chapter->custom_background.width * chapter->custom_background.height;
194
195 mimimi_chapter_I_unpack_bits(size, chapter->colors, mimimi_chapter_I_background_packed);
196
197 mimimi_chapter_I_stamp(&chapter->background_image, &chapter->custom_background, (chapter->origin.x - 36) * 16 + 5, (chapter->origin.y - 10) * 16);
198
199 chapter->background.texture = (*chapter->engine->texture)(chapter->engine->data, &chapter->background_image);
200 chapter->background.camera = &chapter->clamped_camera.output;
201 chapter->background.z = 0;
202}
203
204static void mimimi_chapter_I_foreground(struct mimimi_chapter_I *chapter)
205{
206 int size;
207
208 chapter->foreground_image.colors = chapter->colors;
209 chapter->foreground_image.width = mimimi_chapter_I_foreground_width;
210 chapter->foreground_image.height = mimimi_chapter_I_foreground_height;
211 size = chapter->foreground_image.width * chapter->foreground_image.height;
212
213 mimimi_chapter_I_unpack_bits(size, chapter->colors, mimimi_chapter_I_foreground_packed);
214
215 chapter->foreground.texture = (*chapter->engine->texture)(chapter->engine->data, &chapter->foreground_image);
216 chapter->foreground.camera = &chapter->clamped_camera.output;
217 chapter->foreground.z = 0;
218}
219
220static void mimimi_chapter_I_camera(struct mimimi_chapter_I *chapter)
221{
222 static struct mimimi_clamped_camera_threshold thresholds[] =
223 {
224 {-166, 0, 0},
225 {-134, -1000, -5},
226 {-35, -13, 5},
227 {8, 2, 2},
228 {1000, 1, 1},
229 };
230
231 chapter->clamped_camera.position = &chapter->player.sprite.position;
232 chapter->clamped_camera.input = &chapter->camera;
233 chapter->clamped_camera.thresholds = thresholds;
234 chapter->clamped_camera.count = sizeof thresholds / sizeof *thresholds;
235}
236
237static void mimimi_chapter_I_offset(struct mimimi_chapter_I *chapter)
238{
239 static struct mimimi_offset_threshold thresholds[] =
240 {
241 {-134, {-29824, -768}},
242 {-35, {-12800, 2432}},
243 {8, {0, 0}},
244 };
245
246 chapter->offset.sprite = &chapter->player.sprite;
247 chapter->offset.thresholds = thresholds;
248 chapter->offset.count = sizeof thresholds / sizeof *thresholds;
249}
250
251static void mimimi_chapter_I_background_tick(struct mimimi_chapter_I *chapter)
252{
253 chapter->background.x = chapter->player.sprite.offset.x;
254 chapter->background.y = chapter->player.sprite.offset.y;
255 mimimi_background_tick(&chapter->background, chapter->engine);
256}
257
258static void mimimi_chapter_I_foreground_tick(struct mimimi_chapter_I *chapter)
259{
260 chapter->foreground.x = -35 * 128;
261 chapter->foreground.y = -10 * 128;
262 mimimi_background_tick(&chapter->foreground, chapter->engine);
263}
264
265static void mimimi_chapter_I_platforms(struct mimimi_chapter_I *chapter)
266{
267 static unsigned char tiles[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0};
268
269 int i;
270 void *texture;
271
272 for (i = 0 ; i < 1024 ; i++) chapter->platform_colors[i] = 1;
273 chapter->platform_image.colors = chapter->platform_colors;
274 chapter->platform_image.width = 48;
275 chapter->platform_image.height = 16;
276
277 texture = (*chapter->engine->texture)(chapter->engine->data, &chapter->platform_image);
278
279 for (i = 0 ; i < 3 ; i++)
280 {
281 mimimi_positioned_physics(&chapter->platforms[i].physics, &chapter->player.sprite.physics, &chapter->player.sprite.position);
282 chapter->platforms[i].ground.width = 5;
283 chapter->platforms[i].ground.height = 3;
284 chapter->platforms[i].ground.tiles = tiles;
285 chapter->platforms[i].texture = texture;
286 }
287
288 chapter->platforms[0].physics.transform.x = -148 * 128;
289 chapter->platforms[1].physics.transform.x = -156 * 128;
290 chapter->platforms[2].physics.transform.x = -146 * 128;
291
292 chapter->momentum.x = 0;
293 chapter->momentum.dx = 0;
294}
295
296static void mimimi_chapter_I_platforms_propagate(struct mimimi_chapter_I *chapter)
297{
298 struct mimimi_momentum *momentum;
299 struct mimimi_platform *platforms;
300
301 momentum = &chapter->momentum;
302 platforms = chapter->platforms;
303
304 if (platforms[0].physics.other.airborne == 0)
305 mimimi_linear_propagate(momentum, platforms[0].physics.transform.y, -1792, 256, 256);
306 if (platforms[1].physics.other.airborne == 0)
307 mimimi_linear_propagate(momentum, platforms[1].physics.transform.y, -3072, 256, 256);
308 if (platforms[2].physics.other.airborne == 0)
309 mimimi_linear_propagate(momentum, platforms[2].physics.transform.y, -2048, -256, 256);
310}
311
312static void mimimi_chapter_I_platforms_apply(struct mimimi_chapter_I *chapter)
313{
314 struct mimimi_momentum *momentum;
315 struct mimimi_platform *platforms;
316
317 momentum = &chapter->momentum;
318 platforms = chapter->platforms;
319
320 mimimi_linear_apply(momentum, &platforms[0].physics.transform.y, -1792, 256);
321 mimimi_linear_apply(momentum, &platforms[1].physics.transform.y, -3072, 256);
322 mimimi_linear_apply(momentum, &platforms[2].physics.transform.y, -2048, -256);
323}
324
325static void mimimi_chapter_I_platforms_tick(struct mimimi_chapter_I *chapter)
326{
327 struct mimimi_momentum *momentum;
328 struct mimimi_platform *platforms;
329 int i;
330
331 momentum = &chapter->momentum;
332 platforms = chapter->platforms;
333
334 for (i = 0 ; i < 3 ; i++)
335 if (platforms[i].physics.other.airborne == 0)
336 platforms[i].physics.transform.y += 4;
337
338 mimimi_chapter_I_platforms_propagate(chapter);
339
340 momentum->dx *= 31;
341 momentum->dx /= 32;
342 momentum->x += momentum->dx;
343
344 if (momentum->x < 0)
345 {
346 momentum->x = 0;
347 momentum->dx = 0;
348 }
349 if (momentum->x > 1024)
350 {
351 momentum->x = 1024;
352 momentum->dx = 0;
353 }
354
355 mimimi_chapter_I_platforms_apply(chapter);
356
357 for (i = 0 ; i < 3 ; i++)
358 mimimi_positioned_physics_tick(&platforms[i].physics, &platforms[i].ground);
359}
360
361static void mimimi_chapter_I_platforms_display_tick(struct mimimi_chapter_I *chapter)
362{
363 int i;
364 for (i = 0 ; i < 3 ; i++)
365 mimimi_platform_display_tick(chapter->platforms + i, &chapter->clamped_camera.output, -128, -128, chapter->engine);
366}
367
368void mimimi_chapter_I_tick(void *data, unsigned char left, unsigned char right)
369{
370 struct mimimi_chapter_I *chapter;
371
372 chapter = data;
373 mimimi_offset_tick(&chapter->offset, chapter->origin.x * 128, chapter->origin.y * 128);
374 mimimi_history_tick(&chapter->history, left, right);
375 mimimi_chapter_I_player_tick(chapter);
376 mimimi_chapter_I_platforms_tick(chapter);
377
378 mimimi_chapter_I_background_tick(chapter);
379 mimimi_chapter_I_platforms_display_tick(chapter);
380 mimimi_display_tick(&chapter->player.display, chapter->engine);
381 mimimi_chapter_I_foreground_tick(chapter);
382 mimimi_camera_tick(&chapter->camera, &chapter->player.sprite.position, 0, -512);
383 mimimi_clamped_camera_tick(&chapter->clamped_camera);
384
385 if (chapter->progression == 0)
386 {
387 if (chapter->player.sprite.position.y <= -3456 && chapter->player.sprite.physics.airborne == 0)
388 chapter->progression++;
389 }
390 if (chapter->progression == 1)
391 {
392 if (mimimi_toast_dialogue_bottom_tick(&chapter->dialogue) != 0)
393 chapter->progression++;
394 }
395}
396
397void mimimi_chapter_I(void *data, struct mimimi_engine *engine)
398{
399 struct mimimi_dialogue_paragraph paragraphs[] =
400 {
401 {0, "Mango", "Hello, world!"},
402 };
403
404 struct mimimi_dialogue dialogue;
405 struct mimimi_chapter_I *chapter;
406
407 paragraphs[0].model = mimimi_mango;
408
409 chapter = data;
410 chapter->engine = engine;
411
412 chapter->progression = 0;
413 dialogue.count = sizeof paragraphs / sizeof *paragraphs;
414 dialogue.paragraphs = paragraphs;
415 mimimi_toast_dialogue(&chapter->dialogue, &dialogue, engine);
416
417 mimimi_chapter_I_origin(mimimi_chapter_I_ground, &chapter->origin);
418 mimimi_chapter_I_sprite(&chapter->player, mimimi_mango, chapter);
419
420 chapter->history.left = 0;
421 chapter->history.right = 0;
422
423 chapter->camera = chapter->player.sprite.position;
424 chapter->camera.y -= 512;
425
426 mimimi_chapter_I_camera(chapter);
427 mimimi_chapter_I_background(chapter);
428 mimimi_chapter_I_foreground(chapter);
429
430 mimimi_chapter_I_offset(chapter);
431
432 mimimi_clamped_camera_tick(&chapter->clamped_camera);
433
434 mimimi_chapter_I_platforms(chapter);
435}