Mirai's Miscellaneous Misadventures

M17 / test / chapter.c

// copyright 2022 zamfofex
// license: AGPLv3 or later

#include <mimimi/chapters.h>
#include <mimimi/senran-kagura/characters.h>
#include <mimimi/appearances.h>
#include <mimimi/assets.h>
#include <mimimi/fonts.h>
#include <mimimi/font.h>

#include <mimimi/test.h>

#include "ground.c"

struct mimimi_test
{
	struct mimimi_game *game;
	
	struct mimimi_sprite_appearance *camera_appearance;
	struct mimimi_sprite_appearance *mirai_appearance;
	struct mimimi_sprite_appearance *ryoubi_appearance;
	struct mimimi_sprite_appearance *ryouna_appearance;
	
	struct mimimi_behavior *camera_behavior;
	struct mimimi_behavior *mirai_behavior;
	struct mimimi_behavior *ryoubi_behavior;
	struct mimimi_behavior *ryouna_behavior;
	
	struct mimimi_sprite *camera;
	struct mimimi_sprite *mirai;
	struct mimimi_sprite *ryoubi;
	struct mimimi_sprite *ryouna;
	
	struct mimimi_camera_data camera_data;
	
	struct mimimi_behave_data mirai_behave_data;
	struct mimimi_behave_data ryoubi_behave_data;
	struct mimimi_behave_data ryouna_behave_data;
	
	struct mimimi_behavior mirai_behave_data_behavior;
	struct mimimi_behavior ryoubi_behave_data_behavior;
	struct mimimi_behavior ryouna_behave_data_behavior;
	
	struct mimimi_image *background;
	struct mimimi_image *overlay;
	
	struct mimimi_image *glyphs;
};

static void mimimi_test_start(struct mimimi_chapter *chapter, struct mimimi_game *game)
{
	struct mimimi_test *data = chapter->data;
	
	mimimi_ground(game, mimimi_test_ground, mimimi_test_width, mimimi_test_height);
	mimimi_background(game, data->background);
	mimimi_overlay(game, data->overlay);
	
	int x = 11776;
	int y = 5248;
	
	mimimi_spawn(game, data->camera, x, y - 512, 0, 0, data->camera_appearance, data->camera_behavior);
	mimimi_spawn(game, data->mirai, x, y, 80, 250, data->mirai_appearance, data->mirai_behavior);
	mimimi_spawn(game, data->ryoubi, 10000, 5120, 80, 250, data->ryoubi_appearance, data->ryoubi_behavior);
	mimimi_spawn(game, data->ryouna, 11000, 5376, 80, 250, data->ryouna_appearance, data->ryouna_behavior);
	
	mimimi_camera_sprite(data->camera);
}

static void mimimi_test_step(struct mimimi_chapter *chapter) { }
static void mimimi_test_occurrence(struct mimimi_chapter *chapter, enum mimimi_occurrence appearance, void *occurrence) { }

struct mimimi_chapter *mimimi_test(void *(*allocate)(unsigned int count))
{
	struct mimimi_test *data = (*allocate)(sizeof *data);
	
	data->camera_appearance = (*allocate)(mimimi_sprite_appearance_size);
	data->mirai_appearance = (*allocate)(mimimi_sprite_appearance_size);
	data->ryoubi_appearance = (*allocate)(mimimi_sprite_appearance_size);
	data->ryouna_appearance = (*allocate)(mimimi_sprite_appearance_size);
	
	data->camera_behavior = (*allocate)(sizeof *data->camera_behavior);
	data->mirai_behavior = (*allocate)(sizeof *data->mirai_behavior);
	data->ryoubi_behavior = (*allocate)(sizeof *data->ryoubi_behavior);
	data->ryouna_behavior = (*allocate)(sizeof *data->ryouna_behavior);
	
	data->camera = (*allocate)(mimimi_sprite_size);
	data->mirai = (*allocate)(mimimi_sprite_size);
	data->ryoubi = (*allocate)(mimimi_sprite_size);
	data->ryouna = (*allocate)(mimimi_sprite_size);
	
	data->background = (*allocate)(sizeof *data->background);
	data->overlay = (*allocate)(sizeof *data->overlay);
	
	data->background->colors = (*allocate)(mimimi_test_width * 16 * mimimi_test_height * 16);
	
	data->overlay = (*allocate)(sizeof *data->overlay);
	data->overlay->colors = (*allocate)(mimimi_width * mimimi_height);
	
	data->glyphs = (*allocate)(mimimi_font_image_count * sizeof *data->glyphs);
	
	for (int i = 0 ; i < mimimi_font_image_count ; i++)
		data->glyphs[i].colors = (*allocate)(mimimi_font_image_color_count);
	
	data->mirai_behave_data = *mimimi_behave_data_default;
	data->mirai_behave_data.behavior = &data->mirai_behave_data_behavior;
	data->mirai_behave_data_behavior.behave = &mimimi_controls;
	data->mirai_behavior->behave = &mimimi_behave;
	data->mirai_behavior->data = &data->mirai_behave_data;
	
	data->ryoubi_behave_data = *mimimi_behave_data_default;
	data->ryoubi_behave_data.behavior = &data->ryoubi_behave_data_behavior;
	data->ryoubi_behave_data_behavior.behave = &mimimi_stationary_ai;
	data->ryoubi_behave_data_behavior.data = data->mirai;
	data->ryoubi_behavior->behave = &mimimi_behave;
	data->ryoubi_behavior->data = &data->ryoubi_behave_data;
	
	data->ryouna_behave_data = *mimimi_behave_data_default;
	data->ryouna_behave_data.behavior = &data->ryouna_behave_data_behavior;
	data->ryouna_behave_data_behavior.behave = &mimimi_stationary_ai;
	data->ryouna_behave_data_behavior.data = data->mirai;
	data->ryouna_behavior->behave = &mimimi_behave;
	data->ryouna_behavior->data = &data->ryouna_behave_data;
	
	data->camera_behavior->behave = &mimimi_camera;
	data->camera_behavior->data = &data->camera_data;
	
	data->camera_data.target = data->mirai;
	
	mimimi_sprite_appearance(data->mirai_appearance, mimimi_mirai_yang);
	mimimi_sprite_appearance(data->ryoubi_appearance, mimimi_ryoubi_flash);
	mimimi_sprite_appearance(data->ryouna_appearance, mimimi_ryouna_flash);
	data->camera_appearance = mimimi_empty_appearance;
	
	struct mimimi_chapter *chapter = (*allocate)(sizeof *chapter);
	chapter->data = data;
	chapter->start = &mimimi_test_start;
	chapter->step = &mimimi_test_step;
	chapter->occurrence = &mimimi_test_occurrence;
	
	static unsigned char ground_colors[] = {0x00, 0x3B, 0x1C, 0x21, 0x82, 0x56, 0x43, 0x25};
	
	data->background->width = mimimi_test_width * 16;
	data->background->height = mimimi_test_height * 16;
	
	for (int x = 0 ; x < mimimi_test_width * 16 ; x++)
	for (int y = 0 ; y < mimimi_test_height * 16 ; y++)
	{
		unsigned char color = ground_colors[mimimi_test_ground[x / 16 + y / 16 * mimimi_test_width]];
		data->background->colors[x + y * mimimi_test_width * 16] = color;
	}
	
	mimimi_glyphs(data->glyphs, mimimi_font, 0x6C);
	
	data->overlay->width = mimimi_width;
	data->overlay->height = mimimi_height;
	
	for (int x = 0 ; x < mimimi_width ; x++)
	for (int y = 0 ; y < mimimi_height ; y++)
		data->overlay->colors[x + y * mimimi_width] = 0;
	
	mimimi_text(data->overlay, data->glyphs, 16, 16, "Mirai's Miscellaneous Misadventures M17");
	mimimi_text(data->overlay, data->glyphs, 16, 32, "a Senran Kagura fangame by zamfofex");
	mimimi_text(data->overlay, data->glyphs, 16, 48, "January 27 of 2022");
	
	return chapter;
}

void mimimi_test_end(struct mimimi_chapter *chapter, void (*deallocate)(void *data))
{
	struct mimimi_test *data = chapter->data;
	
	(*deallocate)(chapter);
	
	(*deallocate)(data->camera_appearance);
	(*deallocate)(data->mirai_appearance);
	(*deallocate)(data->ryoubi_appearance);
	(*deallocate)(data->ryouna_appearance);
	
	(*deallocate)(data->camera_behavior);
	(*deallocate)(data->mirai_behavior);
	(*deallocate)(data->ryoubi_behavior);
	(*deallocate)(data->ryouna_behavior);
	
	(*deallocate)(data->camera);
	(*deallocate)(data->mirai);
	(*deallocate)(data->ryoubi);
	(*deallocate)(data->ryouna);
	
	(*deallocate)(data->background);
	(*deallocate)(data->overlay);
	
	for (int i = 0 ; i < mimimi_font_image_count ; i++)
		(*deallocate)(data->glyphs[i].colors);
	
	(*deallocate)(data->glyphs);
	
	(*deallocate)(data);
}