Mirai's Miscellaneous Misadventures

M31 / core / displays.c

1// copyright 2022 zamfofex
2// license: AGPLv3 or later
3
4#include <mimimi/allocators.h>
5#include <mimimi/behaviors.h>
6#include <mimimi/sprites.h>
7#include <mimimi/geometry.h>
8#include <mimimi/engines.h>
9#include <mimimi/chapters.h>
10#include <mimimi/assets.h>
11#include <mimimi/animations.h>
12#include <mimimi/appearances.h>
13#include <mimimi/video.h>
14
15struct mimimi_display
16{
17	struct mimimi_allocator *allocator;
18	struct mimimi_behavior *behavior;
19	struct mimimi_engine *engine;
20	struct mimimi_position *camera;
21	struct mimimi_sprite *sprite;
22	struct mimimi_video_appearance *appearance;
23	unsigned char animation_time;
24	int *direction;
25	int x;
26	int y;
27};
28
29static void mimimi_camera_stamp(struct mimimi_engine *engine, struct mimimi_position *camera, int x, int y, int z, void *texture)
30{
31	z += 8;
32	if (z <= 0) return;
33	
34	x -= camera->x;
35	x /= z;
36	x += engine->size->width / 2;
37	
38	y -= camera->y;
39	y /= z;
40	y += engine->size->height / 2;
41	
42	(*engine->stamp)(engine->data, x, y, texture);
43}
44
45static void mimimi_display_behave(void *data)
46{
47	struct mimimi_display *display = data;
48	struct mimimi_sprite *sprite = display->sprite;
49	struct mimimi_video_appearance *appearance = display->appearance;
50	
51	struct mimimi_position *position = sprite->position;
52	struct mimimi_physics *physics = sprite->physics;
53	struct mimimi_life *life = sprite->life;
54	struct mimimi_walk *walk = sprite->walk;
55	
56	if (walk->direction != 0) *display->direction = walk->direction;
57	
58	int dx;
59	int dy = physics->dy;
60	
61	struct mimimi_video_set *videos;
62	
63	if (*display->direction == 1)
64	{
65		dx = -physics->dx;
66		videos = &appearance->left;
67	}
68	if (*display->direction == 2)
69	{
70		dx = physics->dx;
71		videos = &appearance->right;
72	}
73	
74	if (dx > 31) dx = 31;
75	if (dx < 0) dx = 0;
76	if (dy < 0) dy = 0;
77	
78	struct mimimi_video *video;
79	
80	int x = -8 * display->x;
81	int y = -8 * display->y;
82	
83	if (life->knocked_time == 0)
84	{
85		if (physics->airborne != 0)
86		{
87			void *texture = videos->jumping->textures[dx * videos->jumping->count / 32];
88			mimimi_camera_stamp(display->engine, display->camera, position->x + x, position->y + y, 0, texture);
89			return;
90		}
91		
92		video = videos->standing + dx * videos->standing_video_count / 32;
93		display->animation_time += dx / 4;
94	}
95	else
96	{
97		if (physics->airborne == 0)
98			video = videos->knocked,
99			y += 128;
100		else
101			video = videos->falling;
102		
103		display->animation_time += dy / 8;
104	}
105	
106	void *texture = video->textures[display->animation_time * video->count / 256];
107	mimimi_camera_stamp(display->engine, display->camera, position->x + x, position->y + y, 0, texture);
108}
109
110static void mimimi_display_finish(void *data)
111{
112	struct mimimi_display *display = data;
113	mimimi_deallocate(display->allocator, display->behavior);
114	mimimi_deallocate(display->allocator, display);
115}
116
117struct mimimi_behavior *mimimi_display(struct mimimi_engine *engine, struct mimimi_position *camera, struct mimimi_sprite *sprite, struct mimimi_video_appearance *appearance, int *direction, int x, int y, struct mimimi_allocator *allocator)
118{
119	struct mimimi_display *display = mimimi_allocate(allocator, sizeof *display);
120	display->allocator = allocator;
121	display->engine = engine;
122	display->camera = camera;
123	display->sprite = sprite;
124	display->appearance = appearance;
125	display->x = x;
126	display->y = y;
127	
128	display->animation_time = 0;
129	display->direction = direction;
130	*direction = 1;
131	
132	display->behavior = mimimi_allocate(allocator, sizeof *display->behavior);
133	display->behavior->behave = &mimimi_display_behave;
134	display->behavior->finish = &mimimi_display_finish;
135	display->behavior->data = display;
136	
137	return display->behavior;
138}
139
140struct mimimi_background
141{
142	struct mimimi_allocator *allocator;
143	struct mimimi_behavior *behavior;
144	void *texture;
145	struct mimimi_position *camera;
146	struct mimimi_engine *engine;
147	int x, y, z;
148};
149
150static void mimimi_background_behave(void *data)
151{
152	struct mimimi_background *background_data = data;
153	mimimi_camera_stamp(background_data->engine, background_data->camera, background_data->x, background_data->y - 7, background_data->z, background_data->texture);
154}
155
156static void mimimi_background_finish(void *data)
157{
158	struct mimimi_background *background_data = data;
159	mimimi_deallocate(background_data->allocator, background_data->behavior);
160	mimimi_deallocate(background_data->allocator, background_data);
161}
162
163struct mimimi_behavior *mimimi_background(struct mimimi_engine *engine, struct mimimi_position *camera, void *texture, int x, int y, int z, struct mimimi_allocator *allocator)
164{
165	struct mimimi_background *data = mimimi_allocate(allocator, sizeof *data);
166	data->allocator = allocator;
167	data->texture = texture;
168	data->camera = camera;
169	data->engine = engine;
170	data->x = x;
171	data->y = y;
172	data->z = z;
173	
174	data->behavior = mimimi_allocate(allocator, sizeof *data->behavior);
175	data->behavior->behave = &mimimi_background_behave;
176	data->behavior->finish = &mimimi_background_finish;
177	data->behavior->data = data;
178	
179	return data->behavior;
180}
181
182struct mimimi_overlay
183{
184	struct mimimi_allocator *allocator;
185	struct mimimi_behavior *behavior;
186	struct mimimi_engine *engine;
187	void *texture;
188	int x;
189	int y;
190};
191
192static void mimimi_overlay_behave(void *data)
193{
194	struct mimimi_overlay *overlay_data = data;
195	struct mimimi_engine *engine = overlay_data->engine;
196	(*engine->stamp)(engine->data, overlay_data->x, overlay_data->y, overlay_data->texture);
197}
198
199static void mimimi_overlay_finish(void *data)
200{
201	struct mimimi_background *overlay_data = data;
202	mimimi_deallocate(overlay_data->allocator, overlay_data->behavior);
203	mimimi_deallocate(overlay_data->allocator, overlay_data);
204}
205
206struct mimimi_behavior *mimimi_overlay(struct mimimi_engine *engine, void *texture, int x, int y, struct mimimi_allocator *allocator)
207{
208	struct mimimi_overlay *data = mimimi_allocate(allocator, sizeof *data);
209	data->allocator = allocator;
210	data->engine = engine;
211	data->texture = texture;
212	data->x = x;
213	data->y = y;
214	
215	data->behavior = mimimi_allocate(allocator, sizeof *data->behavior);
216	data->behavior->behave = &mimimi_overlay_behave;
217	data->behavior->finish = &mimimi_overlay_finish;
218	data->behavior->data = data;
219	
220	return data->behavior;
221}