Mirai's Miscellaneous Misadventures

M49 / core / displays.c

/* license: AGPLv3 or later */
/* copyright 2024 zamfofex */

#include <mimimi.h>

void mimimi_camera_stamp(struct mimimi_engine *engine, struct mimimi_position *camera, int x, int y, int z, void *texture)
{
	z += 8;
	if (z <= 0) return;
	
	x -= camera->x;
	x = mimimi_div_up(x, z);
	x += engine->size.width / 2;
	
	y -= camera->y;
	y = mimimi_div_up(y, z);
	y += engine->size.height / 2;
	
	(*engine->stamp)(engine->data, x, y, texture);
}

void mimimi_display_tick(struct mimimi_display *display, struct mimimi_engine *engine)
{
	struct mimimi_sprite *sprite;
	struct mimimi_appearance *appearance;
	struct mimimi_position *position;
	struct mimimi_physics *physics;
	struct mimimi_life *life;
	struct mimimi_walk *walk;
	int dx, dy;
	struct mimimi_video_set *videos;
	struct mimimi_video *video;
	void *texture;
	int x, y;
	
	sprite = display->sprite;
	appearance = display->appearance;
	
	position = &sprite->position;
	physics = &sprite->physics;
	life = &sprite->life;
	walk = &sprite->walk;
	
	x = display->width * -8;
	y = display->height * -8;
	
	if (life->knocked_time == 0 && walk->direction != 0)
		display->direction = walk->direction;
	
	if (display->direction == 1)
	{
		dx = -physics->dx;
		videos = &appearance->left;
	}
	else if (display->direction == 2)
	{
		dx = physics->dx;
		videos = &appearance->right;
	}
	else
	{
		return;
	}
	
	dy = physics->dy;
	
	if (dx > 31) dx = 31;
	if (dx < 0) dx = 0;
	if (dy < 0) dy = 0;
	
	if (life->knocked_time == 0)
	{
		if (physics->airborne != 0)
		{
			dy = physics->dy;
			
			if (dy < -31) dy = -31;
			if (dy > 31) dy = 31;
			dy += 31;
			
			video = videos->jumping + dx * videos->jumping_video_count / 32;
			texture = video->textures[dy * video->count / 64];
			
			mimimi_camera_stamp(engine, display->camera, position->x + x, position->y + y, 0, texture);
			return;
		}
		
		if (physics->airborne != 0)
		{
			texture = videos->jumping->textures[dx * videos->jumping->count / 32];
			mimimi_camera_stamp(engine, display->camera, position->x + x, position->y + y, 0, texture);
			return;
		}
		
		video = videos->standing + dx * videos->standing_video_count / 32;
		display->animation_time += dx / 4;
	}
	else
	{
		if (physics->airborne == 0)
			video = videos->knocked,
			y += 212;
		else
			video = videos->falling,
			y += 128;
		
		display->animation_time += dy / 8;
	}
	
	/* do not assume 'char' is eight bits */
	display->animation_time &= 0xFF;
	
	texture = video->textures[display->animation_time * video->count / 256];
	mimimi_camera_stamp(engine, display->camera, position->x + x, position->y + y, 0, texture);
}

void mimimi_background_tick(struct mimimi_background *background, struct mimimi_engine *engine)
{
	mimimi_camera_stamp(engine, background->camera, background->x, background->y, background->z, background->texture);
}

void mimimi_platform_display_tick(struct mimimi_platform *platform, struct mimimi_position *camera, int x, int y, struct mimimi_engine *engine)
{
	mimimi_camera_stamp(engine, camera, platform->physics.transform.x - x, platform->physics.transform.y - y, 0, platform->texture);
}