Mirai's Miscellaneous Misadventures
M31 / core / displays.c
1
2
3
4#include <mimimi/allocators.h>
5#include <mimimi/behaviors.h>
6#include <mimimi/sprites.h>
7#include <mimimi/geometry.h>
8#include <mimimi/engines.h>
9#include <mimimi/chapters.h>
10#include <mimimi/assets.h>
11#include <mimimi/animations.h>
12#include <mimimi/appearances.h>
13#include <mimimi/video.h>
14
15struct mimimi_display
16{
17 struct mimimi_allocator *allocator;
18 struct mimimi_behavior *behavior;
19 struct mimimi_engine *engine;
20 struct mimimi_position *camera;
21 struct mimimi_sprite *sprite;
22 struct mimimi_video_appearance *appearance;
23 unsigned char animation_time;
24 int *direction;
25 int x;
26 int y;
27};
28
29static void mimimi_camera_stamp(struct mimimi_engine *engine, struct mimimi_position *camera, int x, int y, int z, void *texture)
30{
31 z += 8;
32 if (z <= 0) return;
33
34 x -= camera->x;
35 x /= z;
36 x += engine->size->width / 2;
37
38 y -= camera->y;
39 y /= z;
40 y += engine->size->height / 2;
41
42 (*engine->stamp)(engine->data, x, y, texture);
43}
44
45static void mimimi_display_behave(void *data)
46{
47 struct mimimi_display *display = data;
48 struct mimimi_sprite *sprite = display->sprite;
49 struct mimimi_video_appearance *appearance = display->appearance;
50
51 struct mimimi_position *position = sprite->position;
52 struct mimimi_physics *physics = sprite->physics;
53 struct mimimi_life *life = sprite->life;
54 struct mimimi_walk *walk = sprite->walk;
55
56 if (walk->direction != 0) *display->direction = walk->direction;
57
58 int dx;
59 int dy = physics->dy;
60
61 struct mimimi_video_set *videos;
62
63 if (*display->direction == 1)
64 {
65 dx = -physics->dx;
66 videos = &appearance->left;
67 }
68 if (*display->direction == 2)
69 {
70 dx = physics->dx;
71 videos = &appearance->right;
72 }
73
74 if (dx > 31) dx = 31;
75 if (dx < 0) dx = 0;
76 if (dy < 0) dy = 0;
77
78 struct mimimi_video *video;
79
80 int x = -8 * display->x;
81 int y = -8 * display->y;
82
83 if (life->knocked_time == 0)
84 {
85 if (physics->airborne != 0)
86 {
87 void *texture = videos->jumping->textures[dx * videos->jumping->count / 32];
88 mimimi_camera_stamp(display->engine, display->camera, position->x + x, position->y + y, 0, texture);
89 return;
90 }
91
92 video = videos->standing + dx * videos->standing_video_count / 32;
93 display->animation_time += dx / 4;
94 }
95 else
96 {
97 if (physics->airborne == 0)
98 video = videos->knocked,
99 y += 128;
100 else
101 video = videos->falling;
102
103 display->animation_time += dy / 8;
104 }
105
106 void *texture = video->textures[display->animation_time * video->count / 256];
107 mimimi_camera_stamp(display->engine, display->camera, position->x + x, position->y + y, 0, texture);
108}
109
110static void mimimi_display_finish(void *data)
111{
112 struct mimimi_display *display = data;
113 mimimi_deallocate(display->allocator, display->behavior);
114 mimimi_deallocate(display->allocator, display);
115}
116
117struct 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)
118{
119 struct mimimi_display *display = mimimi_allocate(allocator, sizeof *display);
120 display->allocator = allocator;
121 display->engine = engine;
122 display->camera = camera;
123 display->sprite = sprite;
124 display->appearance = appearance;
125 display->x = x;
126 display->y = y;
127
128 display->animation_time = 0;
129 display->direction = direction;
130 *direction = 1;
131
132 display->behavior = mimimi_allocate(allocator, sizeof *display->behavior);
133 display->behavior->behave = &mimimi_display_behave;
134 display->behavior->finish = &mimimi_display_finish;
135 display->behavior->data = display;
136
137 return display->behavior;
138}
139
140struct mimimi_background
141{
142 struct mimimi_allocator *allocator;
143 struct mimimi_behavior *behavior;
144 void *texture;
145 struct mimimi_position *camera;
146 struct mimimi_engine *engine;
147 int x, y, z;
148};
149
150static void mimimi_background_behave(void *data)
151{
152 struct mimimi_background *background_data = data;
153 mimimi_camera_stamp(background_data->engine, background_data->camera, background_data->x, background_data->y - 7, background_data->z, background_data->texture);
154}
155
156static void mimimi_background_finish(void *data)
157{
158 struct mimimi_background *background_data = data;
159 mimimi_deallocate(background_data->allocator, background_data->behavior);
160 mimimi_deallocate(background_data->allocator, background_data);
161}
162
163struct mimimi_behavior *mimimi_background(struct mimimi_engine *engine, struct mimimi_position *camera, void *texture, int x, int y, int z, struct mimimi_allocator *allocator)
164{
165 struct mimimi_background *data = mimimi_allocate(allocator, sizeof *data);
166 data->allocator = allocator;
167 data->texture = texture;
168 data->camera = camera;
169 data->engine = engine;
170 data->x = x;
171 data->y = y;
172 data->z = z;
173
174 data->behavior = mimimi_allocate(allocator, sizeof *data->behavior);
175 data->behavior->behave = &mimimi_background_behave;
176 data->behavior->finish = &mimimi_background_finish;
177 data->behavior->data = data;
178
179 return data->behavior;
180}
181
182struct mimimi_overlay
183{
184 struct mimimi_allocator *allocator;
185 struct mimimi_behavior *behavior;
186 struct mimimi_engine *engine;
187 void *texture;
188 int x;
189 int y;
190};
191
192static void mimimi_overlay_behave(void *data)
193{
194 struct mimimi_overlay *overlay_data = data;
195 struct mimimi_engine *engine = overlay_data->engine;
196 (*engine->stamp)(engine->data, overlay_data->x, overlay_data->y, overlay_data->texture);
197}
198
199static void mimimi_overlay_finish(void *data)
200{
201 struct mimimi_background *overlay_data = data;
202 mimimi_deallocate(overlay_data->allocator, overlay_data->behavior);
203 mimimi_deallocate(overlay_data->allocator, overlay_data);
204}
205
206struct mimimi_behavior *mimimi_overlay(struct mimimi_engine *engine, void *texture, int x, int y, struct mimimi_allocator *allocator)
207{
208 struct mimimi_overlay *data = mimimi_allocate(allocator, sizeof *data);
209 data->allocator = allocator;
210 data->engine = engine;
211 data->texture = texture;
212 data->x = x;
213 data->y = y;
214
215 data->behavior = mimimi_allocate(allocator, sizeof *data->behavior);
216 data->behavior->behave = &mimimi_overlay_behave;
217 data->behavior->finish = &mimimi_overlay_finish;
218 data->behavior->data = data;
219
220 return data->behavior;
221}