Mirai's Miscellaneous Misadventures

M48 / chapters / loader / setup.c

/* license: AGPLv3 or later */
/* copyright 2023 zamfofex */

#include <mimimi-chapters.h>

struct mimimi_loader_chapter_info
{
	char *name, *description;
	void (*start)(void *chapter, struct mimimi_engine *engine);
	void (*tick)(void *chapter, unsigned char left, unsigned char right);
};

static struct mimimi_loader_chapter_info mimimi_loader_chapters[] =
{
	{
		"test chapter", "This is a chapter to test the foundations of the game and its engine. It features the characters Mango and Pepper!",
		&mimimi_test, &mimimi_test_tick,
	},
	{
		"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.",
		&mimimi_chapter_I, &mimimi_chapter_I_tick,
	},
};

static void mimimi_loader_fill(struct mimimi_image *image, unsigned char color)
{
	int i;
	for (i = 0 ; i < image->width * image->height ; i++)
		image->colors[i] = color;
}

void mimimi_loader_tick(void *data, unsigned char left, unsigned char right)
{
	static int count = sizeof mimimi_loader_chapters / sizeof *mimimi_loader_chapters;
	
	struct mimimi_loader *loader;
	struct mimimi_loader_data *chapter;
	void *chapter_data;
	int i;
	int x, y;
	int width, height;
	
	loader = data;
	
	if (loader->started == 2)
	{
		chapter_data = &loader->chapter;
		(*mimimi_loader_chapters[loader->index].tick)(chapter_data, left, right);
		return;
	}
	
	if (left != 0 && right != 0)
	{
		loader->started = 1;
	}
	
	chapter = &loader->chapter.data;
	
	if (loader->started == 1)
	{
		if (left == 0 && right == 0)
		{
			(*chapter->engine->invalidate)(chapter->engine->data, chapter->background);
			for (i = 0 ; i < count ; i++)
				(*chapter->engine->invalidate)(chapter->engine->data, chapter->textures[i]);
			
			chapter_data = &loader->chapter;
			loader->started = 2;
			(*mimimi_loader_chapters[loader->index].start)(chapter_data, loader->chapter.data.engine);
			(*mimimi_loader_chapters[loader->index].tick)(chapter_data, left, right);
			
			return;
		}
	}
	else
	{
		if (left == 0)
		if (chapter->previous_direction == -1)
		if (loader->index > 0)
			loader->index--;
		
		if (right == 0)
		if (chapter->previous_direction == 1)
		if (loader->index < count - 1)
			loader->index++;
		
		chapter->previous_direction = 0;
		if (left != 0) chapter->previous_direction = -1;
		if (right != 0) chapter->previous_direction = 1;
	}
	
	width = chapter->images[0].width;
	height = chapter->images[0].height;
	
	chapter->x *= 3;
	chapter->x += (width + 8) * loader->index;
	chapter->x /= 4;
	
	(*chapter->engine->stamp)(chapter->engine->data, 0, 0, chapter->background);
	for (i = 0 ; i < count ; i++)
	{
		x = chapter->engine->size.width / 2 - width / 2;
		y = chapter->engine->size.height / 2 - height / 2;
		x += (width + 8) * i - chapter->x;
		(*chapter->engine->stamp)(chapter->engine->data, x, y, chapter->textures[i]);
	}
}

void mimimi_loader(void *data, struct mimimi_engine *engine)
{
	static int count = sizeof mimimi_loader_chapters / sizeof *mimimi_loader_chapters;
	static unsigned char background_colors[512 * 256];
	static char title[] = "select chapter";
	static char note[] = "press [left] and [right] at the same time to select";
	
	struct mimimi_loader *loader;
	struct mimimi_loader_data *chapter;
	int i;
	unsigned char *colors;
	struct mimimi_image *image;
	struct mimimi_loader_chapter_info *info;
	int y;
	int width;
	
	loader = data;
	chapter = &loader->chapter.data;
	
	loader->index = 0;
	loader->started = 0;
	chapter->engine = engine;
	chapter->previous_direction = 0;
	chapter->x = 0;
	
	chapter->background_image.colors = background_colors;
	chapter->background_image.width = 512;
	chapter->background_image.height = 256;
	mimimi_loader_fill(&chapter->background_image, 0x16);
	
	width = mimimi_measure_paragraph(mimimi_font, title);
	mimimi_draw_paragraph(mimimi_font, title, &chapter->background_image, chapter->background_image.width / 2 - width / 2, 32, 0xD);
	
	width = mimimi_measure_paragraph(mimimi_font, note);
	mimimi_draw_paragraph(mimimi_font, note, &chapter->background_image, chapter->background_image.width / 2 - width / 2, chapter->background_image.height - 32 - 16, 0xD);
	
	chapter->background = (*chapter->engine->texture)(chapter->engine->data, &chapter->background_image);
	
	colors = chapter->colors;
	
	for (i = 0 ; i < count ; i++)
	{
		info = mimimi_loader_chapters + i;
		image = chapter->images + i;
		image->width = 192;
		image->height = 96;
		image->colors = colors;
		colors += image->width * image->height;
		mimimi_loader_fill(image, 0xD);
		y = mimimi_draw_text(mimimi_font, info->name, 172, 18, image, 8, 2, 4);
		mimimi_draw_text(mimimi_font, info->description, 172, 18, image, 8, y + 4, 4);
		chapter->textures[i] = (*engine->texture)(engine->data, image);
	}
}