Mirai's Miscellaneous Misadventures
M32 / 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>
#include <mimimi/video.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_video_appearance *appearance;
unsigned char animation_time;
int *direction;
int x;
int y;
};
static 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 /= z;
x += engine->size->width / 2;
y -= camera->y;
y /= z;
y += engine->size->height / 2;
(*engine->stamp)(engine->data, x, y, texture);
}
static void mimimi_display_behave(void *data)
{
struct mimimi_display *display = data;
struct mimimi_sprite *sprite = display->sprite;
struct mimimi_video_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;
if (walk->direction != 0) *display->direction = walk->direction;
int dx;
int dy = physics->dy;
struct mimimi_video_set *videos;
if (*display->direction == 1)
{
dx = -physics->dx;
videos = &appearance->left;
}
if (*display->direction == 2)
{
dx = physics->dx;
videos = &appearance->right;
}
if (dx > 31) dx = 31;
if (dx < 0) dx = 0;
if (dy < 0) dy = 0;
struct mimimi_video *video;
int x = -8 * display->x;
int y = -8 * display->y;
if (life->knocked_time == 0)
{
if (physics->airborne != 0)
{
void *texture = videos->jumping->textures[dx * videos->jumping->count / 32];
mimimi_camera_stamp(display->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 += 128;
else
video = videos->falling;
display->animation_time += dy / 8;
}
void *texture = video->textures[display->animation_time * video->count / 256];
mimimi_camera_stamp(display->engine, display->camera, position->x + x, position->y + y, 0, texture);
}
static void mimimi_display_finish(void *data)
{
struct mimimi_display *display = data;
mimimi_deallocate(display->allocator, display->behavior);
mimimi_deallocate(display->allocator, display);
}
struct mimimi_behavior *mimimi_display(struct mimimi_engine *engine, struct mimimi_position *camera, struct mimimi_sprite *sprite, struct mimimi_video_appearance *appearance, int *direction, int x, int y, struct mimimi_allocator *allocator)
{
struct mimimi_display *display = mimimi_allocate(allocator, sizeof *display);
display->allocator = allocator;
display->engine = engine;
display->camera = camera;
display->sprite = sprite;
display->appearance = appearance;
display->x = x;
display->y = y;
display->animation_time = 0;
display->direction = direction;
*direction = 1;
display->behavior = mimimi_allocate(allocator, 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;
void *texture;
struct mimimi_position *camera;
struct mimimi_engine *engine;
int x, y, z;
};
static void mimimi_background_behave(void *data)
{
struct mimimi_background *background_data = data;
mimimi_camera_stamp(background_data->engine, background_data->camera, background_data->x, background_data->y - 7, background_data->z, background_data->texture);
}
static void mimimi_background_finish(void *data)
{
struct mimimi_background *background_data = data;
mimimi_deallocate(background_data->allocator, background_data->behavior);
mimimi_deallocate(background_data->allocator, background_data);
}
struct mimimi_behavior *mimimi_background(struct mimimi_engine *engine, struct mimimi_position *camera, void *texture, int x, int y, int z, struct mimimi_allocator *allocator)
{
struct mimimi_background *data = mimimi_allocate(allocator, sizeof *data);
data->allocator = allocator;
data->texture = texture;
data->camera = camera;
data->engine = engine;
data->x = x;
data->y = y;
data->z = z;
data->behavior = mimimi_allocate(allocator, 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;
void *texture;
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->texture);
}
static void mimimi_overlay_finish(void *data)
{
struct mimimi_background *overlay_data = data;
mimimi_deallocate(overlay_data->allocator, overlay_data->behavior);
mimimi_deallocate(overlay_data->allocator, overlay_data);
}
struct mimimi_behavior *mimimi_overlay(struct mimimi_engine *engine, void *texture, int x, int y, struct mimimi_allocator *allocator)
{
struct mimimi_overlay *data = mimimi_allocate(allocator, sizeof *data);
data->allocator = allocator;
data->engine = engine;
data->texture = texture;
data->x = x;
data->y = y;
data->behavior = mimimi_allocate(allocator, sizeof *data->behavior);
data->behavior->behave = &mimimi_overlay_behave;
data->behavior->finish = &mimimi_overlay_finish;
data->behavior->data = data;
return data->behavior;
}