From 6077980c61e1985fcc5ac969cd5e15e696498191 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sat, 27 Mar 2010 20:47:24 +0100 Subject: [PATCH] rnd-20100327-1-src * added support for native Sokoban solution files in pure 'udlrUDLR' format with extension ".sln" instead of ".tape" for solution tapes --- ChangeLog | 21 +++++++++--- src/conftime.h | 2 +- src/files.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ src/libgame/setup.c | 13 ++++++++ 4 files changed, 111 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6766943e..16909a52 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,17 +1,28 @@ +2010-03-27 + * added support for native Sokoban solution files in pure 'udlrUDLR' + format with extension ".sln" instead of ".tape" for solution tapes + 2010-03-26 * added image config suffix ".class" to be able to define classes of crumbled elements which are then separated against each others when drawing crumbled borders (class names can freely be defined) + (Example: "sand.CRUMBLED.class: sand" and "emc_grass.CRUMBLED.class: + emc_grass" results in sand and emc_grass being crumbled separately, + even if directly adjacent on the playfield.) * added image config suffix ".style" to use two new features for crumbled graphics: - - "accurate_borders": try to draw correctly crumbled corners - - "inner_corners": also draw inner corners -- this is a big kludge: + - "accurate_borders": try to draw correctly crumbled corners (which + means that a row of crumbled elements does not have two crumbled + corners for each element in the row, but only at the "real" corners + at the start and the end of the row of elements) + - "inner_corners": also draw inner corners in concave constructions + of several crumbled elements -- this is currently a big kludge: the number of frames for crumbled graphic must be "2", with the first frame as usual (crumbled graphic), while the second frame contains - the inner corners for the crumbled graphic + the graphic with inner (crumbled) corners for the crumbled graphic (These two features are mainly intended for bevelled walls, not for - diggable elements like sand; "inner_corners" only reliably works for - static walls, not for dynamically changing walls using CEs.) + diggable elements like sand; "inner_corners" only works reliably for + static walls, not for in-game dynamically changing walls using CEs.) 2010-03-16 * continued code cleanup of native Supaplex game engine diff --git a/src/conftime.h b/src/conftime.h index a00f5051..dc3844ee 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "2010-03-26 21:45" +#define COMPILE_DATE_STRING "2010-03-27 20:44" diff --git a/src/files.c b/src/files.c index 2e58ad30..91e597b1 100644 --- a/src/files.c +++ b/src/files.c @@ -8452,6 +8452,79 @@ static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape) return chunk_size; } +void LoadTape_SokobanSolution(char *filename) +{ + FILE *file; + int move_delay = TILESIZE / level.initial_player_stepsize[0]; + + if (!(file = fopen(filename, MODE_READ))) + { + tape.no_valid_file = TRUE; + + return; + } + + while (!feof(file)) + { + unsigned char c = fgetc(file); + + if (feof(file)) + break; + + switch (c) + { + case 'u': + case 'U': + tape.pos[tape.length].action[0] = MV_UP; + tape.pos[tape.length].delay = move_delay + (c < 'a' ? 2 : 0); + tape.length++; + break; + + case 'd': + case 'D': + tape.pos[tape.length].action[0] = MV_DOWN; + tape.pos[tape.length].delay = move_delay + (c < 'a' ? 2 : 0); + tape.length++; + break; + + case 'l': + case 'L': + tape.pos[tape.length].action[0] = MV_LEFT; + tape.pos[tape.length].delay = move_delay + (c < 'a' ? 2 : 0); + tape.length++; + break; + + case 'r': + case 'R': + tape.pos[tape.length].action[0] = MV_RIGHT; + tape.pos[tape.length].delay = move_delay + (c < 'a' ? 2 : 0); + tape.length++; + break; + + case '\n': + case '\r': + case '\t': + case ' ': + /* ignore white-space characters */ + break; + + default: + tape.no_valid_file = TRUE; + + Error(ERR_WARN, "unsupported Sokoban solution file '%s' ['%d']", filename, c); + + break; + } + } + + fclose(file); + + if (tape.no_valid_file) + return; + + tape.length_seconds = GetTapeLength(); +} + void LoadTapeFromFilename(char *filename) { char cookie[MAX_LINE_LEN]; @@ -8462,6 +8535,13 @@ void LoadTapeFromFilename(char *filename) /* always start with reliable default values */ setTapeInfoToDefaults(); + if (strSuffix(filename, ".sln")) + { + LoadTape_SokobanSolution(filename); + + return; + } + if (!(file = fopen(filename, MODE_READ))) { tape.no_valid_file = TRUE; @@ -8506,6 +8586,7 @@ void LoadTapeFromFilename(char *filename) Error(ERR_WARN, "unsupported version of tape file '%s'", filename); fclose(file); + return; } diff --git a/src/libgame/setup.c b/src/libgame/setup.c index 52aa7a13..3ccc5352 100644 --- a/src/libgame/setup.c +++ b/src/libgame/setup.c @@ -412,6 +412,19 @@ char *getSolutionTapeFilename(int nr) sprintf(basename, "%03d.%s", nr, TAPEFILE_EXTENSION); filename = getPath2(getSolutionTapeDir(), basename); + if (!fileExists(filename)) + { + static char *filename_sln = NULL; + + checked_free(filename_sln); + + sprintf(basename, "%03d.sln", nr); + filename_sln = getPath2(getSolutionTapeDir(), basename); + + if (fileExists(filename_sln)) + return filename_sln; + } + return filename; } -- 2.34.1