Mirai's Miscellaneous Misadventures
M52 / 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, 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 {
21 if (ground->tiles[position->x + position->y * ground->width] == 2)
22 return;
23 }
24}
25
26void mimimi_stage(struct mimimi_stage *stage, 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) exit(1);
37 stage->clamped_camera.input = &stage->camera;
38 stage->platform_set_count = 0;
39
40 for (i = 0 ; i < count ; i++)
41 {
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 {
58 area = stage->areas + i;
59 area->ground = grounds[i];
60 right_floor_y = 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, struct mimimi_image *image)
69{
70 struct mimimi_sprite *sprite, *player;
71 int i, j, k;
72 int x, y;
73
74 player = stage->sprites;
75
76 j = 0;
77 while (player->position.x < stage->areas[j].offset.x * 128) j++;
78
79 for (i = 0 ; i < stage->sprite_count ; i++)
80 {
81 sprite = stage->sprites + i;
82
83 k = 0;
84 while (sprite->position.x < stage->areas[k].offset.x * 128) k++;
85 sprite->ground = stage->areas[k].ground;
86 sprite->offset = stage->areas[k].offset;
87 sprite->offset.x *= 128;
88 sprite->offset.y *= 128;
89
90 stage->clamped_camera.offset = stage->areas[k].offset;
91 stage->clamped_camera.size.width = stage->areas[k].ground->width;
92 stage->clamped_camera.size.height = stage->areas[k].ground->height;
93
94 mimimi_sprite_tick(sprite);
95 }
96
97 for (i = 0 ; i < stage->platform_set_count ; i++)
98 mimimi_platform_set_tick(stage->platform_sets + i);
99
100 x = player->physics.dx / 42;
101 y = player->physics.dy / 64 - 256;
102 mimimi_camera_tick(&stage->camera, &player->position, x, y);
103 mimimi_clamped_camera_tick(&stage->clamped_camera, image->width, image->height);
104
105 for (i = 0 ; i < stage->areas[j].background_count ; i++)
106 mimimi_background_tick(stage->areas[j].backgrounds + i, image, &stage->clamped_camera.output, &player->offset);
107 for (i = 0 ; i < stage->platform_set_count ; i++)
108 mimimi_platform_set_display_tick(stage->platform_sets + i, image, &stage->clamped_camera.output);
109 for (i = 0 ; i < stage->sprite_count ; i++)
110 mimimi_display_tick(stage->displays[i], image, stage->sprites + i);
111 for (i = 0 ; i < stage->areas[j].foreground_count ; i++)
112 mimimi_background_tick(stage->areas[j].foregrounds + i, image, &stage->clamped_camera.output, &player->offset);
113
114 mimimi_boxing(&stage->clamped_camera.size, image);
115}
116
117struct mimimi_sprite *mimimi_spawn(struct mimimi_stage *stage, struct mimimi_display *display, int x, int y, int width, int height)
118{
119 int i;
120
121 if (stage->sprite_count == 0)
122 {
123 stage->sprites = NULL;
124 stage->displays = NULL;
125 }
126
127 i = stage->sprite_count++;
128
129 stage->sprites = realloc(stage->sprites, sizeof *stage->sprites * stage->sprite_count);
130 stage->displays = realloc(stage->displays, sizeof *stage->displays * stage->sprite_count);
131 if (stage->sprites == NULL) exit(1);
132 if (stage->displays == NULL) exit(1);
133
134 mimimi_sprite(stage->sprites + i, NULL, x, y, width, height);
135
136 display->camera = &stage->clamped_camera.output;
137 display->animation_time = 0;
138 display->direction = 1;
139
140 stage->displays[i] = display;
141
142 if (i == 0)
143 {
144 stage->camera = stage->sprites[i].position;
145 stage->camera.y -= 256;
146 }
147
148 return stage->sprites + i;
149}
150
151void mimimi_background(struct mimimi_image *image, 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) exit(1);
160
161 for (y = 0 ; y < image->height ; y++)
162 for (x = 0 ; x < image->width ; x++)
163 {
164 color = colors[mimimi_ground_tile(ground, x / 16, y / 16)];
165 image->colors[x + y * image->width] = color;
166 }
167}