Mirai's Miscellaneous Misadventures
M48 / core / sprites.c
#include <mimimi.h>
static void mimimi_wall_physics(struct mimimi_physics *physics, struct mimimi_position *position, struct mimimi_ground *ground)
{
int x0, y0;
int x1, y1;
int left, right;
int top, bottom;
int top2, bottom2;
x0 = position->x;
y0 = position->y;
x1 = physics->width / 2;
y1 = physics->height;
top = (y0 - y1) / 128;
top2 = top - 1;
bottom = (y0 - 127) / 128;
bottom2 = bottom + 1;
left = (x0 - x1) / 128;
right = (x0 + x1) / 128;
if (
(mimimi_ground_tile(ground, left, bottom) != 0 && mimimi_ground_tile(ground, left, bottom2) != 0) ||
(mimimi_ground_tile(ground, left, top) != 0 && mimimi_ground_tile(ground, left, top2) != 0)
)
{
if (physics->dx < 0) physics->dx = 0;
position->x = (left + 1) * 128 + x1;
}
if (
(mimimi_ground_tile(ground, right, bottom) != 0 && mimimi_ground_tile(ground, right, bottom2) != 0) ||
(mimimi_ground_tile(ground, right, top) != 0 && mimimi_ground_tile(ground, right, top2) != 0)
)
{
if (physics->dx > 0) physics->dx = 0;
position->x = right * 128 - x1 - 1;
}
}
static void mimimi_slope_physics(struct mimimi_physics *physics, struct mimimi_position *position, struct mimimi_ground *ground)
{
int x0, y0;
int x1, y1;
int top, bottom;
int left, right;
x0 = position->x;
y0 = position->y;
x1 = physics->width / 2;
y1 = physics->height;
top = (y0 - y1) / 128;
bottom = (y0 - 127) / 128;
left = (x0 - x1) / 128;
right = (x0 + x1) / 128;
if (mimimi_ground_tile(ground, left, bottom) != 0)
if (mimimi_ground_tile(ground, left, top) == 0)
position->y = bottom * 128;
if (mimimi_ground_tile(ground, right, bottom) != 0)
if (mimimi_ground_tile(ground, right, top) == 0)
position->y = bottom * 128;
}
static void mimimi_ceiling_physics(struct mimimi_physics *physics, struct mimimi_position *position, struct mimimi_ground *ground)
{
int x0, y0;
int x1, y1;
int top, top2;
int left, right;
x0 = position->x;
y0 = position->y;
x1 = physics->width / 2;
y1 = physics->height;
top = (y0 - y1) / 128;
top2 = top - 1;
left = (x0 - x1) / 128;
right = (x0 + x1) / 128;
if (mimimi_ground_tile(ground, left, top) != 0 && mimimi_ground_tile(ground, right, top) != 0)
if (mimimi_ground_tile(ground, left, top2) != 0 || mimimi_ground_tile(ground, right, top2) != 0)
{
if (physics->dy < 0) physics->dy = 0;
position->y = (top + 1) * 128 + y1;
}
}
static void mimimi_landing_physics(struct mimimi_physics *physics, struct mimimi_position *position, struct mimimi_ground *ground)
{
int x0, y0;
int x1;
int left, right;
int bottom;
x0 = position->x;
y0 = position->y;
x1 = physics->width / 2;
bottom = y0 / 128;
left = (x0 - x1) / 128;
right = (x0 + x1) / 128;
if (physics->dy < 0) return;
if (mimimi_ground_tile(ground, left, bottom) != 0 || mimimi_ground_tile(ground, right, bottom) != 0)
{
physics->airborne = 0;
physics->dy = 0;
position->y = bottom * 128;
}
}
static void mimimi_fall_physics(struct mimimi_physics *physics, struct mimimi_position *position, struct mimimi_ground *ground)
{
int x0, y0;
int x1;
int bottom, bottom2;
int center;
int left, right;
x0 = position->x;
y0 = position->y;
x1 = physics->width / 2;
bottom = y0 / 128;
bottom2 = bottom + 1;
center = x0 / 128;
left = (x0 - x1) / 128;
right = (x0 + x1) / 128;
if (mimimi_ground_tile(ground, left, bottom) == 0 && mimimi_ground_tile(ground, right, bottom) == 0)
{
if (mimimi_ground_tile(ground, center, bottom2) == 0)
physics->airborne = 1;
else
position->y = bottom2 * 128;
}
}
static void mimimi_physics_dynamics(struct mimimi_physics *physics, struct mimimi_position *position)
{
position->x += physics->dx;
position->y += physics->dy;
}
static void mimimi_ground_collision_physics(struct mimimi_physics *physics, struct mimimi_position *position, struct mimimi_ground *ground)
{
mimimi_slope_physics(physics, position, ground);
mimimi_wall_physics(physics, position, ground);
mimimi_fall_physics(physics, position, ground);
if (physics->airborne == 0)
{
position->y /= 128;
position->y *= 128;
}
}
static void mimimi_airborne_collision_physics(struct mimimi_physics *physics, struct mimimi_position *position, struct mimimi_ground *ground)
{
mimimi_ceiling_physics(physics, position, ground);
mimimi_wall_physics(physics, position, ground);
mimimi_landing_physics(physics, position, ground);
}
static void mimimi_ground_physics(struct mimimi_physics *physics, struct mimimi_position *position)
{
physics->dx *= 5;
physics->dx /= 6;
physics->dy = 0;
mimimi_physics_dynamics(physics, position);
}
static void mimimi_airborne_physics(struct mimimi_physics *physics, struct mimimi_position *position)
{
physics->dx *= 17;
physics->dx /= 18;
physics->dy += physics->gravity;
mimimi_physics_dynamics(physics, position);
}
void mimimi_collision_physics_tick(struct mimimi_physics *physics, struct mimimi_position *position, struct mimimi_ground *ground)
{
if (physics->airborne == 0)
mimimi_ground_collision_physics(physics, position, ground);
else
mimimi_airborne_collision_physics(physics, position, ground);
}
void mimimi_dynamics_tick(struct mimimi_physics *physics, struct mimimi_position *position)
{
if (physics->airborne == 0)
mimimi_ground_physics(physics, position);
else
mimimi_airborne_physics(physics, position);
}
void mimimi_physics_tick(struct mimimi_physics *physics, struct mimimi_position *position, struct mimimi_ground *ground)
{
mimimi_dynamics_tick(physics, position);
mimimi_collision_physics_tick(physics, position, ground);
}
void mimimi_physics(struct mimimi_physics *physics, int width, int height)
{
physics->dx = 0;
physics->dy = 0;
physics->airborne = 1;
physics->width = width;
physics->height = height;
physics->gravity = 3;
}
void mimimi_life_tick(struct mimimi_life *life)
{
if (life->knocked_time != 0)
{
life->knocked_time--;
life->immunity_time = life->recovery_time;
}
if (life->immunity_time != 0)
{
life->pristinity = life->max_pristinity;
life->immunity_time--;
}
if (life->pristinity < life->max_pristinity)
life->pristinity++;
}
void mimimi_fall_tick(struct mimimi_fall *fall, struct mimimi_physics *physics, struct mimimi_life *life)
{
if (physics->dy > fall->max_speed && life->knocked_time < fall->knocked_time)
life->knocked_time = fall->knocked_time;
}
void mimimi_walk_tick(struct mimimi_walk *walk, struct mimimi_physics *physics)
{
int ax;
if (walk->direction == 0) return;
if (physics->airborne == 0)
ax = walk->ground_speed;
else
ax = walk->airborne_speed;
if (walk->direction == 1)
physics->dx -= ax;
if (walk->direction == 2)
physics->dx += ax;
}
void mimimi_sprite(struct mimimi_sprite *sprite, struct mimimi_ground *ground, int x, int y, int width, int height)
{
sprite->position.x = x;
sprite->position.y = y;
mimimi_physics(&sprite->physics, width, height);
sprite->life.knocked_time = 0;
sprite->life.immunity_time = 0;
sprite->life.pristinity = 256;
sprite->life.max_pristinity = 256;
sprite->life.recovery_time = 64;
sprite->fall.max_speed = 128;
sprite->fall.knocked_time = 64;
sprite->walk.ground_speed = 6;
sprite->walk.airborne_speed = 3;
sprite->walk.direction = 0;
sprite->offset.x = 0;
sprite->offset.y = 0;
sprite->ground = ground;
}
void mimimi_sprite_tick(struct mimimi_sprite *sprite)
{
struct mimimi_position position;
mimimi_life_tick(&sprite->life);
if (sprite->life.knocked_time == 0) mimimi_walk_tick(&sprite->walk, &sprite->physics);
position = sprite->position;
position.x -= sprite->offset.x;
position.y -= sprite->offset.y;
mimimi_physics_tick(&sprite->physics, &position, sprite->ground);
position.x += sprite->offset.x;
position.y += sprite->offset.y;
sprite->position = position;
mimimi_fall_tick(&sprite->fall, &sprite->physics, &sprite->life);
}
void mimimi_jump(void *data)
{
struct mimimi_sprite *sprite;
sprite = data;
if (sprite->life.knocked_time != 0) return;
if (sprite->physics.airborne != 0) return;
sprite->physics.airborne = 1;
sprite->physics.dy = -56;
}
void mimimi_offset_tick(struct mimimi_offset *offset, int x, int y)
{
int i;
int count;
struct mimimi_offset_threshold *thresholds;
struct mimimi_sprite *sprite;
count = offset->count;
sprite = offset->sprite;
thresholds = offset->thresholds;
for (i = 0 ; i < count ; i++)
{
if (sprite->position.x < thresholds[i].x * 128)
break;
}
sprite->offset = thresholds[i].offset;
sprite->offset.x -= x;
sprite->offset.y -= y;
}