rnd-20100327-1-src
authorHolger Schemel <info@artsoft.org>
Sat, 27 Mar 2010 19:47:24 +0000 (20:47 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:58:56 +0000 (10:58 +0200)
* added support for native Sokoban solution files in pure 'udlrUDLR'
  format with extension ".sln" instead of ".tape" for solution tapes

ChangeLog
src/conftime.h
src/files.c
src/libgame/setup.c

index 6766943edc8ea5196d1dbfce50275995710e04a8..16909a52ca272998f76bdd4633abb39b2f116f56 100644 (file)
--- 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
index a00f5051eeb4b954409772e7bece797fc1ea37e3..dc3844eee5b1cb1b665420256a364ddf0d4d9b3f 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "2010-03-26 21:45"
+#define COMPILE_DATE_STRING "2010-03-27 20:44"
index 2e58ad30240e469571637a99b075a5267d87dd4d..91e597b1fb680e5367cb6ce4700311321b2bf6b0 100644 (file)
@@ -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;
     }
 
index 52aa7a1380798bd2c9d547063ef867764bf9d771..3ccc53524dcb5d49e88f0501750965570215e10c 100644 (file)
@@ -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;
 }