Mirai's Miscellaneous Misadventures
M54 / core / stages.c
1
2
3
4#include <stdlib.h>
5#include "../mimimi.h"
6
7static int mimimi_ground_floor(struct mimimi_ground *ground, int x)
8{
9 int y;
10 for (y = ground->height ; y > 0 ; y--) {
11 if (mimimi_ground_tile(ground, x, y - 1) == 0) return y;
12 }
13 return 0;
14}
15
16static void mimimi_origin(struct mimimi_ground *ground, struct mimimi_position *position)
17{
18 for (position->y = 0 ; position->y < ground->height ; position->y++) {
19 for (position->x = 0 ; position->x < ground->width ; position->x++) {
20 if (ground->tiles[position->x + position->y * ground->width] == 2) return;
21 }
22 }
23}
24
25void mimimi_stage(struct mimimi_stage *stage, struct mimimi_ground **grounds, int count)
26{
27 int i, k;
28 struct mimimi_position offset;
29 int left_floor_y, right_floor_y;
30 struct mimimi_area *area;
31
32 stage->sprite_count = 0;
33 stage->area_count = count;
34 stage->areas = malloc(sizeof *stage->areas * count);
35 if (stage->areas == NULL) exit(1);
36 stage->clamped_camera.input = &stage->camera;
37 stage->platform_set_count = 0;
38
39 for (i = 0 ; i < count ; i++) {
40 area = stage->areas + i;
41 area->ground = grounds[i];
42 area->background_count = 0;
43 area->foreground_count = 0;
44 }
45
46 mimimi_origin(grounds[0], &offset);
47 offset.x *= -1;
48 offset.y *= -1;
49 stage->areas[0].ground = grounds[0];
50 stage->areas[0].offset = offset;
51
52 left_floor_y = mimimi_ground_floor(grounds[0], 0);
53
54 for (i = 1 ; i < count ; i++) {
55 area = stage->areas + i;
56 area->ground = grounds[i];
57 right_floor_y = mimimi_ground_floor(grounds[i], grounds[i]->width - 1);
58 offset.x -= grounds[i]->width;
59 offset.y -= right_floor_y - left_floor_y;
60 left_floor_y = mimimi_ground_floor(grounds[i], 0);
61 area->offset = offset;
62 }
63
64 k = sizeof stage->sounds / sizeof *stage->sounds;
65
66 for (i = 0 ; i < k ; i++) {
67 stage->sounds[i].sound.count = 0;
68 stage->sounds[i].current = 0;
69 }
70}
71
72void mimimi_stage_tick(struct mimimi_stage *stage, struct mimimi_input *input)
73{
74 struct mimimi_sprite *sprite, *player;
75 int i, j, k;
76 int x, y;
77 int count;
78 struct mimimi_image *image;
79 struct mimimi_played_sound *sound;
80
81 image = &input->image;
82 player = stage->sprites;
83
84 j = 0;
85 while (player->position.x < stage->areas[j].offset.x * 128) j++;
86
87 for (i = 0 ; i < stage->sprite_count ; i++) {
88
89 sprite = stage->sprites + i;
90
91 k = 0;
92 while (sprite->position.x < stage->areas[k].offset.x * 128) k++;
93 sprite->ground = stage->areas[k].ground;
94 sprite->offset = stage->areas[k].offset;
95 sprite->offset.x *= 128;
96 sprite->offset.y *= 128;
97
98 stage->clamped_camera.offset = stage->areas[k].offset;
99 stage->clamped_camera.size.width = stage->areas[k].ground->width;
100 stage->clamped_camera.size.height = stage->areas[k].ground->height;
101
102 mimimi_sprite_tick(sprite);
103 }
104
105 for (i = 0 ; i < stage->platform_set_count ; i++) mimimi_platform_set_tick(stage->platform_sets + i);
106
107 x = player->physics.dx / 42;
108 y = player->physics.dy / 64 - 256;
109 mimimi_camera_tick(&stage->camera, &player->position, x, y);
110 mimimi_clamped_camera_tick(&stage->clamped_camera, image->width, image->height);
111
112 for (i = 0 ; i < stage->areas[j].background_count ; i++) {
113 mimimi_background_tick(stage->areas[j].backgrounds + i, image, &stage->clamped_camera.output, &player->offset);
114 }
115 for (i = 0 ; i < stage->platform_set_count ; i++) {
116 mimimi_platform_set_display_tick(stage->platform_sets + i, image, &stage->clamped_camera.output);
117 }
118 for (i = 0 ; i < stage->sprite_count ; i++) {
119 mimimi_display_tick(image, stage->sprites + i, &stage->clamped_camera.output);
120 }
121 for (i = 0 ; i < stage->areas[j].foreground_count ; i++) {
122 mimimi_background_tick(stage->areas[j].foregrounds + i, image, &stage->clamped_camera.output, &player->offset);
123 }
124
125 mimimi_boxing(&stage->clamped_camera.size, image);
126
127 count = sizeof stage->sounds / sizeof *stage->sounds;
128 k = sizeof input->notes / sizeof *input->notes;
129
130 for (i = 0 ; i < k ; i++) input->notes[i].volume = 0;
131
132 for (i = 0 ; i < count ; i++) {
133 sound = stage->sounds + i;
134 if (sound->current >= sound->sound.count) continue;
135 for (k = 0 ; k < 16 ; k++) input->notes[i * 16 + k] = sound->sound.notes[sound->current][k];
136 sound->current++;
137 }
138}
139
140struct mimimi_sprite *mimimi_spawn(struct mimimi_stage *stage, struct mimimi_model *model, int x, int y, int width, int height)
141{
142 int i;
143
144 if (stage->sprite_count == 0) stage->sprites = NULL;
145
146 i = stage->sprite_count++;
147
148 stage->sprites = realloc(stage->sprites, sizeof *stage->sprites * stage->sprite_count);
149 if (stage->sprites == NULL) exit(1);
150
151 mimimi_sprite(stage->sprites + i, model, NULL, x, y, width, height);
152
153 if (i == 0) {
154 stage->camera = stage->sprites[i].position;
155 stage->camera.y -= 256;
156 }
157
158 return stage->sprites + i;
159}
160
161void mimimi_background(struct mimimi_image *image, struct mimimi_ground *ground, unsigned char *colors)
162{
163 int x, y;
164 unsigned char color;
165
166 image->width = ground->width * 16;
167 image->height = ground->height * 16;
168 image->colors = malloc(image->width * image->height);
169 if (image->colors == NULL) exit(1);
170
171 for (y = 0 ; y < image->height ; y++) {
172 for (x = 0 ; x < image->width ; x++) {
173 color = colors[mimimi_ground_tile(ground, x / 16, y / 16)];
174 image->colors[x + y * image->width] = color;
175 }
176 }
177}
178
179void mimimi_play_sound(struct mimimi_stage *stage, struct mimimi_sound *sound)
180{
181 int i;
182 int count;
183
184 count = sizeof stage->sounds / sizeof *stage->sounds;
185
186 for (i = 0 ; i < count ; i++) {
187 if (stage->sounds[i].current >= stage->sounds[i].sound.count) break;
188 }
189
190 if (i == count) return;
191
192 stage->sounds[i].sound = *sound;
193 stage->sounds[i].current = 0;
194}
195
196void mimimi_stage_jump(void *data)
197{
198 static struct mimimi_sound sound = {{0}, 0};
199
200 struct mimimi_stage_jump *jump;
201
202 jump = data;
203 if (jump->sprite->physics.airborne == 0) mimimi_play_sound(jump->stage, &sound);
204 mimimi_jump(jump->sprite);
205}