Mirai's Miscellaneous Misadventures
M27 / core / displays.c
#include <mimimi/allocators.h>
#include <mimimi/behaviors.h>
#include <mimimi/sprites.h>
#include <mimimi/geometry.h>
#include <mimimi/engines.h>
#include <mimimi/chapters.h>
#include <mimimi/assets.h>
#include <mimimi/animations.h>
#include <mimimi/appearances.h>
struct mimimi_display
{
struct mimimi_allocator *allocator;
struct mimimi_behavior *behavior;
struct mimimi_engine *engine;
struct mimimi_position *camera;
struct mimimi_sprite *sprite;
struct mimimi_appearance *appearance;
unsigned char animation_time;
int *direction;
};
static void mimimi_camera_stamp(struct mimimi_engine *engine, struct mimimi_position *camera, int x, int y, int z, struct mimimi_image *image)
{
z += 8;
if (z <= 0) return;
x -= camera->x;
x /= z;
x += engine->size->width / 2;
x -= image->width / 2;
y -= camera->y;
y /= z;
y += engine->size->height / 2;
y -= image->height;
(*engine->stamp)(engine->data, x, y, image);
}
static void mimimi_display_behave(void *data)
{
struct mimimi_display *display = data;
struct mimimi_sprite *sprite = display->sprite;
struct mimimi_appearance *appearance = display->appearance;
struct mimimi_position *position = sprite->position;
struct mimimi_physics *physics = sprite->physics;
struct mimimi_life *life = sprite->life;
struct mimimi_walk *walk = sprite->walk;
int dx;
int dy = physics->dy;
if (walk->direction != 0) *display->direction = walk->direction;
struct mimimi_animation_set *animations;
if (*display->direction == 1)
{
dx = -physics->dx;
animations = &appearance->left;
}
if (*display->direction == 2)
{
dx = physics->dx;
animations = &appearance->right;
}
if (dx > 31) dx = 31;
if (dx < 0) dx = 0;
if (dy < 0) dy = 0;
struct mimimi_animation *animation;
int y = 0;
if (life->knocked_time == 0)
{
if (physics->airborne != 0)
{
struct mimimi_image *image = animations->jumping + dx * animations->jumping_image_count / 32;
mimimi_camera_stamp(display->engine, display->camera, position->x, position->y + y, 0, image);
return;
}
animation = animations->standing + dx * animations->standing_animation_count / 32;
display->animation_time += dx / 4;
}
else
{
if (physics->airborne == 0)
animation = animations->knocked,
y = 128;
else
animation = animations->falling;
display->animation_time += dy / 8;
}
struct mimimi_image *image = animation->images + display->animation_time * animation->count / 256;
mimimi_camera_stamp(display->engine, display->camera, position->x, position->y + y, 0, image);
}
static void mimimi_display_finish(void *data)
{
struct mimimi_display *display = data;
(*display->allocator->deallocate)(display->behavior);
(*display->allocator->deallocate)(display);
}
struct 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)
{
struct mimimi_display *display = (*allocator->allocate)(sizeof *display);
display->allocator = allocator;
display->engine = engine;
display->camera = camera;
display->sprite = sprite;
display->appearance = appearance;
display->animation_time = 0;
display->direction = direction;
*direction = 1;
display->behavior = (*allocator->allocate)(sizeof *display->behavior);
display->behavior->behave = &mimimi_display_behave;
display->behavior->finish = &mimimi_display_finish;
display->behavior->data = display;
return display->behavior;
}
struct mimimi_background
{
struct mimimi_allocator *allocator;
struct mimimi_behavior *behavior;
struct mimimi_image *image;
struct mimimi_position *camera;
struct mimimi_engine *engine;
int offset;
};
static void mimimi_background_behave(void *data)
{
struct mimimi_background *background_data = data;
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);
}
static void mimimi_background_finish(void *data)
{
struct mimimi_background *background_data = data;
(*background_data->allocator->deallocate)(background_data->behavior);
(*background_data->allocator->deallocate)(background_data);
}
struct mimimi_behavior *mimimi_background(struct mimimi_engine *engine, struct mimimi_position *camera, struct mimimi_image *image, int offset, struct mimimi_allocator *allocator)
{
struct mimimi_background *data = (*allocator->allocate)(sizeof *data);
data->allocator = allocator;
data->image = image;
data->camera = camera;
data->engine = engine;
data->offset = offset;
data->behavior = (*allocator->allocate)(sizeof *data->behavior);
data->behavior->behave = &mimimi_background_behave;
data->behavior->finish = &mimimi_background_finish;
data->behavior->data = data;
return data->behavior;
}
struct mimimi_overlay
{
struct mimimi_allocator *allocator;
struct mimimi_behavior *behavior;
struct mimimi_engine *engine;
struct mimimi_image *image;
int x;
int y;
};
static void mimimi_overlay_behave(void *data)
{
struct mimimi_overlay *overlay_data = data;
struct mimimi_engine *engine = overlay_data->engine;
(*engine->stamp)(engine->data, overlay_data->x, overlay_data->y, overlay_data->image);
}
static void mimimi_overlay_finish(void *data)
{
struct mimimi_background *overlay_data = data;
(*overlay_data->allocator->deallocate)(overlay_data->behavior);
(*overlay_data->allocator->deallocate)(overlay_data);
}
struct mimimi_behavior *mimimi_overlay(struct mimimi_engine *engine, struct mimimi_image *image, int x, int y, struct mimimi_allocator *allocator)
{
struct mimimi_overlay *data = (*allocator->allocate)(sizeof *data);
data->allocator = allocator;
data->engine = engine;
data->image = image;
data->x = x;
data->y = y;
data->behavior = (*allocator->allocate)(sizeof *data->behavior);
data->behavior->behave = &mimimi_overlay_behave;
data->behavior->finish = &mimimi_overlay_finish;
data->behavior->data = data;
return data->behavior;
}