Mirai's Miscellaneous Misadventures
M53 / 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)
12 return y;
13 return 0;
14}
15
16static void mimimi_origin(struct mimimi_ground *ground,
17 struct mimimi_position *position)
18{
19 for (position->y = 0; position->y < ground->height; position->y++)
20 for (position->x = 0; position->x < ground->width; position->x++)
21 if (ground->tiles[position->x + position->y * ground->width] == 2)
22 return;
23}
24
25void mimimi_stage(struct mimimi_stage *stage,
26 struct mimimi_ground **grounds, int count)
27{
28 int i;
29 struct mimimi_position offset;
30 int left_floor_y, right_floor_y;
31 struct mimimi_area *area;
32
33 stage->sprite_count = 0;
34 stage->area_count = count;
35 stage->areas = malloc(sizeof *stage->areas * count);
36 if (stage->areas == NULL)
37 exit(1);
38 stage->clamped_camera.input = &stage->camera;
39 stage->platform_set_count = 0;
40
41 for (i = 0; i < count; i++) {
42 area = stage->areas + i;
43 area->ground = grounds[i];
44 area->background_count = 0;
45 area->foreground_count = 0;
46 }
47
48 mimimi_origin(grounds[0], &offset);
49 offset.x *= -1;
50 offset.y *= -1;
51 stage->areas[0].ground = grounds[0];
52 stage->areas[0].offset = offset;
53
54 left_floor_y = mimimi_ground_floor(grounds[0], 0);
55
56 for (i = 1; i < count; i++) {
57 area = stage->areas + i;
58 area->ground = grounds[i];
59 right_floor_y =
60 mimimi_ground_floor(grounds[i], grounds[i]->width - 1);
61 offset.x -= grounds[i]->width;
62 offset.y -= right_floor_y - left_floor_y;
63 left_floor_y = mimimi_ground_floor(grounds[i], 0);
64 area->offset = offset;
65 }
66}
67
68void mimimi_stage_tick(struct mimimi_stage *stage,
69 struct mimimi_image *image)
70{
71 struct mimimi_sprite *sprite, *player;
72 int i, j, k;
73 int x, y;
74
75 player = stage->sprites;
76
77 j = 0;
78 while (player->position.x < stage->areas[j].offset.x * 128)
79 j++;
80
81 for (i = 0; i < stage->sprite_count; i++) {
82 sprite = stage->sprites + i;
83
84 k = 0;
85 while (sprite->position.x < stage->areas[k].offset.x * 128)
86 k++;
87 sprite->ground = stage->areas[k].ground;
88 sprite->offset = stage->areas[k].offset;
89 sprite->offset.x *= 128;
90 sprite->offset.y *= 128;
91
92 stage->clamped_camera.offset = stage->areas[k].offset;
93 stage->clamped_camera.size.width = stage->areas[k].ground->width;
94 stage->clamped_camera.size.height = stage->areas[k].ground->height;
95
96 mimimi_sprite_tick(sprite);
97 }
98
99 for (i = 0; i < stage->platform_set_count; i++)
100 mimimi_platform_set_tick(stage->platform_sets + i);
101
102 x = player->physics.dx / 42;
103 y = player->physics.dy / 64 - 256;
104 mimimi_camera_tick(&stage->camera, &player->position, x, y);
105 mimimi_clamped_camera_tick(&stage->clamped_camera, image->width,
106 image->height);
107
108 for (i = 0; i < stage->areas[j].background_count; i++)
109 mimimi_background_tick(stage->areas[j].backgrounds + i, image,
110 &stage->clamped_camera.output, &player->offset);
111 for (i = 0; i < stage->platform_set_count; i++)
112 mimimi_platform_set_display_tick(stage->platform_sets + i, image,
113 &stage->clamped_camera.output);
114 for (i = 0; i < stage->sprite_count; i++)
115 mimimi_display_tick(image, stage->sprites + i,
116 &stage->clamped_camera.output);
117 for (i = 0; i < stage->areas[j].foreground_count; i++)
118 mimimi_background_tick(stage->areas[j].foregrounds + i, image,
119 &stage->clamped_camera.output, &player->offset);
120
121 mimimi_boxing(&stage->clamped_camera.size, image);
122}
123
124struct mimimi_sprite *mimimi_spawn(struct mimimi_stage *stage,
125 struct mimimi_model *model, int x, int y, int width, int height)
126{
127 int i;
128
129 if (stage->sprite_count == 0)
130 stage->sprites = NULL;
131
132 i = stage->sprite_count++;
133
134 stage->sprites =
135 realloc(stage->sprites,
136 sizeof *stage->sprites * stage->sprite_count);
137 if (stage->sprites == NULL)
138 exit(1);
139
140 mimimi_sprite(stage->sprites + i, model, NULL, x, y, width, height);
141
142 if (i == 0) {
143 stage->camera = stage->sprites[i].position;
144 stage->camera.y -= 256;
145 }
146
147 return stage->sprites + i;
148}
149
150void mimimi_background(struct mimimi_image *image,
151 struct mimimi_ground *ground, unsigned char *colors)
152{
153 int x, y;
154 unsigned char color;
155
156 image->width = ground->width * 16;
157 image->height = ground->height * 16;
158 image->colors = malloc(image->width * image->height);
159 if (image->colors == NULL)
160 exit(1);
161
162 for (y = 0; y < image->height; y++) {
163 for (x = 0; x < image->width; x++) {
164 color = colors[mimimi_ground_tile(ground, x / 16, y / 16)];
165 image->colors[x + y * image->width] = color;
166 }
167 }
168}