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