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