X-Git-Url: https://git.jsancho.org/?a=blobdiff_plain;f=Source%2FMacCompatibility.cpp;h=8a295fddd281bf1dc96e5c6032a864cfeab1b44c;hb=44146d06c780d3aaa283672fedb08b8870ebe1b9;hp=b05d2b91bc27541fbc6ebec0459dce6a648b6685;hpb=68db9594c12cd81dd246c2c0c511a499ac04b2fd;p=lugaru.git diff --git a/Source/MacCompatibility.cpp b/Source/MacCompatibility.cpp index b05d2b9..8a295fd 100644 --- a/Source/MacCompatibility.cpp +++ b/Source/MacCompatibility.cpp @@ -1,3 +1,24 @@ +/* +Copyright (C) 2003, 2010 - Wolfire Games + +This file is part of Lugaru. + +Lugaru is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + #if !PLATFORM_MACOSX /**> HEADER FILES <**/ @@ -16,6 +37,7 @@ #if PLATFORM_UNIX #include #include +#include #include typedef long long __int64; typedef __int64 LARGE_INTEGER; @@ -122,9 +144,13 @@ Duration AbsoluteDeltaToDuration( AbsoluteTime& a, AbsoluteTime& b) #if PLATFORM_UNIX #include +#include +#include +#include #include -// public domain code from PhysicsFS: http://icculus.org/physfs/ +// some but not all of this is code from PhysicsFS: http://icculus.org/physfs/ +// the zlib license on physfs allows this cut-and-pasting. static int locateOneElement(char *buf) { char *ptr; @@ -167,34 +193,97 @@ static int locateOneElement(char *buf) } /* locateOneElement */ -static inline int PHYSFSEXT_locateCorrectCase(char *buf) +static inline const char *getUserDirByUID(void) +{ + struct passwd *pw = getpwuid(getuid()); + if (pw != NULL) + return(pw->pw_dir); + return(NULL); +} /* getUserDirByUID */ + + +static inline const char *getPrefPath(void) +{ + static char *prefpath = NULL; + if (prefpath == NULL) + { + const char *homedir = getenv("HOME"); + if (homedir == NULL) + homedir = getUserDirByUID(); + if (homedir == NULL) + homedir = "."; // oh well. + +#if (defined(__APPLE__) && defined(__MACH__)) + const char *PREFPATHNAME = "Library/Application Support/Lugaru"; +#else + const char *PREFPATHNAME = ".lugaru"; +#endif + size_t len = strlen(homedir) + strlen(PREFPATHNAME) + 2; + prefpath = new char[len]; + snprintf(prefpath, len, "%s/%s", homedir, PREFPATHNAME); + } + return(prefpath); +} + +static int locateCorrectCase(char *buf, bool makedirs) { int rc; char *ptr; char *prevptr; ptr = prevptr = buf; - if (*ptr == '\0') - return(0); /* Uh...I guess that's success. */ - while (ptr = strchr(ptr + 1, '/')) { *ptr = '\0'; /* block this path section off */ rc = locateOneElement(buf); - *ptr = '/'; /* restore path separator */ if (!rc) - return(-2); /* missing element in path. */ + { + if (makedirs) /* normal if we're writing; build dirs! */ + mkdir(buf, S_IRWXU); + else + { + *ptr = '/'; /* restore path separator */ + return(-2); /* missing element in path. */ + } /* else */ + } /* if */ + *ptr = '/'; /* restore path separator */ } /* while */ /* check final element... */ return(locateOneElement(buf) ? 0 : -1); -} /* PHYSFSEXT_locateCorrectCase */ +} + + +static int locateCorrectFile(char *buf, const char *mode) +{ + if (*buf == '\0') + return(0); /* Uh...I guess that's failure. */ + + assert((mode[0] == 'w') || (mode[0] == 'r')); + + bool iswriting = (mode[0] == 'w'); + const char *prefpath = getPrefPath(); + size_t len = strlen(buf) + strlen(prefpath) + 2; + char *prefpathfile = (char *) alloca(len); + snprintf(prefpathfile, len, "%s/%s", prefpath, buf); + + int rc = locateCorrectCase(prefpathfile, iswriting); /* favor prefpath. */ + if ( (rc == 0) || ((rc == -1) && (iswriting)) ) // found or create? + strcpy(buf, prefpathfile); + else if ((rc < 0) && (!iswriting)) /* not writing? Try game dir... */ + rc = locateCorrectCase(buf, iswriting); + + return(rc); +} /* locateCorrectFile */ #endif -static char g_filename[ 256]; -char* ConvertFileName( const char* orgfilename) +static char g_filename[4096]; +char* ConvertFileName( const char* orgfilename, const char *mode) { + if (orgfilename == g_filename) // recursion? + return g_filename; + // translate filename into proper path name if (orgfilename[ 0] == ':') orgfilename++; @@ -204,10 +293,13 @@ char* ConvertFileName( const char* orgfilename) { if (g_filename[ n] == ':') g_filename[ n] = '/'; + + else if (g_filename[ n] == '\\') + g_filename[ n] = '/'; } #if PLATFORM_UNIX - PHYSFSEXT_locateCorrectCase(g_filename); + locateCorrectFile(g_filename, mode); #endif return g_filename;