Mirai's Miscellaneous Misadventures

M51 / chapters / loader / setup.c

1/* license: AGPLv3 or later */
2/* copyright 2024 zamfofex */
3
4#include <stdlib.h>
5
6#include <mimimi-chapters.h>
7
8struct mimimi_loader_chapter_info
9{
10	char *name, *description;
11	void *(*start)(struct mimimi_engine *engine);
12	void (*tick)(void *chapter, unsigned char left, unsigned char right);
13};
14
15static struct mimimi_loader_chapter_info mimimi_loader_chapters[] =
16{
17	{
18		"test chapter", "This is a chapter to test the foundations of the game and its engine. It features the characters Mango and Pepper!",
19		&mimimi_test, &mimimi_test_tick,
20	},
21	{
22		"chapter I", "This is the first chapter of the game! It is currently still a work-in-progress, but strives to eventually come to tell a story.",
23		&mimimi_chapter_I, &mimimi_chapter_I_tick,
24	},
25};
26
27static void mimimi_loader_fill(struct mimimi_image *image, unsigned char color)
28{
29	int i;
30	for (i = 0 ; i < image->width * image->height ; i++)
31		image->colors[i] = color;
32}
33
34void mimimi_loader_tick(void *data, unsigned char left, unsigned char right)
35{
36	static int count = sizeof mimimi_loader_chapters / sizeof *mimimi_loader_chapters;
37	
38	struct mimimi_loader *loader;
39	int i;
40	int x, y;
41	int width, height;
42	
43	loader = data;
44	
45	loader->engine->size.width = 512;
46	loader->engine->size.height = 256;
47	
48	if (loader->started == 2)
49	{
50		(*mimimi_loader_chapters[loader->index].tick)(loader->chapter, left, right);
51		return;
52	}
53	
54	if (left != 0 && right != 0)
55		loader->started = 1;
56	
57	if (loader->started == 1)
58	{
59		if (left == 0 && right == 0)
60		{
61			(*loader->engine->invalidate)(loader->engine->data, loader->background);
62			for (i = 0 ; i < count ; i++)
63				(*loader->engine->invalidate)(loader->engine->data, loader->textures[i]);
64			
65			loader->started = 2;
66			loader->chapter = (*mimimi_loader_chapters[loader->index].start)(loader->engine);
67			(*mimimi_loader_chapters[loader->index].tick)(loader->chapter, left, right);
68			
69			return;
70		}
71	}
72	else
73	{
74		if (left == 0)
75		if (loader->previous_direction == -1)
76		if (loader->index > 0)
77			loader->index--;
78		
79		if (right == 0)
80		if (loader->previous_direction == 1)
81		if (loader->index < count - 1)
82			loader->index++;
83		
84		loader->previous_direction = 0;
85		if (left != 0) loader->previous_direction = -1;
86		if (right != 0) loader->previous_direction = 1;
87	}
88	
89	width = loader->images[0].width;
90	height = loader->images[0].height;
91	
92	loader->x *= 3;
93	loader->x += (width + 8) * loader->index;
94	loader->x /= 4;
95	
96	(*loader->engine->stamp)(loader->engine->data, 0, 0, loader->background);
97	for (i = 0 ; i < count ; i++)
98	{
99		x = loader->engine->size.width / 2 - width / 2;
100		y = loader->engine->size.height / 2 - height / 2;
101		x += (width + 8) * i - loader->x;
102		(*loader->engine->stamp)(loader->engine->data, x, y, loader->textures[i]);
103	}
104}
105
106void *mimimi_loader(struct mimimi_engine *engine)
107{
108	static int count = sizeof mimimi_loader_chapters / sizeof *mimimi_loader_chapters;
109	static unsigned char background_colors[512 * 256];
110	static char title[] = "select chapter";
111	static char note[] = "press [left] and [right] at the same time to select";
112	
113	struct mimimi_loader *loader;
114	int i;
115	unsigned char *colors;
116	struct mimimi_image *image;
117	struct mimimi_loader_chapter_info *info;
118	int y;
119	int width;
120	
121	engine->size.width = 256;
122	engine->size.height = 128;
123	
124	loader = malloc(sizeof *loader);
125	if (loader == NULL) exit(1);
126	
127	loader->index = 0;
128	loader->started = 0;
129	loader->engine = engine;
130	loader->previous_direction = 0;
131	loader->x = 0;
132	
133	loader->background_image.colors = background_colors;
134	loader->background_image.width = 512;
135	loader->background_image.height = 256;
136	mimimi_loader_fill(&loader->background_image, 0x16);
137	
138	width = mimimi_measure_paragraph(mimimi_font, title);
139	mimimi_draw_paragraph(mimimi_font, title, &loader->background_image, loader->background_image.width / 2 - width / 2, 32, 0xD);
140	
141	width = mimimi_measure_paragraph(mimimi_font, note);
142	mimimi_draw_paragraph(mimimi_font, note, &loader->background_image, loader->background_image.width / 2 - width / 2, loader->background_image.height - 32 - 16, 0xD);
143	
144	loader->background = (*loader->engine->texture)(loader->engine->data, &loader->background_image);
145	
146	colors = loader->colors;
147	
148	for (i = 0 ; i < count ; i++)
149	{
150		info = mimimi_loader_chapters + i;
151		image = loader->images + i;
152		image->width = 192;
153		image->height = 96;
154		image->colors = colors;
155		colors += image->width * image->height;
156		mimimi_loader_fill(image, 0xD);
157		y = mimimi_draw_text(mimimi_font, info->name, 172, 18, image, 8, 2, 4);
158		mimimi_draw_text(mimimi_font, info->description, 172, 18, image, 8, y + 4, 4);
159		loader->textures[i] = (*engine->texture)(engine->data, image);
160	}
161	
162	return loader;
163}