Mirai's Miscellaneous Misadventures
M34 / core / physics.c
1
2
3
4static unsigned char mimimi_ground_get(struct mimimi_ground *ground, int x, int y)
5{
6 if (x < 0) return 1;
7 if (y < 0) return 1;
8 if (x >= ground->width) return 1;
9 if (y >= ground->height) return 1;
10 return ground->tiles[x + y * ground->width];
11}
12
13static void mimimi_wall_physics(struct mimimi_physics_data *data)
14{
15 struct mimimi_ground *ground = data->ground;
16 struct mimimi_position *position = data->position;
17 struct mimimi_physics *physics = data->physics;
18
19 int x0 = position->x;
20 int y0 = position->y;
21 int x1 = physics->width / 2;
22 int y1 = physics->height;
23
24 int top = (y0 - y1) / 128;
25 int top2 = top - 1;
26 int bottom = (y0 - 127) / 128;
27 int bottom2 = bottom - 1;
28 int left = (x0 - x1) / 128;
29 int right = (x0 + x1) / 128;
30
31 if (
32 mimimi_ground_get(ground, left, bottom) != 0 &&
33 mimimi_ground_get(ground, left, bottom2) != 0 ||
34 mimimi_ground_get(ground, left, top) != 0 &&
35 mimimi_ground_get(ground, left, top2) != 0
36 )
37 {
38 if (physics->dx < 0) physics->dx = 0;
39 position->x = (left + 1) * 128 + x1;
40 }
41
42 if (
43 mimimi_ground_get(ground, right, bottom) != 0 &&
44 mimimi_ground_get(ground, right, bottom2) != 0 ||
45 mimimi_ground_get(ground, right, top) != 0 &&
46 mimimi_ground_get(ground, right, top2) != 0
47 )
48 {
49 if (physics->dx > 0) physics->dx = 0;
50 position->x = right * 128 - x1 - 1;
51 }
52}
53
54static void mimimi_slope_physics(struct mimimi_physics_data *data)
55{
56 struct mimimi_ground *ground = data->ground;
57 struct mimimi_position *position = data->position;
58 struct mimimi_physics *physics = data->physics;
59
60 int x0 = position->x;
61 int y0 = position->y;
62 int x1 = physics->width / 2;
63 int y1 = physics->height;
64
65 int top = (y0 - y1) / 128;
66 int bottom = (y0 - 127) / 128;
67 int left = (x0 - x1) / 128;
68 int right = (x0 + x1) / 128;
69
70 if (mimimi_ground_get(ground, left, bottom) != 0)
71 if (mimimi_ground_get(ground, left, top) == 0)
72 position->y = bottom * 128;
73 if (mimimi_ground_get(ground, right, bottom) != 0)
74 if (mimimi_ground_get(ground, right, top) == 0)
75 position->y = bottom * 128;
76}
77
78static void mimimi_ceiling_physics(struct mimimi_physics_data *data)
79{
80 struct mimimi_ground *ground = data->ground;
81 struct mimimi_position *position = data->position;
82 struct mimimi_physics *physics = data->physics;
83
84 if (physics->dy > 0) return;
85
86 int x0 = position->x;
87 int y0 = position->y;
88 int x1 = physics->width / 2;
89 int y1 = physics->height;
90
91 int top = (y0 - y1) / 128;
92 int top2 = top - 1;
93 int left = (x0 - x1) / 128;
94 int right = (x0 + x1) / 128;
95
96 if (mimimi_ground_get(ground, left, top) != 0 && mimimi_ground_get(ground, right, top) != 0)
97 if (mimimi_ground_get(ground, left, top2) != 0 || mimimi_ground_get(ground, right, top2) != 0)
98 {
99 physics->dy = 0;
100 position->y = (top + 1) * 128 + y1;
101 }
102}
103
104static void mimimi_landing_physics(struct mimimi_physics_data *data)
105{
106 struct mimimi_ground *ground = data->ground;
107 struct mimimi_position *position = data->position;
108 struct mimimi_physics *physics = data->physics;
109
110 int x0 = position->x;
111 int y0 = position->y;
112 int x1 = physics->width / 2;
113
114 int bottom = y0 / 128;
115 int left = (x0 - x1) / 128;
116 int right = (x0 + x1) / 128;
117
118 if (physics->dy < 0) return;
119
120 if (mimimi_ground_get(ground, left, bottom) != 0 || mimimi_ground_get(ground, right, bottom) != 0)
121 {
122 physics->airborne = 0;
123 physics->dy = 0;
124 position->y = bottom * 128;
125 }
126}
127
128static void mimimi_fall_physics(struct mimimi_physics_data *data)
129{
130 struct mimimi_ground *ground = data->ground;
131 struct mimimi_position *position = data->position;
132 struct mimimi_physics *physics = data->physics;
133
134 int x0 = position->x;
135 int y0 = position->y;
136 int x1 = physics->width / 2;
137
138 int bottom = y0 / 128;
139 int center = x0 / 128;
140 int left = (x0 - x1) / 128;
141 int right = (x0 + x1) / 128;
142
143 if (mimimi_ground_get(ground, left, bottom) == 0 && mimimi_ground_get(ground, right, bottom) == 0)
144 {
145 if (mimimi_ground_get(ground, center, (bottom + 1)) == 0)
146
147 physics->airborne = 1;
148 else
149
150 position->y = (bottom + 1) * 128;
151 }
152}
153
154static void mimimi_physics_dynamics(struct mimimi_physics_data *data)
155{
156 struct mimimi_position *position = data->position;
157 struct mimimi_physics *physics = data->physics;
158
159 position->x += physics->dx;
160 position->y += physics->dy;
161}
162
163static void mimimi_ground_physics(struct mimimi_physics_data *data)
164{
165 struct mimimi_physics *physics = data->physics;
166
167 physics->dx *= 5;
168 physics->dx /= 6;
169 physics->dy = 0;
170
171 mimimi_physics_dynamics(data);
172
173 mimimi_slope_physics(data);
174 mimimi_wall_physics(data);
175 mimimi_fall_physics(data);
176}
177
178static void mimimi_airborne_physics(struct mimimi_physics_data *data)
179{
180 struct mimimi_physics *physics = data->physics;
181
182 physics->dx *= 17;
183 physics->dx /= 18;
184 physics->dy += physics->gravity;
185
186 mimimi_physics_dynamics(data);
187
188 mimimi_ceiling_physics(data);
189 mimimi_wall_physics(data);
190 mimimi_landing_physics(data);
191}