Mirai's Miscellaneous Misadventures

M53 / chapter-I / main.c

1/* license: AGPLv3 or later */
2/* copyright 2024 zamfofex */
3
4#include <stdlib.h>
5#include "../mimimi.h"
6#include "ground.h"
7#include "background.h"
8
9struct mimimi_chapter_I {
10    unsigned char colors[1024 * 512];
11    struct mimimi_history history;
12    int progression;
13    struct mimimi_toast_dialogue dialogue0, dialogue1;
14    struct mimimi_toast_dialogue tutorial, dialogue;
15    struct mimimi_stage stage;
16};
17
18static void mimimi_chapter_I_background(struct mimimi_chapter_I *chapter)
19{
20    int i;
21    struct mimimi_area *area;
22    struct mimimi_image *image;
23
24    for (i = 0; i < chapter->stage.area_count; i++) {
25        area = chapter->stage.areas + i;
26        area->background_count = 1;
27        area->backgrounds = malloc(sizeof *area->backgrounds);
28        if (area->backgrounds == NULL)
29            exit(1);
30        mimimi_background(&area->backgrounds[0].image, area->ground,
31            mimimi_chapter_I_colors[i]);
32        area->backgrounds[0].x = 0;
33        area->backgrounds[0].y = 0;
34        area->backgrounds[0].z = 0;
35    }
36
37    area = chapter->stage.areas;
38
39    image = &area->backgrounds[0].image;
40    free(image->colors);
41    image->width = mimimi_chapter_I_background_width;
42    image->height = mimimi_chapter_I_background_height;
43    image->colors = malloc(image->width * image->height);
44    if (image->colors == NULL)
45        exit(1);
46    mimimi_unpack_bits(image->width * image->height, image->colors,
47        mimimi_chapter_I_background_packed);
48    area->backgrounds[0].x = -88;
49    area->backgrounds[0].y = 0;
50    area->backgrounds[0].z = 0;
51
52    area->foregrounds = malloc(sizeof *area->foregrounds);
53    if (area->foregrounds == NULL)
54        exit(1);
55
56    image = &area->foregrounds[0].image;
57    image->width = mimimi_chapter_I_foreground_width;
58    image->height = mimimi_chapter_I_foreground_height;
59    image->colors = malloc(image->width * image->height);
60    if (image->colors == NULL)
61        exit(1);
62    mimimi_unpack_bits(image->width * image->height, image->colors,
63        mimimi_chapter_I_foreground_packed);
64    area->foreground_count = 1;
65    area->foregrounds[0].x = 0;
66    area->foregrounds[0].y = 0;
67    area->foregrounds[0].z = 0;
68}
69
70static void mimimi_chapter_I_size(struct mimimi_image *image,
71    struct mimimi_input *input)
72{
73    int width, height;
74
75    if (input->size.width / input->size.height < 2) {
76        height = 256;
77        width = height * input->size.width / input->size.height;
78    } else {
79        width = 512;
80        height = width * input->size.height / input->size.width;
81    }
82
83    if (width < 256) {
84        width = 256;
85        height = width * input->size.height / input->size.width;
86        if (height > 384)
87            height = 384;
88    }
89    if (height < 192) {
90        height = 192;
91        width = height * input->size.width / input->size.height;
92        if (width > 512)
93            width = 512;
94    }
95
96    image->width = width;
97    image->height = height;
98}
99
100static void mimimi_chapter_I_tick(void *data, struct mimimi_output *output,
101    struct mimimi_input *input)
102{
103    struct mimimi_chapter_I *chapter;
104    struct mimimi_sprite *player;
105
106    chapter = data;
107    player = chapter->stage.sprites;
108
109    mimimi_chapter_I_size(&output->image, input);
110    output->image.colors = chapter->colors;
111
112    mimimi_history_tick(&chapter->history, input->left, input->right);
113    mimimi_controls_tick(&chapter->stage.sprites[0].walk,
114        &chapter->history, &mimimi_jump, chapter->stage.sprites);
115    mimimi_stage_tick(&chapter->stage, &output->image);
116
117    if (chapter->progression == 0) {
118        if (player->position.x < -0x1800)
119            chapter->progression++;
120    }
121    if (chapter->progression == 1) {
122        if (mimimi_toast_dialogue_tick(&chapter->tutorial,
123                &output->image) != 0)
124            chapter->progression++;
125    }
126    if (chapter->progression == 2) {
127        if (player->position.x < -0x5600)
128            chapter->progression++;
129    }
130    if (chapter->progression == 3) {
131        if (mimimi_toast_dialogue_tick(&chapter->dialogue0,
132                &output->image) != 0)
133            chapter->progression++;
134    }
135    if (chapter->progression == 4) {
136        if (chapter->stage.platform_sets[0].angular_platforms[0].physics.
137            other.airborne == 0)
138            chapter->progression++;
139    }
140    if (chapter->progression == 5) {
141        if (mimimi_toast_dialogue_tick(&chapter->dialogue1,
142                &output->image) != 0)
143            chapter->progression++;
144    }
145    if (chapter->progression == 6) {
146        if (player->position.y <= -0x2C00 && player->physics.airborne == 0)
147            chapter->progression++;
148    }
149    if (chapter->progression == 7) {
150        if (mimimi_toast_dialogue_tick(&chapter->dialogue,
151                &output->image) != 0)
152            chapter->progression++;
153    }
154}
155
156int main(void)
157{
158    static unsigned char colors0[] = { 0, 0x6B };
159    static unsigned char colors1[] = { 0, 8 };
160    static struct mimimi_ground ground0 =
161        { 4, 3, { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 } };
162    static struct mimimi_ground ground1 =
163        { 5, 3, { 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 } };
164    static struct mimimi_dialogue_paragraph paragraphs[] = {
165        { NULL, "Mirai", "There seems to be nothing for me to do. Hmmm... Maybe I can find something to do later."},
166        { NULL, "Ryouna", "Hear that? If you come back later, then maybe you can find something to do!" },
167        { NULL, "Ryoubi", "Who are you talking to? Are you stupid or something?" },
168        { NULL, "Ryouna", "Aaah! Ryoubi, I really like when you yell insults at me!" },
169        { NULL, "Mirai", "Wha-? What are you two doing here?" },
170        { NULL, "Haruka", "Hehe, don't worry about it!" },
171    };
172    static struct mimimi_dialogue_paragraph paragraphs0[] = {
173        { NULL, "Haruka", "Press a direction twice to jump!" },
174        { NULL, "Mirai", "Hmm, I wonder what's on top of those platforms..." },
175        { NULL, "Mirai", "Oh, it seems like I need to be quick if I want to get to the top." },
176    };
177
178    struct mimimi_dialogue dialogue;
179    struct mimimi_chapter_I *chapter;
180    struct mimimi_platform_set *platforms;
181    struct mimimi_image *image;
182
183    paragraphs0[0].model = mimimi_haruka_flash;
184    paragraphs0[1].model = mimimi_mirai_flash;
185    paragraphs0[2].model = mimimi_mirai_flash;
186    paragraphs[0].model = mimimi_mirai_flash;
187    paragraphs[1].model = mimimi_ryouna_flash;
188    paragraphs[2].model = mimimi_ryoubi_flash;
189    paragraphs[3].model = mimimi_ryouna_flash;
190    paragraphs[4].model = mimimi_mirai_flash;
191    paragraphs[5].model = mimimi_haruka_flash;
192
193    chapter = malloc(sizeof *chapter);
194    if (chapter == NULL)
195        exit(1);
196
197    mimimi_stage(&chapter->stage, mimimi_chapter_I_stage,
198        sizeof mimimi_chapter_I_stage / sizeof *mimimi_chapter_I_stage);
199    mimimi_chapter_I_background(chapter);
200
201    chapter->progression = 0;
202
203    dialogue.count = 1;
204    dialogue.paragraphs = paragraphs0;
205    mimimi_toast_dialogue(&chapter->tutorial, &dialogue);
206
207    dialogue.count = 1;
208    dialogue.paragraphs = paragraphs0 + 1;
209    mimimi_toast_dialogue(&chapter->dialogue0, &dialogue);
210
211    dialogue.count = 1;
212    dialogue.paragraphs = paragraphs0 + 2;
213    mimimi_toast_dialogue(&chapter->dialogue1, &dialogue);
214
215    dialogue.count = sizeof paragraphs / sizeof *paragraphs;
216    dialogue.paragraphs = paragraphs;
217    mimimi_toast_dialogue(&chapter->dialogue, &dialogue);
218
219    mimimi_spawn(&chapter->stage, mimimi_mirai_flash, 0, 0, 80, 250);
220
221    image = malloc(sizeof *image);
222    if (image == NULL)
223        return 1;
224
225    mimimi_background(image, &ground0, colors0);
226
227    platforms = mimimi_add_platform_set(&chapter->stage);
228    platforms->angular_weight = 512;
229    platforms->strength = 128;
230
231    mimimi_spawn_angular_platform(&chapter->stage, platforms, &ground0,
232        image, -0x5800, -0x1C80, -80, 256, 1024);
233    mimimi_spawn_angular_platform(&chapter->stage, platforms, &ground0,
234        image, -0x5800, -0x1C80, -80, 256, 2048);
235    mimimi_spawn_angular_platform(&chapter->stage, platforms, &ground0,
236        image, -0x5800, -0x1C80, -80, 256, 3072);
237
238    platforms = mimimi_add_platform_set(&chapter->stage);
239    platforms->angular_weight = 512;
240    platforms->strength = 128;
241
242    mimimi_spawn_angular_platform(&chapter->stage, platforms, &ground0,
243        image, -0x6500, -0x2100, 80, 256, 1024);
244    mimimi_spawn_angular_platform(&chapter->stage, platforms, &ground0,
245        image, -0x6500, -0x2100, 80, 256, 2048);
246    mimimi_spawn_angular_platform(&chapter->stage, platforms, &ground0,
247        image, -0x6500, -0x2100, 80, 256, 3072);
248
249    image = malloc(sizeof *image);
250    if (image == NULL)
251        return 1;
252
253    mimimi_background(image, &ground1, colors1);
254
255    platforms = mimimi_add_platform_set(&chapter->stage);
256    platforms->strength = 0;
257    platforms->min = 0;
258    platforms->max = 1024;
259
260    mimimi_spawn_linear_platform(&chapter->stage, platforms, &ground1,
261        image, -0x4B00, -0x700, 256);
262    mimimi_spawn_linear_platform(&chapter->stage, platforms, &ground1,
263        image, -0x4800, -0x800, -256);
264    mimimi_spawn_linear_platform(&chapter->stage, platforms, &ground1,
265        image, -0x4F00, -0xC00, 256);
266    mimimi_spawn_linear_platform(&chapter->stage, platforms, &ground1,
267        image, -0x4F00, -0xD00, -256);
268
269    chapter->history.left = 0;
270    chapter->history.right = 0;
271
272    mimimi_main(&mimimi_chapter_I_tick, chapter);
273    return 1;
274}