Mirai's Miscellaneous Misadventures

M50 / 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	if (loader->started == 2)

46	{

47		(*mimimi_loader_chapters[loader->index].tick)(loader->chapter, left, right);

48		return;

49	}

50	

51	if (left != 0 && right != 0)

52		loader->started = 1;

53	

54	if (loader->started == 1)

55	{

56		if (left == 0 && right == 0)

57		{

58			(*loader->engine->invalidate)(loader->engine->data, loader->background);

59			for (i = 0 ; i < count ; i++)

60				(*loader->engine->invalidate)(loader->engine->data, loader->textures[i]);

61			

62			loader->started = 2;

63			loader->chapter = (*mimimi_loader_chapters[loader->index].start)(loader->engine);

64			(*mimimi_loader_chapters[loader->index].tick)(loader->chapter, left, right);

65			

66			return;

67		}

68	}

69	else

70	{

71		if (left == 0)

72		if (loader->previous_direction == -1)

73		if (loader->index > 0)

74			loader->index--;

75		

76		if (right == 0)

77		if (loader->previous_direction == 1)

78		if (loader->index < count - 1)

79			loader->index++;

80		

81		loader->previous_direction = 0;

82		if (left != 0) loader->previous_direction = -1;

83		if (right != 0) loader->previous_direction = 1;

84	}

85	

86	width = loader->images[0].width;

87	height = loader->images[0].height;

88	

89	loader->x *= 3;

90	loader->x += (width + 8) * loader->index;

91	loader->x /= 4;

92	

93	(*loader->engine->stamp)(loader->engine->data, 0, 0, loader->background);

94	for (i = 0 ; i < count ; i++)

95	{

96		x = loader->engine->size.width / 2 - width / 2;

97		y = loader->engine->size.height / 2 - height / 2;

98		x += (width + 8) * i - loader->x;

99		(*loader->engine->stamp)(loader->engine->data, x, y, loader->textures[i]);

100	}

101}

102

103void *mimimi_loader(struct mimimi_engine *engine)

104{

105	static int count = sizeof mimimi_loader_chapters / sizeof *mimimi_loader_chapters;

106	static unsigned char background_colors[512 * 256];

107	static char title[] = "select chapter";

108	static char note[] = "press [left] and [right] at the same time to select";

109	

110	struct mimimi_loader *loader;

111	int i;

112	unsigned char *colors;

113	struct mimimi_image *image;

114	struct mimimi_loader_chapter_info *info;

115	int y;

116	int width;

117	

118	loader = malloc(sizeof *loader);

119	if (loader == NULL) exit(1);

120	

121	loader->index = 0;

122	loader->started = 0;

123	loader->engine = engine;

124	loader->previous_direction = 0;

125	loader->x = 0;

126	

127	loader->background_image.colors = background_colors;

128	loader->background_image.width = 512;

129	loader->background_image.height = 256;

130	mimimi_loader_fill(&loader->background_image, 0x16);

131	

132	width = mimimi_measure_paragraph(mimimi_font, title);

133	mimimi_draw_paragraph(mimimi_font, title, &loader->background_image, loader->background_image.width / 2 - width / 2, 32, 0xD);

134	

135	width = mimimi_measure_paragraph(mimimi_font, note);

136	mimimi_draw_paragraph(mimimi_font, note, &loader->background_image, loader->background_image.width / 2 - width / 2, loader->background_image.height - 32 - 16, 0xD);

137	

138	loader->background = (*loader->engine->texture)(loader->engine->data, &loader->background_image);

139	

140	colors = loader->colors;

141	

142	for (i = 0 ; i < count ; i++)

143	{

144		info = mimimi_loader_chapters + i;

145		image = loader->images + i;

146		image->width = 192;

147		image->height = 96;

148		image->colors = colors;

149		colors += image->width * image->height;

150		mimimi_loader_fill(image, 0xD);

151		y = mimimi_draw_text(mimimi_font, info->name, 172, 18, image, 8, 2, 4);

152		mimimi_draw_text(mimimi_font, info->description, 172, 18, image, 8, y + 4, 4);

153		loader->textures[i] = (*engine->texture)(engine->data, image);

154	}

155	

156	return loader;

157}