rnd-20091101-2-src
[rocksndiamonds.git] / src / files.c
index e71ca2a26a34b72b86c04e5b0684e4135db4efbb..329e4e931187c1eb55abe3cf08d88708a5162c6c 100644 (file)
@@ -1770,19 +1770,26 @@ static char *getLevelFilenameFromBasename(char *basename)
 
 static int getFileTypeFromBasename(char *basename)
 {
+  /* !!! ALSO SEE COMMENT IN checkForPackageFromBasename() !!! */
+
   static char *filename = NULL;
   struct stat file_status;
 
   /* ---------- try to determine file type from filename ---------- */
 
   /* check for typical filename of a Supaplex level package file */
+#if 1
+  if (strlen(basename) == 10 && strPrefixLower(basename, "levels.d"))
+    return LEVEL_FILE_TYPE_SP;
+#else
   if (strlen(basename) == 10 && (strncmp(basename, "levels.d", 8) == 0 ||
                                 strncmp(basename, "LEVELS.D", 8) == 0))
     return LEVEL_FILE_TYPE_SP;
+#endif
 
   /* check for typical filename of a Diamond Caves II level package file */
-  if (strSuffix(basename, ".dc") ||
-      strSuffix(basename, ".dc2"))
+  if (strSuffixLower(basename, ".dc") ||
+      strSuffixLower(basename, ".dc2"))
     return LEVEL_FILE_TYPE_DC;
 
   /* ---------- try to determine file type from filesize ---------- */
@@ -1800,6 +1807,14 @@ static int getFileTypeFromBasename(char *basename)
   return LEVEL_FILE_TYPE_UNKNOWN;
 }
 
+static boolean checkForPackageFromBasename(char *basename)
+{
+  /* !!! WON'T WORK ANYMORE IF getFileTypeFromBasename() ALSO DETECTS !!!
+     !!! SINGLE LEVELS (CURRENTLY ONLY DETECTS LEVEL PACKAGES         !!! */
+
+  return (getFileTypeFromBasename(basename) != LEVEL_FILE_TYPE_UNKNOWN);
+}
+
 static char *getSingleLevelBasename(int nr)
 {
   static char basename[MAX_FILENAME_LEN];
@@ -1953,6 +1968,9 @@ static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi)
 
     setLevelFileInfo_FormatLevelFilename(lfi, filetype,
                                         leveldir_current->level_filename, nr);
+
+    lfi->packed = checkForPackageFromBasename(leveldir_current->level_filename);
+
     if (fileExists(lfi->filename))
       return;
   }
@@ -4157,11 +4175,12 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level,
 
 void CopyNativeLevel_RND_to_SP(struct LevelInfo *level)
 {
-  LevelInfoType *header = &native_sp_level.header;
+  struct LevelInfo_SP *level_sp = level->native_sp_level;
+  LevelInfoType *header = &level_sp->header;
   int i, x, y;
 
-  native_sp_level.width = level->fieldx;
-  native_sp_level.height = level->fieldy;
+  level_sp->width = level->fieldx;
+  level_sp->height = level->fieldy;
 
   for (x = 0; x < level->fieldx; x++)
   {
@@ -4173,12 +4192,14 @@ void CopyNativeLevel_RND_to_SP(struct LevelInfo *level)
       if (element_old >= EL_SP_START &&
          element_old <= EL_SP_END)
        element_new = element_old - EL_SP_START;
+      else if (element_old == EL_EMPTY_SPACE)
+       element_new = 0x00;
       else if (element_old == EL_INVISIBLE_WALL)
        element_new = 0x28;
       else
-       element_new = EL_SP_HARDWARE_YELLOW;    /* unknown to Supaplex engine */
+       element_new = 0x20;     /* map unknown elements to yellow "hardware" */
 
-      native_sp_level.playfield[x][y] = element_new;
+      level_sp->playfield[x][y] = element_new;
     }
   }
 
@@ -4195,17 +4216,18 @@ void CopyNativeLevel_RND_to_SP(struct LevelInfo *level)
 
 void CopyNativeLevel_SP_to_RND(struct LevelInfo *level)
 {
-  LevelInfoType *header = &native_sp_level.header;
+  struct LevelInfo_SP *level_sp = level->native_sp_level;
+  LevelInfoType *header = &level_sp->header;
   int i, x, y;
 
-  level->fieldx = native_sp_level.width;
-  level->fieldy = native_sp_level.height;
+  level->fieldx = level_sp->width;
+  level->fieldy = level_sp->height;
 
   for (x = 0; x < level->fieldx; x++)
   {
     for (y = 0; y < level->fieldy; y++)
     {
-      int element_old = native_sp_level.playfield[x][y];
+      int element_old = level_sp->playfield[x][y];
       int element_new;
 
       if (element_old <= 0x27)
@@ -4297,6 +4319,35 @@ void CopyNativeLevel_SP_to_RND(struct LevelInfo *level)
        level->yamyam_content[i].e[x][y] = EL_EMPTY;
 }
 
+static void setTapeInfoToDefaults();
+
+static void CopyNativeTape_SP_to_RND(struct LevelInfo *level)
+{
+  struct LevelInfo_SP *level_sp = level->native_sp_level;
+  struct DemoInfo_SP *demo = &level_sp->demo;
+  int i;
+
+  /* always start with reliable default values */
+  setTapeInfoToDefaults();
+
+  tape.level_nr = demo->level_nr;      /* (currently not used) */
+  tape.length = demo->length - 1;      /* without "end of demo" byte */
+  tape.random_seed = level_sp->header.DemoRandomSeed;
+
+  // tape.date = <SET FROM FILE DATE OF *.SP FILE>
+
+  for (i = 0; i < demo->length - 1; i++)
+  {
+    int demo_action = demo->data[i] & 0x0f;
+    int demo_repeat = (demo->data[i] & 0xf0) >> 4;
+
+    tape.pos[i].action[0] = map_key_SP_to_RND(demo_action);
+    tape.pos[i].delay = demo_repeat + 1;
+  }
+
+  tape.length_seconds = GetTapeLength();
+}
+
 
 /* ------------------------------------------------------------------------- */
 /* functions for loading DC level                                            */
@@ -8014,6 +8065,13 @@ void LoadSolutionTape(int nr)
   char *filename = getSolutionTapeFilename(nr);
 
   LoadTapeFromFilename(filename);
+
+#if 1
+  if (TAPE_IS_EMPTY(tape) &&
+      level.game_engine_type == GAME_ENGINE_TYPE_SP &&
+      level.native_sp_level->demo.is_available)
+    CopyNativeTape_SP_to_RND(&level);
+#endif
 }
 
 static void SaveTape_VERS(FILE *file, struct TapeInfo *tape)