Mirai's Miscellaneous Misadventures
M55 / 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 stage->area_index = j;
87
88 for (i = 0 ; i < stage->sprite_count ; i++) {
89
90 sprite = stage->sprites + i;
91
92 k = 0;
93 while (sprite->position.x < stage->areas[k].offset.x * 128) k++;
94 sprite->ground = stage->areas[k].ground;
95 sprite->offset = stage->areas[k].offset;
96 sprite->offset.x *= 128;
97 sprite->offset.y *= 128;
98
99 stage->clamped_camera.offset = stage->areas[k].offset;
100 stage->clamped_camera.size.width = stage->areas[k].ground->width;
101 stage->clamped_camera.size.height = stage->areas[k].ground->height;
102
103 mimimi_sprite_tick(sprite);
104 }
105
106 for (i = 0 ; i < stage->platform_set_count ; i++) mimimi_platform_set_tick(stage->platform_sets + i);
107
108 x = player->physics.dx / 42;
109 y = player->physics.dy / 64 - 256;
110 mimimi_camera_tick(&stage->camera, &player->position, x, y);
111 mimimi_clamped_camera_tick(&stage->clamped_camera, image->width, image->height);
112
113 for (i = 0 ; i < stage->areas[j].background_count ; i++) {
114 mimimi_background_tick(stage->areas[j].backgrounds + i, image, &stage->clamped_camera.output, &player->offset);
115 }
116 for (i = 0 ; i < stage->platform_set_count ; i++) {
117 mimimi_platform_set_display_tick(stage->platform_sets + i, image, &stage->clamped_camera.output);
118 }
119 for (i = 0 ; i < stage->sprite_count ; i++) {
120 mimimi_display_tick(image, stage->sprites + i, &stage->clamped_camera.output);
121 }
122 for (i = 0 ; i < stage->areas[j].foreground_count ; i++) {
123 mimimi_background_tick(stage->areas[j].foregrounds + i, image, &stage->clamped_camera.output, &player->offset);
124 }
125
126 mimimi_boxing(&stage->clamped_camera.size, image);
127
128 count = sizeof stage->sounds / sizeof *stage->sounds;
129 k = sizeof input->notes / sizeof *input->notes;
130
131 for (i = 0 ; i < k ; i++) input->notes[i].volume = 0;
132
133 for (i = 0 ; i < count ; i++) {
134 sound = stage->sounds + i;
135 if (sound->current >= sound->sound.count) continue;
136 for (k = 0 ; k < 16 ; k++) input->notes[i * 16 + k] = sound->sound.notes[sound->current][k];
137 sound->current++;
138 }
139}
140
141struct mimimi_sprite *mimimi_spawn(struct mimimi_stage *stage, struct mimimi_model *model, int x, int y, int width, int height)
142{
143 int i;
144
145 if (stage->sprite_count == 0) stage->sprites = NULL;
146
147 i = stage->sprite_count++;
148
149 stage->sprites = realloc(stage->sprites, sizeof *stage->sprites * stage->sprite_count);
150 if (stage->sprites == NULL) exit(1);
151
152 mimimi_sprite(stage->sprites + i, model, NULL, x, y, width, height);
153
154 if (i == 0) {
155 stage->camera = stage->sprites[i].position;
156 stage->camera.y -= 256;
157 }
158
159 return stage->sprites + i;
160}
161
162void mimimi_background(struct mimimi_image *image, struct mimimi_ground *ground)
163{
164 int x, y;
165 unsigned char color;
166
167 image->width = ground->width * 16;
168 image->height = ground->height * 16;
169 image->colors = malloc(image->width * image->height);
170 if (image->colors == NULL) exit(1);
171
172 for (y = 0 ; y < image->height ; y++) {
173 for (x = 0 ; x < image->width ; x++) {
174 color = ground->colors[mimimi_ground_tile(ground, x / 16, y / 16)];
175 image->colors[x + y * image->width] = color;
176 }
177 }
178}
179
180void mimimi_play_sound(struct mimimi_stage *stage, struct mimimi_sound *sound)
181{
182 int i;
183 int count;
184
185 count = sizeof stage->sounds / sizeof *stage->sounds;
186
187 for (i = 0 ; i < count ; i++) {
188 if (stage->sounds[i].current >= stage->sounds[i].sound.count) break;
189 }
190
191 if (i == count) return;
192
193 stage->sounds[i].sound = *sound;
194 stage->sounds[i].current = 0;
195}
196
197void mimimi_stage_jump(void *data)
198{
199 static struct mimimi_sound sound = {{0}, 0};
200
201 struct mimimi_stage_jump *jump;
202
203 jump = data;
204 if (jump->sprite->physics.airborne == 0) mimimi_play_sound(jump->stage, &sound);
205 mimimi_jump(jump->sprite);
206}