Mirai's Miscellaneous Misadventures

M49 / core / motion.c

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

#include <mimimi.h>

void mimimi_linear_propagate(struct mimimi_momentum *momentum, int value, int x0, int scale)
{
	momentum->dx += (value - x0) * 256 / scale - momentum->x;
}

void mimimi_linear_apply(struct mimimi_momentum *momentum, int *value, int x0, int scale)
{
	*value = momentum->x * scale / 256 + x0;
}

void mimimi_angular_propagate(struct mimimi_momentum *momentum, struct mimimi_position *position, int x0, int y0, int a0, int scale)
{
	int a, x, y, dx;
	
	x = position->x - x0;
	y = position->y - y0;
	a = mimimi_angle(x, y);
	
	dx = (a / 64 - a0) - momentum->x * scale / 256;
	
	dx = mimimi_mod(dx, 256);
	if (dx > 128) dx = dx - 256;
	momentum->dx += dx * 256 / scale;
}

void mimimi_angular_apply(struct mimimi_momentum *momentum, struct mimimi_position *position, int x0, int y0, int a0, int scale, int length)
{
	int a, x, y;
	
	a = mimimi_mod(momentum->x * scale / 256 + a0, 256);
	
	x = mimimi_sine[a] * length / 128;
	y = mimimi_cosine[a] * length / 128;
	
	position->x = x + x0;
	position->y = y + y0;
}

static void mimimi_linear_motion_propagate(void *data)
{
	struct mimimi_linear_motion *motion;
	motion = data;
	mimimi_linear_propagate(motion->motion.momentum, *motion->value, motion->origin, motion->scale);
}

static void mimimi_linear_motion_apply(void *data)
{
	struct mimimi_linear_motion *motion;
	motion = data;
	mimimi_linear_apply(motion->motion.momentum, motion->value, motion->origin, motion->scale);
}

void mimimi_linear_motion(struct mimimi_linear_motion *motion, struct mimimi_momentum *momentum, int *value, int origin, int scale)
{
	motion->value = value;
	motion->origin = origin;
	motion->scale = scale;
	
	motion->motion.data = motion;
	motion->motion.momentum = momentum;
	motion->motion.propagate = &mimimi_linear_motion_propagate;
	motion->motion.apply = &mimimi_linear_motion_apply;
}

static void mimimi_angular_motion_propagate(void *data)
{
	struct mimimi_angular_motion *motion;
	motion = data;
	mimimi_angular_propagate(motion->motion.momentum, motion->value, motion->origin.x, motion->origin.y, motion->angle, motion->scale);
}

static void mimimi_angular_motion_apply(void *data)
{
	struct mimimi_angular_motion *motion;
	motion = data;
	mimimi_angular_apply(motion->motion.momentum, motion->value, motion->origin.x, motion->origin.y, motion->angle, motion->scale, motion->height);
}

void mimimi_angular_motion(struct mimimi_angular_motion *motion, struct mimimi_momentum *momentum, struct mimimi_position *value, int x0, int y0, int a0, int scale, int height)
{
	motion->value = value;
	motion->origin.x = x0;
	motion->origin.y = y0;
	motion->angle = a0;
	motion->scale = scale;
	motion->height = height;
	
	motion->motion.data = motion;
	motion->motion.momentum = momentum;
	motion->motion.propagate = &mimimi_angular_motion_propagate;
	motion->motion.apply = &mimimi_angular_motion_apply;
}