Mirai's Miscellaneous Misadventures
M20 / core / controls.c
1
2
3
4#include <mimimi/controls.h>
5#include <mimimi/behaviors.h>
6#include <mimimi/allocators.h>
7#include <mimimi/sprites.h>
8#include <mimimi/chapters.h>
9
10struct mimimi_history_data
11{
12 struct mimimi_allocator *allocator;
13 struct mimimi_behavior *behavior;
14 struct mimimi_history *history;
15 struct mimimi_chapter *chapter;
16};
17
18static void mimimi_history_behave(void *data0)
19{
20 struct mimimi_history_data *data = data0;
21 data->history->left <<= 1;
22 data->history->left |= data->chapter->left;
23 data->history->right <<= 1;
24 data->history->right |= data->chapter->right;
25}
26
27static void mimimi_history_finish(void *data)
28{
29 struct mimimi_history_data *history_data = data;
30 (*history_data->allocator->deallocate)(history_data->behavior);
31 (*history_data->allocator->deallocate)(history_data);
32}
33
34struct mimimi_behavior *mimimi_history(struct mimimi_history *history, struct mimimi_chapter *chapter, struct mimimi_allocator *allocator)
35{
36 struct mimimi_history_data *data = (*allocator->allocate)(sizeof *data);
37 data->allocator = allocator;
38 data->history = history;
39 data->chapter = chapter;
40
41 history->left = 0;
42 history->right = 0;
43
44 data->behavior = (*allocator->allocate)(sizeof *data->behavior);
45 data->behavior->behave = &mimimi_history_behave;
46 data->behavior->finish = &mimimi_history_finish;
47 data->behavior->data = data;
48
49 return data->behavior;
50}
51
52struct mimimi_controls_data
53{
54 struct mimimi_allocator *allocator;
55 struct mimimi_behavior *behavior;
56 struct mimimi_controls *controls;
57 struct mimimi_walk *walk;
58 struct mimimi_history *history;
59};
60
61static unsigned char mimimi_count_oscillations(unsigned int history)
62{
63 unsigned char count = 0;
64 unsigned char prev = history&1;
65 for (int i = 0 ; i < 16 ; i++)
66 {
67 if ((history&1) != prev) count++;
68 prev = history&1;
69 history >>= 1;
70 }
71 return count;
72}
73
74static void mimimi_control(void *data)
75{
76 struct mimimi_controls_data *controls_data = data;
77
78 struct mimimi_walk *walk = controls_data->walk;
79 struct mimimi_history *history = controls_data->history;
80
81 struct mimimi_behavior *jump = controls_data->controls->jump;
82
83 unsigned char left_oscillations = mimimi_count_oscillations(history->left);
84 unsigned char right_oscillations = mimimi_count_oscillations(history->right);
85
86 switch (walk->direction)
87 {
88 case 0:
89 if ((history->left&1) != 0)
90 walk->direction = 1;
91 if ((history->right&1) != 0)
92 walk->direction = 2;
93 break;
94 case 1:
95 if ((history->left&1) == 0)
96 walk->direction = 0;
97 else if (left_oscillations > 1)
98 (*jump->behave)(jump->data);
99
100 if ((history->right&1) != 0)
101 {
102 if (right_oscillations == 0)
103 {
104
105 }
106 }
107 if ((history->right&1) != 0 && (history->right&2) == 0)
108 {
109
110 }
111 break;
112 case 2:
113 if ((history->right&1) == 0)
114 walk->direction = 0;
115 else if (right_oscillations > 1)
116 (*jump->behave)(jump->data);
117
118 if ((history->left&1) != 0)
119 {
120 if (left_oscillations == 0)
121 {
122
123 }
124 }
125 if ((history->left&1) != 0 && (history->left&2) == 0)
126 {
127
128 }
129 break;
130 }
131}
132
133static void mimimi_controls_finish(void *data)
134{
135 struct mimimi_controls_data *controls_data = data;
136 (*controls_data->allocator->deallocate)(controls_data->behavior);
137 (*controls_data->allocator->deallocate)(controls_data);
138}
139
140struct mimimi_behavior *mimimi_controls(struct mimimi_controls *controls, struct mimimi_walk *walk, struct mimimi_history *history, struct mimimi_allocator *allocator)
141{
142 struct mimimi_controls_data *data = (*allocator->allocate)(sizeof *data);
143 data->allocator = allocator;
144 data->controls = controls;
145 data->walk = walk;
146 data->history = history;
147
148 controls->jump = mimimi_noop;
149
150 data->behavior = (*allocator->allocate)(sizeof *data->behavior);
151 data->behavior->behave = &mimimi_control;
152 data->behavior->finish = &mimimi_controls_finish;
153 data->behavior->data = data;
154
155 return data->behavior;
156}
157
158struct mimimi_jump_data
159{
160 struct mimimi_allocator *allocator;
161 struct mimimi_behavior *behavior;
162 struct mimimi_jump *jump;
163 struct mimimi_physics *physics;
164};
165
166static void mimimi_jump_behave(void *data)
167{
168 struct mimimi_jump_data *jump_data = data;
169 if (jump_data->physics->airborne == 0)
170 {
171 jump_data->physics->airborne = 1;
172 jump_data->physics->dy = -jump_data->jump->strength;
173 }
174}
175
176static void mimimi_jump_finish(void *data)
177{
178 struct mimimi_jump_data *jump_data = data;
179 (*jump_data->allocator->deallocate)(jump_data->behavior);
180 (*jump_data->allocator->deallocate)(jump_data);
181}
182
183struct mimimi_behavior *mimimi_jump(struct mimimi_jump *jump, struct mimimi_physics *physics, struct mimimi_allocator *allocator)
184{
185 struct mimimi_jump_data *data = (*allocator->allocate)(sizeof *data);
186 data->allocator = allocator;
187 data->jump = jump;
188 data->physics = physics;
189
190 jump->strength = 56;
191
192 data->behavior = (*allocator->allocate)(sizeof *data->behavior);
193 data->behavior->behave = &mimimi_jump_behave;
194 data->behavior->finish = &mimimi_jump_finish;
195 data->behavior->data = data;
196
197 return data->behavior;
198}