Mirai's Miscellaneous Misadventures

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