foxygit / doom Log in
commit 4df4383d18115a25c13c4d132de01428330b5a5d
Author:     Simon Howard <fraggle@gmail.com>
AuthorDate: Fri Dec 22 15:22:40 2006 +0000
Commit:     Simon Howard <fraggle@gmail.com>
CommitDate: Fri Dec 22 15:22:40 2006 +0000

    Add definitions for PATH and directory separators.
    Allow multiple directories to be specified in DOOMWADDIR, in the same
    way as PATH.
    Make -iwad search through all search paths for the specified IWAD.

    Subversion-branch: /trunk/chocolate-doom
    Subversion-revision: 799
---
 NEWS           |   4 ++
 src/d_iwad.c   | 136 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 src/doomtype.h |  12 +++++
 src/m_misc.c   |   3 +-
 src/w_wad.c    |   4 +-
 5 files changed, 138 insertions(+), 21 deletions(-)

diff --git a/NEWS b/NEWS
index 74a4f2f8..f89e1f57 100644
--- a/NEWS
+++ b/NEWS
@@ -72,6 +72,10 @@
      * Autoadjusting the screen mode can now be disabled.
      * On Windows, the registry is queried to detect installed versions of
        Doom and automatically locate IWAD files.
+     * DOOMWADDIR can be used like PATH to specify multiple locations in
+       which to search for IWAD files.  Also, '-iwad' is now enhanced,
+       so that eg. '-iwad doom.wad' will now search all IWAD search
+       paths for 'doom.wad'.

     Portability improvements:
      * Chocolate Doom now compiles and runs cleanly on MacOS X.  Huge
diff --git a/src/d_iwad.c b/src/d_iwad.c
index 6e4d29f8..04774203 100644
--- a/src/d_iwad.c
+++ b/src/d_iwad.c
@@ -39,15 +39,20 @@
 #include "z_zone.h"

 // Array of locations to search for IWAD files
+//
+// "128 IWAD search directories should be enough for anybody".

-#define MAX_IWAD_DIRS 32
+#define MAX_IWAD_DIRS 128
 static char *iwad_dirs[MAX_IWAD_DIRS];
 static int num_iwad_dirs = 0;

 static void AddIWADDir(char *dir)
 {
-    iwad_dirs[num_iwad_dirs] = dir;
-    ++num_iwad_dirs;
+    if (num_iwad_dirs < MAX_IWAD_DIRS)
+    {
+        iwad_dirs[num_iwad_dirs] = dir;
+        ++num_iwad_dirs;
+    }
 }

 // This is Windows-specific code that automatically finds the location
@@ -276,7 +281,7 @@ static char *SearchDirectoryForIWAD(char *dir)

         filename = Z_Malloc(strlen(dir) + strlen(iwadname) + 3, PU_STATIC, 0);

-        sprintf(filename, "%s/%s", dir, iwadname);
+        sprintf(filename, "%s%c%s", dir, DIR_SEPARATOR, iwadname);

         if (M_FileExists(filename))
         {
@@ -320,26 +325,69 @@ static void IdentifyIWADByName(char *name)
 }

 //
-// Build a list of IWAD files
-//
+// Add directories from the list in the DOOMWADDIR environment variable.
+//

-static void BuildIWADDirList(void)
+static void AddDoomWadDirs(void)
 {
     char *doomwaddir;
+    char *p;

     // Check the DOOMWADDIR environment variable.

     doomwaddir = getenv("DOOMWADDIR");

-    if (doomwaddir != NULL)
+    if (doomwaddir == NULL)
     {
-        AddIWADDir(doomwaddir);
+        return;
     }

+    doomwaddir = strdup(doomwaddir);
+
+    // Add the initial directory
+
+    AddIWADDir(doomwaddir);
+
+    // Split into individual dirs within the list.
+
+    p = doomwaddir;
+
+    for (;;)
+    {
+        p = strchr(p, PATH_SEPARATOR);
+
+        if (p != NULL)
+        {
+            // Break at the separator and store the right hand side
+            // as another iwad dir
+
+            *p = '\0';
+            p += 1;
+
+            AddIWADDir(p);
+        }
+        else
+        {
+            break;
+        }
+    }
+}
+
+
+//
+// Build a list of IWAD files
+//
+
+static void BuildIWADDirList(void)
+{
     // Look in the current directory.  Doom always does this.

     AddIWADDir(".");

+    // Add dirs from DOOMWADDIR
+
+    AddDoomWadDirs();
+
 #ifdef _WIN32

     // Search the registry and find where IWADs have been installed.
@@ -357,6 +405,48 @@ static void BuildIWADDirList(void)
 #endif
 }

+//
+// Searches IWAD search paths for an IWAD with a specific name.
+//
+
+
+char *D_FindIWADByName(char *name)
+{
+    char *buf;
+    int i;
+    boolean exists;
+
+    // Absolute path?
+
+    if (M_FileExists(name))
+    {
+        return name;
+    }
+
+    // Search through all IWAD paths for a file with the given name.
+
+    for (i=0; i<num_iwad_dirs; ++i)
+    {
+        // Construct a string for the full path
+
+        buf = Z_Malloc(strlen(iwad_dirs[i]) + strlen(name) + 5, PU_STATIC, 0);
+        sprintf(buf, "%s%c%s", iwad_dirs[i], DIR_SEPARATOR, name);
+
+        exists = M_FileExists(buf);
+
+        if (exists)
+        {
+            return buf;
+        }
+
+        Z_Free(buf);
+    }
+
+    // File not found
+
+    return NULL;
+}
+
 //
 // FindIWAD
 // Checks availability of IWAD files by name,
@@ -367,22 +457,35 @@ static void BuildIWADDirList(void)
 char *D_FindIWAD(void)
 {
     char *result;
+    char *iwadfile;
     int iwadparm;
     int i;

+    // Build a list of locations to look for an IWAD
+
+    BuildIWADDirList();
+
+    // Check for the -iwad parameter
+
     iwadparm = M_CheckParm("-iwad");

     if (iwadparm)
     {
-        result = myargv[iwadparm + 1];
+        // Search through IWAD dirs for an IWAD with the given name.
+
+        iwadfile = myargv[iwadparm + 1];
+
+        result = D_FindIWADByName(iwadfile);
+
+        if (result == NULL)
+        {
+            I_Error("IWAD file '%s' not found!", iwadfile);
+        }
+
         IdentifyIWADByName(result);
     }
     else
     {
-        // Build a list of locations to look for an IWAD
-
-        BuildIWADDirList();
-
         // Search through the list and look for an IWAD

         result = NULL;
@@ -437,9 +540,8 @@ void D_SetSaveGameDir(void)
         {
             if (gamemission == iwads[i].mission)
             {
-                strcat(savegamedir, "/");
-                strcat(savegamedir, iwads[i].name);
-                strcat(savegamedir, "/");
+                sprintf(savegamedir, "%c%s%c",
+                        DIR_SEPARATOR, iwads[i].name, DIR_SEPARATOR);
                 M_MakeDirectory(savegamedir);
                 break;
             }
diff --git a/src/doomtype.h b/src/doomtype.h
index 4dbed9e6..5b2faf38 100644
--- a/src/doomtype.h
+++ b/src/doomtype.h
@@ -59,5 +59,17 @@ typedef uint8_t byte;

 #include <limits.h>

+#ifdef _WIN32
+
+#define DIR_SEPARATOR '\\'
+#define PATH_SEPARATOR ';'
+
+#else
+
+#define DIR_SEPARATOR '/'
+#define PATH_SEPARATOR ':'
+
+#endif
+
 #endif

diff --git a/src/m_misc.c b/src/m_misc.c
index 42736371..ff268ef0 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -671,7 +671,8 @@ void M_SetConfigDir(void)

         configdir = malloc(strlen(homedir) + strlen(PACKAGE_TARNAME) + 5);

-        sprintf(configdir, "%s/.%s/", homedir, PACKAGE_TARNAME);
+        sprintf(configdir, "%s%c.%s%c", homedir, DIR_SEPARATOR,
+			                PACKAGE_TARNAME, DIR_SEPARATOR);

         // make the directory if it doesnt already exist

diff --git a/src/w_wad.c b/src/w_wad.c
index 397ec457..0e438140 100644
--- a/src/w_wad.c
+++ b/src/w_wad.c
@@ -79,9 +79,7 @@ static void ExtractFileBase(char *path, char *dest)
     src = path + strlen(path) - 1;

     // back up until a \ or the start
-    while (src != path
-	   && *(src-1) != '\\'
-	   && *(src-1) != '/')
+    while (src != path && *(src - 1) != DIR_SEPARATOR)
     {
 	src--;
     }