Mirai's Miscellaneous Misadventures

M45 / core / displays.c

1/* license: AGPLv3 or later */
2/* copyright 2023 zamfofex */
3
4#include <mimimi.h>
5
6void mimimi_camera_stamp(struct mimimi_engine *engine, struct mimimi_position *camera, int x, int y, int z, void *texture)
7{
8	z += 8;
9	if (z <= 0) return;
10	
11	x -= camera->x;
12	x = mimimi_div_up(x, z);
13	x += engine->size.width / 2;
14	
15	y -= camera->y;
16	y = mimimi_div_up(y, z);
17	y += engine->size.height / 2;
18	
19	(*engine->stamp)(engine->data, x, y, texture);
20}
21
22void mimimi_display_tick(struct mimimi_display *display, struct mimimi_engine *engine)
23{
24	struct mimimi_sprite *sprite;
25	struct mimimi_appearance *appearance;
26	struct mimimi_position *position;
27	struct mimimi_physics *physics;
28	struct mimimi_life *life;
29	struct mimimi_walk *walk;
30	int dx, dy;
31	struct mimimi_video_set *videos;
32	struct mimimi_video *video;
33	void *texture;
34	int x, y;
35	
36	sprite = display->sprite;
37	appearance = display->appearance;
38	
39	position = &sprite->position;
40	physics = &sprite->physics;
41	life = &sprite->life;
42	walk = &sprite->walk;
43	
44	x = display->width * -8;
45	y = display->height * -8;
46	
47	if (life->knocked_time == 0 && walk->direction != 0)
48		display->direction = walk->direction;
49	
50	if (display->direction == 1)
51	{
52		dx = -physics->dx;
53		videos = &appearance->left;
54	}
55	else if (display->direction == 2)
56	{
57		dx = physics->dx;
58		videos = &appearance->right;
59	}
60	else
61	{
62		return;
63	}
64	
65	dy = physics->dy;
66	
67	if (dx > 31) dx = 31;
68	if (dx < 0) dx = 0;
69	if (dy < 0) dy = 0;
70	
71	if (life->knocked_time == 0)
72	{
73		if (physics->airborne != 0)
74		{
75			dy = physics->dy;
76			
77			if (dy < -31) dy = -31;
78			if (dy > 31) dy = 31;
79			dy += 31;
80			
81			video = videos->jumping + dx * videos->jumping_video_count / 32;
82			texture = video->textures[dy * video->count / 64];
83			
84			mimimi_camera_stamp(engine, display->camera, position->x + x, position->y + y, 0, texture);
85			return;
86		}
87		
88		if (physics->airborne != 0)
89		{
90			texture = videos->jumping->textures[dx * videos->jumping->count / 32];
91			mimimi_camera_stamp(engine, display->camera, position->x + x, position->y + y, 0, texture);
92			return;
93		}
94		
95		video = videos->standing + dx * videos->standing_video_count / 32;
96		display->animation_time += dx / 4;
97	}
98	else
99	{
100		if (physics->airborne == 0)
101			video = videos->knocked,
102			y += 212;
103		else
104			video = videos->falling,
105			y += 128;
106		
107		display->animation_time += dy / 8;
108	}
109	
110	/* do not assume 'char' is eight bits */
111	display->animation_time &= 0xFF;
112	
113	texture = video->textures[display->animation_time * video->count / 256];
114	mimimi_camera_stamp(engine, display->camera, position->x + x, position->y + y, 0, texture);
115}
116
117void mimimi_background_tick(struct mimimi_background *background, struct mimimi_engine *engine)
118{
119	mimimi_camera_stamp(engine, background->camera, background->x, background->y, background->z, background->texture);
120}
121
122void mimimi_platform_display_tick(struct mimimi_platform *platform, struct mimimi_position *camera, int x, int y, struct mimimi_engine *engine)
123{
124	mimimi_camera_stamp(engine, camera, platform->physics.transform.x - x, platform->physics.transform.y - y, 0, platform->texture);
125}