Add support for loading stages from a file
This commit is contained in:
parent
19f0ce06f6
commit
40f3e4e3bf
|
@ -0,0 +1,26 @@
|
|||
Example bundle
|
||||
|
||||
Stages are separated by ten dashes, and each stage must be 10 lines of 10
|
||||
characters each. At the top of the file is a free-form comment field.
|
||||
----------
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
!
|
||||
gggggggggg
|
||||
----------
|
||||
!
|
||||
D 4
|
||||
C 3 44
|
||||
3 3 4
|
||||
B
|
||||
222 2 2
|
||||
|
||||
A 1 111
|
||||
@g
|
||||
gd
|
110
switcher.c
110
switcher.c
|
@ -17,6 +17,7 @@
|
|||
enum game_mode { TITLESCREEN, STAGE };
|
||||
enum game_mode game_mode = TITLESCREEN;
|
||||
bool stages_beat[STAGES];
|
||||
size_t stages_num;
|
||||
|
||||
#define PLAYFIELD_SIDE 100
|
||||
#define TILE_SIDE 10
|
||||
|
@ -93,7 +94,8 @@ static enum palette playfield[PLAYFIELD_SIDE * PLAYFIELD_SIDE];
|
|||
#include "rebind_rebind1_alt_tile.inc"
|
||||
|
||||
static char tilemap[TILES * TILES + 1];
|
||||
static char *stages[] = {
|
||||
static char *stages[STAGES];
|
||||
static char *builtin_stages[] = {
|
||||
" "
|
||||
" "
|
||||
" "
|
||||
|
@ -446,7 +448,7 @@ static void update_stage(struct timespec now, struct timespec dt_timespec) {
|
|||
switch(sample_tilemap(midpoint_x, midpoint_y)) {
|
||||
case '!':
|
||||
stages_beat[selection_index] = true;
|
||||
if (selection_index < STAGES - 1)
|
||||
if (selection_index + 1 < stages_num)
|
||||
selection_index++;
|
||||
game_mode = TITLESCREEN;
|
||||
initialize();
|
||||
|
@ -473,7 +475,7 @@ static void update_titlescreen(struct timespec now, struct timespec dt_timespec)
|
|||
(void) dt_timespec;
|
||||
if (keys_released && left_held && selection_index > 0)
|
||||
selection_index--;
|
||||
if (keys_released && right_held && selection_index < STAGES - 1)
|
||||
if (keys_released && right_held && selection_index + 1 < stages_num)
|
||||
selection_index++;
|
||||
if (keys_released && jump_held)
|
||||
stage_selected = true;
|
||||
|
@ -549,20 +551,20 @@ static void draw_stage(struct timespec now) {
|
|||
|
||||
static void draw_titlescreen(struct timespec now) {
|
||||
(void) now;
|
||||
for (size_t i = 0; i < STAGES; i++) {
|
||||
for (size_t i = 0; i < stages_num; i++) {
|
||||
size_t x = i * TILE_SIDE + TILE_SIDE;
|
||||
size_t y = 0;
|
||||
if (stages_beat[i])
|
||||
draw_tile(star_tile, x, y);
|
||||
}
|
||||
draw_tile(stage1_tile, 1 * TILE_SIDE, TILE_SIDE);
|
||||
draw_tile(stage2_tile, 2 * TILE_SIDE, TILE_SIDE);
|
||||
draw_tile(stage3_tile, 3 * TILE_SIDE, TILE_SIDE);
|
||||
draw_tile(stage4_tile, 4 * TILE_SIDE, TILE_SIDE);
|
||||
draw_tile(stage5_tile, 5 * TILE_SIDE, TILE_SIDE);
|
||||
draw_tile(stage6_tile, 6 * TILE_SIDE, TILE_SIDE);
|
||||
draw_tile(stage7_tile, 7 * TILE_SIDE, TILE_SIDE);
|
||||
draw_tile(stage8_tile, 8 * TILE_SIDE, TILE_SIDE);
|
||||
if (stages_num >= 1) draw_tile(stage1_tile, 1 * TILE_SIDE, TILE_SIDE);
|
||||
if (stages_num >= 2) draw_tile(stage2_tile, 2 * TILE_SIDE, TILE_SIDE);
|
||||
if (stages_num >= 3) draw_tile(stage3_tile, 3 * TILE_SIDE, TILE_SIDE);
|
||||
if (stages_num >= 4) draw_tile(stage4_tile, 4 * TILE_SIDE, TILE_SIDE);
|
||||
if (stages_num >= 5) draw_tile(stage5_tile, 5 * TILE_SIDE, TILE_SIDE);
|
||||
if (stages_num >= 6) draw_tile(stage6_tile, 6 * TILE_SIDE, TILE_SIDE);
|
||||
if (stages_num >= 7) draw_tile(stage7_tile, 7 * TILE_SIDE, TILE_SIDE);
|
||||
if (stages_num >= 8) draw_tile(stage8_tile, 8 * TILE_SIDE, TILE_SIDE);
|
||||
size_t underline_y = 2 * TILE_SIDE + 1;
|
||||
size_t underline_x = selection_index * TILE_SIDE + TILE_SIDE + 2;
|
||||
for (size_t x = 0; x < TILE_SIDE - 4; x++)
|
||||
|
@ -605,7 +607,91 @@ static void draw(struct timespec now) {
|
|||
}
|
||||
}
|
||||
|
||||
static void load_stages(char *path) {
|
||||
FILE *f = fopen(path, "r");
|
||||
if (!f)
|
||||
err(1, "%s", path);
|
||||
|
||||
stages_num = 0;
|
||||
|
||||
bool in_comment = true;
|
||||
size_t linenum = 0;
|
||||
size_t stage_fill = 0;
|
||||
char *stage[10];
|
||||
while (true) {
|
||||
linenum++;
|
||||
char *line = NULL;
|
||||
size_t size = 0;
|
||||
ssize_t length = getline(&line, &size, f);
|
||||
if (length < 0) {
|
||||
break;
|
||||
free(line);
|
||||
}
|
||||
if (line[length - 1] == '\n') {
|
||||
line[length - 1] = 0;
|
||||
length--;
|
||||
}
|
||||
if (!strcmp(line, "----------")) {
|
||||
if (in_comment) {
|
||||
in_comment = false;
|
||||
continue;
|
||||
} else {
|
||||
if (stages_num == STAGES)
|
||||
errx(1, "%s: %zu: Too many stages (maximum %zu)", path, linenum, (size_t)STAGES);
|
||||
free(line);
|
||||
if (stage_fill < 10)
|
||||
errx(1, "%s: %zu: Not enough lines for a stage (expected 10, got %zu)", path, linenum, stage_fill);
|
||||
char *stage_str;
|
||||
asprintf(&stage_str, "%s%s%s%s%s%s%s%s%s%s", stage[0], stage[1], stage[2], stage[3], stage[4], stage[5], stage[6], stage[7], stage[8], stage[9]);
|
||||
stages[stages_num++] = stage_str;
|
||||
for (size_t i = 0; i < stage_fill; i++)
|
||||
free(stage[i]);
|
||||
stage_fill = 0;
|
||||
continue;
|
||||
}
|
||||
} else if (stage_fill == 10)
|
||||
errx(1, "%s: %zu: Too many lines for a stage (expected 10)", path, linenum);
|
||||
if (in_comment)
|
||||
free(line);
|
||||
else if (length < 10)
|
||||
errx(1, "%s: %zu: Line too short (expected 10 character, got %zd)", path, linenum, length);
|
||||
else if (length > 10)
|
||||
errx(1, "%s: %zu: Line too long (expected 10 character, got %zd)", path, linenum, length);
|
||||
else
|
||||
stage[stage_fill++] = line;
|
||||
}
|
||||
|
||||
if (stage_fill) {
|
||||
if (stages_num == STAGES)
|
||||
errx(1, "%s: %zu: Too many stages (maximum %zu)", path, linenum, (size_t)STAGES);
|
||||
if (stage_fill < 10)
|
||||
errx(1, "%s: %zu: Not enough lines for a stage (expected 10, got %zu)", path, linenum, stage_fill);
|
||||
char *stage_str;
|
||||
asprintf(&stage_str, "%s%s%s%s%s%s%s%s%s%s", stage[0], stage[1], stage[2], stage[3], stage[4], stage[5], stage[6], stage[7], stage[8], stage[9]);
|
||||
stages[stages_num++] = stage_str;
|
||||
for (size_t i = 0; i < stage_fill; i++)
|
||||
free(stage[i]);
|
||||
}
|
||||
|
||||
if (!stages_num)
|
||||
errx(1, "%s: Bundle did not contain any stages", path);
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc == 1) {
|
||||
stages_num = sizeof(builtin_stages) / sizeof(*builtin_stages);
|
||||
for (size_t i = 0; i < stages_num; i++) {
|
||||
stages[i] = builtin_stages[i];
|
||||
}
|
||||
} else if (argc == 2)
|
||||
load_stages(argv[1]);
|
||||
else {
|
||||
printf("Usage: %s [/path/to/stage-bundle]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct display_connection *connection = display_connect_default();
|
||||
if (!connection && errno == ECONNREFUSED)
|
||||
display_spawn(argc, argv);
|
||||
|
|
Loading…
Reference in New Issue