From c77756e6fe793ff80d36a39b711b00e8aa53a47d Mon Sep 17 00:00:00 2001 From: Steven Fuller Date: Wed, 15 Oct 2003 02:56:47 +0000 Subject: [PATCH] changed FixFilename to only lowercase the game-supplied part of a filename. added better game directory detection code. now each candidate directory is checked for validity. --- src/files.c | 11 ++-- src/main.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 138 insertions(+), 14 deletions(-) diff --git a/src/files.c b/src/files.c index 042441b..b25ddbe 100644 --- a/src/files.c +++ b/src/files.c @@ -44,15 +44,19 @@ static char *FixFilename(const char *filename, const char *prefix, int force) { char *f, *ptr; int flen; + int plen; - flen = strlen(filename) + strlen(prefix) + 2; + plen = strlen(prefix) + 1; + flen = strlen(filename) + plen + 1; f = (char *)malloc(flen); strcpy(f, prefix); strcat(f, DIR_SEPARATOR); strcat(f, filename); - ptr = f; + /* only the filename part needs to be modified */ + ptr = &f[plen+1]; + while (*ptr) { if ((*ptr == '/') || (*ptr == '\\') || (*ptr == ':')) { *ptr = DIR_SEPARATOR[0]; @@ -60,8 +64,9 @@ static char *FixFilename(const char *filename, const char *prefix, int force) *ptr = 0; break; } else { - if (force) + if (force) { *ptr = tolower(*ptr); + } } ptr++; } diff --git a/src/main.c b/src/main.c index 22918df..3a3ae71 100644 --- a/src/main.c +++ b/src/main.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include "SDL.h" #include @@ -1080,19 +1082,63 @@ void FlipBuffers() char *AvpCDPath = 0; +static int try_game_directory(char *dir, char *file) +{ + char tmppath[PATH_MAX]; + + strncpy(tmppath, dir, PATH_MAX-32); + tmppath[PATH_MAX-32] = 0; + strcat(tmppath, file); + + return access(tmppath, R_OK) == 0; +} + +static int check_game_directory(char *dir) +{ + if (!dir || !*dir) { + return 0; + } + + if (!try_game_directory(dir, "/avp_huds")) { + return 0; + } + + if (!try_game_directory(dir, "/avp_huds/alien.rif")) { + return 0; + } + + if (!try_game_directory(dir, "/avp_rifs")) { + return 0; + } + + if (!try_game_directory(dir, "/avp_rifs/temple.rif")) { + return 0; + } + + if (!try_game_directory(dir, "/fastfile")) { + return 0; + } + + if (!try_game_directory(dir, "/fastfile/ffinfo.txt")) { + return 0; + } + + return 1; +} + void InitGameDirectories(char *argv0) { extern char *SecondTex_Directory; extern char *SecondSoundDir; + + char tmppath[PATH_MAX]; char *homedir, *gamedir, *localdir, *tmp; + char *path; + size_t len, copylen; SecondTex_Directory = "graphics/"; SecondSoundDir = "sound/"; -/* - printf("argv[0] = %s\n", argv0); - printf("$HOME = %s\n", getenv("HOME")); - printf("$AVP_DATA = %s\n", getenv("AVP_DATA")); -*/ + homedir = getenv("HOME"); if (homedir == NULL) homedir = "."; @@ -1103,26 +1149,99 @@ void InitGameDirectories(char *argv0) tmp = NULL; - /* TODO: for each step, check existance of avp_rifs directory? */ + /* + 1. $AVP_DATA overrides all + 2. executable path from argv[0] + 3. realpath of executable path from argv[0] + 4. $PATH + 5. current directory + */ + + /* 1. $AVP_DATA */ gamedir = getenv("AVP_DATA"); + + /* $AVP_DATA overrides all, so no check */ + if (gamedir == NULL) { + /* 2. executable path from argv[0] */ tmp = strdup(argv0); + if (tmp == NULL) { + /* ... */ + fprintf(stderr, "InitGameDirectories failure\n"); + exit(EXIT_FAILURE); + } + gamedir = strrchr(tmp, '/'); - if (gamedir == NULL) { - gamedir = "."; - } else { + + if (gamedir) { *gamedir = 0; gamedir = tmp; + + if (!check_game_directory(gamedir)) { + gamedir = NULL; + } } } + if (gamedir == NULL) { + /* 3. realpath of executable path from argv[0] */ + + assert(tmp != NULL); + + gamedir = realpath(tmp, tmppath); + + if (!check_game_directory(gamedir)) { + gamedir = NULL; + } + } + + if (gamedir == NULL) { + /* 4. $PATH */ + path = getenv("PATH"); + if (path) { + while (*path) { + len = strcspn(path, ":"); + + copylen = min(len, PATH_MAX-1); + + strncpy(tmppath, path, copylen); + tmppath[copylen] = 0; + + if (check_game_directory(tmppath)) { + gamedir = tmppath; + break; + } + + path += len; + path += strspn(path, ":"); + } + } + } + + if (gamedir == NULL) { + /* 5. current directory */ + gamedir = "."; + } + + assert(gamedir != NULL); + + /* last chance sanity check */ + if (!check_game_directory(gamedir)) { + fprintf(stderr, "Unable to find the AvP gamedata.\n"); + fprintf(stderr, "The directory last examined was: %s\n", gamedir); + fprintf(stderr, "Has the game been installed and\n"); + fprintf(stderr, "are all game files lowercase?\n"); + exit(EXIT_FAILURE); + } + SetGameDirectories(localdir, gamedir); free(localdir); - if (tmp) + if (tmp) { free(tmp); - + } + /* delete some log files */ DeleteGameFile("dx_error.log"); }