Mirai's Miscellaneous Misadventures
M23 / core / controls.c
#include <mimimi/controls.h>
#include <mimimi/behaviors.h>
#include <mimimi/allocators.h>
#include <mimimi/sprites.h>
#include <mimimi/chapters.h>
struct mimimi_history_data
{
struct mimimi_allocator *allocator;
struct mimimi_behavior *behavior;
struct mimimi_history *history;
struct mimimi_chapter *chapter;
};
static void mimimi_history_behave(void *data0)
{
struct mimimi_history_data *data = data0;
data->history->left <<= 1;
data->history->left |= data->chapter->left;
data->history->right <<= 1;
data->history->right |= data->chapter->right;
}
static void mimimi_history_finish(void *data)
{
struct mimimi_history_data *history_data = data;
(*history_data->allocator->deallocate)(history_data->behavior);
(*history_data->allocator->deallocate)(history_data);
}
struct mimimi_behavior *mimimi_history(struct mimimi_history *history, struct mimimi_chapter *chapter, struct mimimi_allocator *allocator)
{
struct mimimi_history_data *data = (*allocator->allocate)(sizeof *data);
data->allocator = allocator;
data->history = history;
data->chapter = chapter;
history->left = 0;
history->right = 0;
data->behavior = (*allocator->allocate)(sizeof *data->behavior);
data->behavior->behave = &mimimi_history_behave;
data->behavior->finish = &mimimi_history_finish;
data->behavior->data = data;
return data->behavior;
}
struct mimimi_controls_data
{
struct mimimi_allocator *allocator;
struct mimimi_behavior *behavior;
struct mimimi_controls *controls;
struct mimimi_walk *walk;
struct mimimi_history *history;
};
static unsigned char mimimi_count_oscillations(unsigned int history)
{
unsigned char count = 0;
unsigned char prev = history&1;
for (int i = 0 ; i < 16 ; i++)
{
if ((history&1) != prev) count++;
prev = history&1;
history >>= 1;
}
return count;
}
static void mimimi_control(void *data)
{
struct mimimi_controls_data *controls_data = data;
struct mimimi_walk *walk = controls_data->walk;
struct mimimi_history *history = controls_data->history;
struct mimimi_behavior *jump = controls_data->controls->jump;
unsigned char left_oscillations = mimimi_count_oscillations(history->left);
unsigned char right_oscillations = mimimi_count_oscillations(history->right);
switch (walk->direction)
{
case 0:
if ((history->left&1) != 0)
walk->direction = 1;
if ((history->right&1) != 0)
walk->direction = 2;
break;
case 1:
if ((history->left&1) == 0)
walk->direction = 0;
else if (left_oscillations > 1)
(*jump->behave)(jump->data);
if ((history->right&1) != 0)
{
if (right_oscillations == 0)
{
}
}
if ((history->right&1) != 0 && (history->right&2) == 0)
{
}
break;
case 2:
if ((history->right&1) == 0)
walk->direction = 0;
else if (right_oscillations > 1)
(*jump->behave)(jump->data);
if ((history->left&1) != 0)
{
if (left_oscillations == 0)
{
}
}
if ((history->left&1) != 0 && (history->left&2) == 0)
{
}
break;
}
}
static void mimimi_controls_finish(void *data)
{
struct mimimi_controls_data *controls_data = data;
(*controls_data->allocator->deallocate)(controls_data->behavior);
(*controls_data->allocator->deallocate)(controls_data);
}
struct mimimi_behavior *mimimi_controls(struct mimimi_controls *controls, struct mimimi_walk *walk, struct mimimi_history *history, struct mimimi_allocator *allocator)
{
struct mimimi_controls_data *data = (*allocator->allocate)(sizeof *data);
data->allocator = allocator;
data->controls = controls;
data->walk = walk;
data->history = history;
controls->jump = mimimi_noop;
data->behavior = (*allocator->allocate)(sizeof *data->behavior);
data->behavior->behave = &mimimi_control;
data->behavior->finish = &mimimi_controls_finish;
data->behavior->data = data;
return data->behavior;
}
struct mimimi_jump_data
{
struct mimimi_allocator *allocator;
struct mimimi_behavior *behavior;
struct mimimi_jump *jump;
struct mimimi_physics *physics;
};
static void mimimi_jump_behave(void *data)
{
struct mimimi_jump_data *jump_data = data;
if (jump_data->physics->airborne == 0)
{
jump_data->physics->airborne = 1;
jump_data->physics->dy = -jump_data->jump->strength;
}
}
static void mimimi_jump_finish(void *data)
{
struct mimimi_jump_data *jump_data = data;
(*jump_data->allocator->deallocate)(jump_data->behavior);
(*jump_data->allocator->deallocate)(jump_data);
}
struct mimimi_behavior *mimimi_jump(struct mimimi_jump *jump, struct mimimi_physics *physics, struct mimimi_allocator *allocator)
{
struct mimimi_jump_data *data = (*allocator->allocate)(sizeof *data);
data->allocator = allocator;
data->jump = jump;
data->physics = physics;
jump->strength = 56;
data->behavior = (*allocator->allocate)(sizeof *data->behavior);
data->behavior->behave = &mimimi_jump_behave;
data->behavior->finish = &mimimi_jump_finish;
data->behavior->data = data;
return data->behavior;
}