Mirai's Miscellaneous Misadventures

M53 / core / controls.c

1/* license: AGPLv3 or later */
2/* copyright 2024 zamfofex */
3
4#include "../mimimi.h"
5
6void mimimi_history_tick(struct mimimi_history *history,
7    unsigned char left, unsigned char right)
8{
9    history->left <<= 1;
10    history->right <<= 1;
11
12    history->left &= 0xFFFF;
13    history->right &= 0xFFFF;
14
15    if (left != 0)
16        history->left |= 1;
17    if (right != 0)
18        history->right |= 1;
19}
20
21static int mimimi_count_oscillations(unsigned int history)
22{
23    int count, i;
24    unsigned char prev;
25
26    count = 0;
27    prev = history & 1;
28    for (i = 0; i < 16; i++) {
29        if ((history & 1) != prev)
30            count++;
31        prev = history & 1;
32        history >>= 1;
33    }
34
35    return count;
36}
37
38void mimimi_controls_tick(struct mimimi_walk *walk,
39    struct mimimi_history *history, void (*jump)(void *data), void *data)
40{
41    int left_oscillations, right_oscillations;
42
43    left_oscillations = mimimi_count_oscillations(history->left);
44    right_oscillations = mimimi_count_oscillations(history->right);
45
46    switch (walk->direction) {
47    case 0:
48        if ((history->right & 1) != 0) {
49            walk->direction = 2;
50            if (right_oscillations > 1 && (history->right & 2) == 0)
51                (*jump)(data);
52        }
53        if ((history->left & 1) != 0) {
54            walk->direction = 1;
55            if (left_oscillations > 1 && (history->left & 2) == 0)
56                (*jump)(data);
57        }
58        break;
59    case 1:
60        if ((history->left & 1) == 0)
61            walk->direction = 0;
62        break;
63    case 2:
64        if ((history->right & 1) == 0)
65            walk->direction = 0;
66        break;
67    }
68}