mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-16 01:11:44 +00:00
Mac OS X: Add detection of the Steam and GOG releases of Duke 3D and the Steam release of NAM. DONT_BUILD.
git-svn-id: https://svn.eduke32.com/eduke32@4801 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
442a9bbfef
commit
0b91499ee0
5 changed files with 376 additions and 51 deletions
|
@ -761,7 +761,8 @@ char *Bgetenv(const char *name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *Bgethomedir(void);
|
char *Bgethomedir(void);
|
||||||
char *Bgetsupportdir(int32_t global);
|
char *Bgetsupportdir(void);
|
||||||
|
char *Bgetappdir(void);
|
||||||
uint32_t Bgetsysmemsize(void);
|
uint32_t Bgetsysmemsize(void);
|
||||||
int32_t Bcorrectfilename(char *filename, int32_t removefn);
|
int32_t Bcorrectfilename(char *filename, int32_t removefn);
|
||||||
int32_t Bcanonicalisefilename(char *filename, int32_t removefn);
|
int32_t Bcanonicalisefilename(char *filename, int32_t removefn);
|
||||||
|
|
|
@ -9,6 +9,11 @@ extern "C" {
|
||||||
int32_t osx_msgbox(const char *name, const char *msg);
|
int32_t osx_msgbox(const char *name, const char *msg);
|
||||||
int32_t osx_ynbox(const char *name, const char *msg);
|
int32_t osx_ynbox(const char *name, const char *msg);
|
||||||
|
|
||||||
|
char *osx_gethomedir(void);
|
||||||
|
char *osx_getsupportdir(void);
|
||||||
|
char *osx_getappdir(void);
|
||||||
|
char *osx_getapplicationsdir(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# include <shlobj.h>
|
# include <shlobj.h>
|
||||||
# include <direct.h>
|
# include <direct.h>
|
||||||
|
#elif __APPLE__
|
||||||
|
# include "osxbits.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
|
@ -25,6 +27,13 @@
|
||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||||
|
# include <libgen.h> // for dirname()
|
||||||
|
#endif
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
# include <sys/sysctl.h> // for sysctl() to get path to executable
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "baselayer.h"
|
#include "baselayer.h"
|
||||||
|
|
||||||
////////// PANICKING ALLOCATION FUNCTIONS //////////
|
////////// PANICKING ALLOCATION FUNCTIONS //////////
|
||||||
|
@ -393,22 +402,8 @@ char *Bgethomedir(void)
|
||||||
if (loaded)
|
if (loaded)
|
||||||
FreeLibrary(hShell32);
|
FreeLibrary(hShell32);
|
||||||
return NULL;
|
return NULL;
|
||||||
#elif defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_3
|
#elif defined __APPLE__
|
||||||
FSRef ref;
|
return osx_gethomedir();
|
||||||
CFStringRef str;
|
|
||||||
CFURLRef base;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
if (FSFindFolder(kUserDomain, kVolumeRootFolderType, kDontCreateFolder, &ref) < 0) return NULL;
|
|
||||||
base = CFURLCreateFromFSRef(NULL, &ref);
|
|
||||||
if (!base) return NULL;
|
|
||||||
str = CFURLCopyFileSystemPath(base, kCFURLPOSIXPathStyle);
|
|
||||||
CFRelease(base);
|
|
||||||
if (!str) return NULL;
|
|
||||||
s = (char *)CFStringGetCStringPtr(str,CFStringGetSystemEncoding());
|
|
||||||
if (s) s = Bstrdup(s);
|
|
||||||
CFRelease(str);
|
|
||||||
return s;
|
|
||||||
#elif defined(GEKKO)
|
#elif defined(GEKKO)
|
||||||
// return current drive's name
|
// return current drive's name
|
||||||
char *drv, cwd[BMAX_PATH] = {0};
|
char *drv, cwd[BMAX_PATH] = {0};
|
||||||
|
@ -424,32 +419,63 @@ char *Bgethomedir(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
char *Bgetsupportdir(int32_t global)
|
char *Bgetsupportdir(void)
|
||||||
{
|
{
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3_
|
#if defined __APPLE__
|
||||||
UNREFERENCED_PARAMETER(global);
|
return osx_getsupportdir();
|
||||||
return Bgethomedir();
|
|
||||||
#else
|
#else
|
||||||
FSRef ref;
|
return Bgethomedir();
|
||||||
CFStringRef str;
|
|
||||||
CFURLRef base;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
if (FSFindFolder(global ? kLocalDomain : kUserDomain,
|
|
||||||
kApplicationSupportFolderType,
|
|
||||||
kDontCreateFolder, &ref) < 0) return NULL;
|
|
||||||
base = CFURLCreateFromFSRef(NULL, &ref);
|
|
||||||
if (!base) return NULL;
|
|
||||||
str = CFURLCopyFileSystemPath(base, kCFURLPOSIXPathStyle);
|
|
||||||
CFRelease(base);
|
|
||||||
if (!str) return NULL;
|
|
||||||
s = (char *)CFStringGetCStringPtr(str,CFStringGetSystemEncoding());
|
|
||||||
if (s) s = Bstrdup(s);
|
|
||||||
CFRelease(str);
|
|
||||||
return s;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *Bgetappdir(void)
|
||||||
|
{
|
||||||
|
char *dir = NULL;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
TCHAR appdir[MAX_PATH];
|
||||||
|
|
||||||
|
if (GetModuleFileName(NULL, appdir, MAX_PATH) > 0) {
|
||||||
|
// trim off the filename
|
||||||
|
char *slash = strrchr(appdir, '\\');
|
||||||
|
if (slash) slash[0] = 0;
|
||||||
|
dir = strdup(appdir);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined __APPLE__
|
||||||
|
dir = osx_getappdir();
|
||||||
|
#elif defined(__linux) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||||
|
char buf[PATH_MAX] = {0};
|
||||||
|
char buf2[PATH_MAX] = {0};
|
||||||
|
# ifdef __linux
|
||||||
|
snprintf(buf, sizeof(buf), "/proc/%d/exe", getpid());
|
||||||
|
# else // the BSDs.. except for FreeBSD which has a sysctl
|
||||||
|
snprintf(buf, sizeof(buf), "/proc/%d/file", getpid());
|
||||||
|
# endif
|
||||||
|
int len = readlink(buf, buf2, sizeof(buf2));
|
||||||
|
if (len != -1) {
|
||||||
|
// remove executable name with dirname(3)
|
||||||
|
// on Linux, dirname() will modify buf2 (cutting off executable name) and return it
|
||||||
|
// on FreeBSD it seems to use some internal buffer instead.. anyway, just strdup()
|
||||||
|
dir = strdup(dirname(buf2));
|
||||||
|
}
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
// the sysctl should also work when /proc/ is not mounted (which seems to
|
||||||
|
// be common on FreeBSD), so use it..
|
||||||
|
char buf[PATH_MAX] = {0};
|
||||||
|
int name[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
|
||||||
|
size_t len = sizeof(buf)-1;
|
||||||
|
int ret = sysctl(name, sizeof(name)/sizeof(name[0]), buf, &len, NULL, 0);
|
||||||
|
if(ret == 0 && buf[0] != '\0') {
|
||||||
|
// again, remove executable name with dirname()
|
||||||
|
// on FreeBSD dirname() seems to use some internal buffer
|
||||||
|
dir = strdup(dirname(buf));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t Bcorrectfilename(char *filename, int32_t removefn)
|
int32_t Bcorrectfilename(char *filename, int32_t removefn)
|
||||||
{
|
{
|
||||||
char *fn;
|
char *fn;
|
||||||
|
|
|
@ -58,3 +58,92 @@ int osx_ynbox(const char *name, const char *msg)
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *osx_gethomedir(void)
|
||||||
|
{
|
||||||
|
NSString *path = NSHomeDirectory();
|
||||||
|
const char *Cpath = [path UTF8String];
|
||||||
|
char *returnpath = NULL;
|
||||||
|
|
||||||
|
if (Cpath)
|
||||||
|
returnpath = Bstrdup(Cpath);
|
||||||
|
|
||||||
|
[path release];
|
||||||
|
|
||||||
|
return returnpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *osx_getsupportdir(void)
|
||||||
|
{
|
||||||
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
|
||||||
|
char *returnpath = NULL;
|
||||||
|
|
||||||
|
if ([paths count] > 0)
|
||||||
|
{
|
||||||
|
const char *Cpath = [[paths objectAtIndex:0] UTF8String];
|
||||||
|
|
||||||
|
if (Cpath)
|
||||||
|
returnpath = Bstrdup(Cpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
[paths release];
|
||||||
|
|
||||||
|
return returnpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *osx_getappdir(void)
|
||||||
|
{
|
||||||
|
CFBundleRef mainBundle;
|
||||||
|
CFURLRef resUrl, fullUrl;
|
||||||
|
CFStringRef str;
|
||||||
|
const char *s;
|
||||||
|
char *dir = NULL;
|
||||||
|
|
||||||
|
mainBundle = CFBundleGetMainBundle();
|
||||||
|
if (!mainBundle) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
resUrl = CFBundleCopyResourcesDirectoryURL(mainBundle);
|
||||||
|
CFRelease(mainBundle);
|
||||||
|
if (!resUrl) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
fullUrl = CFURLCopyAbsoluteURL(resUrl);
|
||||||
|
if (fullUrl) {
|
||||||
|
CFRelease(resUrl);
|
||||||
|
resUrl = fullUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = CFURLCopyFileSystemPath(resUrl, kCFURLPOSIXPathStyle);
|
||||||
|
CFRelease(resUrl);
|
||||||
|
if (!str) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
s = CFStringGetCStringPtr(str, CFStringGetSystemEncoding());
|
||||||
|
if (s) {
|
||||||
|
dir = strdup(s);
|
||||||
|
}
|
||||||
|
CFRelease(str);
|
||||||
|
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *osx_getapplicationsdir(void)
|
||||||
|
{
|
||||||
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSAllApplicationsDirectory, NSLocalDomainMask, YES);
|
||||||
|
char *returnpath = NULL;
|
||||||
|
|
||||||
|
if ([paths count] > 0)
|
||||||
|
{
|
||||||
|
const char *Cpath = [[paths objectAtIndex:0] UTF8String];
|
||||||
|
|
||||||
|
if (Cpath)
|
||||||
|
returnpath = Bstrdup(Cpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
[paths release];
|
||||||
|
|
||||||
|
return returnpath;
|
||||||
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
# ifndef KEY_WOW64_32KEY
|
# ifndef KEY_WOW64_32KEY
|
||||||
# define KEY_WOW64_32KEY 0x0200
|
# define KEY_WOW64_32KEY 0x0200
|
||||||
# endif
|
# endif
|
||||||
|
#elif defined __APPLE__
|
||||||
|
# include "osxbits.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
@ -292,16 +294,14 @@ void G_ExtInit(void)
|
||||||
{
|
{
|
||||||
char cwd[BMAX_PATH];
|
char cwd[BMAX_PATH];
|
||||||
|
|
||||||
if (getcwd(cwd,BMAX_PATH))
|
#ifdef __APPLE__
|
||||||
{
|
char *appdir = Bgetappdir();
|
||||||
#if defined(__APPLE__)
|
addsearchpath(appdir);
|
||||||
/* Dirty hack on OS X to also look for gamedata inside the application bundle - rhoenie 08/08 */
|
Bfree(appdir);
|
||||||
char seekinappcontainer[BMAX_PATH];
|
|
||||||
Bsnprintf(seekinappcontainer,sizeof(seekinappcontainer),"%s/EDuke32.app/", cwd);
|
|
||||||
addsearchpath(seekinappcontainer);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (getcwd(cwd,BMAX_PATH) && Bstrcmp(cwd,"/") != 0)
|
||||||
addsearchpath(cwd);
|
addsearchpath(cwd);
|
||||||
}
|
|
||||||
|
|
||||||
if (CommandPaths)
|
if (CommandPaths)
|
||||||
{
|
{
|
||||||
|
@ -337,8 +337,6 @@ void G_ExtInit(void)
|
||||||
Bsnprintf(cwd,sizeof(cwd),"%s/"
|
Bsnprintf(cwd,sizeof(cwd),"%s/"
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
"EDuke32 Settings"
|
"EDuke32 Settings"
|
||||||
#elif defined(__APPLE__)
|
|
||||||
"Library/Application Support/EDuke32"
|
|
||||||
#elif defined(GEKKO)
|
#elif defined(GEKKO)
|
||||||
"apps/eduke32"
|
"apps/eduke32"
|
||||||
#else
|
#else
|
||||||
|
@ -605,6 +603,195 @@ static void G_LoadAddon(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
static void G_AddSteamPathsApple(const char *basepath)
|
||||||
|
{
|
||||||
|
char buf[BMAX_PATH];
|
||||||
|
|
||||||
|
Bsnprintf(buf, sizeof(buf), "%s/steamapps/common/Duke Nukem 3D/gameroot", basepath);
|
||||||
|
addsearchpath(buf);
|
||||||
|
|
||||||
|
Bsnprintf(buf, sizeof(buf), "%s/steamapps/common/Duke Nukem 3D/gameroot/addons/dc", basepath);
|
||||||
|
addsearchpath(buf);
|
||||||
|
|
||||||
|
Bsnprintf(buf, sizeof(buf), "%s/steamapps/common/Duke Nukem 3D/gameroot/addons/nw", basepath);
|
||||||
|
addsearchpath(buf);
|
||||||
|
|
||||||
|
Bsnprintf(buf, sizeof(buf), "%s/steamapps/common/Duke Nukem 3D/gameroot/addons/vacation", basepath);
|
||||||
|
addsearchpath(buf);
|
||||||
|
|
||||||
|
Bsnprintf(buf, sizeof(buf), "%s/steamapps/common/Nam/Nam.app/Contents/Resources/Nam.boxer/C.harddisk/NAM", basepath);
|
||||||
|
addsearchpath(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// A bare-bones "parser" for Valve's KeyValues VDF format.
|
||||||
|
// There is no guarantee this will function properly with ill-formed files.
|
||||||
|
static void KeyValues_SkipWhitespace(char **vdfbuf, char * const vdfbufend)
|
||||||
|
{
|
||||||
|
while (((*vdfbuf)[0] == ' ' || (*vdfbuf)[0] == '\n' || (*vdfbuf)[0] == '\r' || (*vdfbuf)[0] == '\t' || (*vdfbuf)[0] == '\0') && *vdfbuf < vdfbufend)
|
||||||
|
(*vdfbuf)++;
|
||||||
|
|
||||||
|
// comments
|
||||||
|
if ((*vdfbuf) + 2 < vdfbufend && (*vdfbuf)[0] == '/' && (*vdfbuf)[1] == '/')
|
||||||
|
{
|
||||||
|
while ((*vdfbuf)[0] != '\n' && (*vdfbuf)[0] != '\r' && *vdfbuf < vdfbufend)
|
||||||
|
(*vdfbuf)++;
|
||||||
|
|
||||||
|
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void KeyValues_SkipToEndOfQuotedToken(char **vdfbuf, char * const vdfbufend)
|
||||||
|
{
|
||||||
|
(*vdfbuf)++;
|
||||||
|
while ((*vdfbuf)[0] != '\"' && (*vdfbuf)[-1] != '\\' && *vdfbuf < vdfbufend)
|
||||||
|
(*vdfbuf)++;
|
||||||
|
}
|
||||||
|
static void KeyValues_SkipToEndOfUnquotedToken(char **vdfbuf, char * const vdfbufend)
|
||||||
|
{
|
||||||
|
while ((*vdfbuf)[0] != ' ' && (*vdfbuf)[0] != '\n' && (*vdfbuf)[0] != '\r' && (*vdfbuf)[0] != '\t' && (*vdfbuf)[0] != '\0' && *vdfbuf < vdfbufend)
|
||||||
|
(*vdfbuf)++;
|
||||||
|
}
|
||||||
|
static void KeyValues_SkipNextWhatever(char **vdfbuf, char * const vdfbufend)
|
||||||
|
{
|
||||||
|
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||||
|
|
||||||
|
if (*vdfbuf == vdfbufend)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((*vdfbuf)[0] == '{')
|
||||||
|
{
|
||||||
|
(*vdfbuf)++;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
|
||||||
|
}
|
||||||
|
while ((*vdfbuf)[0] != '}');
|
||||||
|
(*vdfbuf)++;
|
||||||
|
}
|
||||||
|
else if ((*vdfbuf)[0] == '\"')
|
||||||
|
KeyValues_SkipToEndOfQuotedToken(vdfbuf, vdfbufend);
|
||||||
|
else if ((*vdfbuf)[0] != '}')
|
||||||
|
KeyValues_SkipToEndOfUnquotedToken(vdfbuf, vdfbufend);
|
||||||
|
|
||||||
|
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||||
|
}
|
||||||
|
static char* KeyValues_NormalizeToken(char **vdfbuf, char * const vdfbufend)
|
||||||
|
{
|
||||||
|
char *token = *vdfbuf;
|
||||||
|
|
||||||
|
if ((*vdfbuf)[0] == '\"' && *vdfbuf < vdfbufend)
|
||||||
|
{
|
||||||
|
token++;
|
||||||
|
|
||||||
|
KeyValues_SkipToEndOfQuotedToken(vdfbuf, vdfbufend);
|
||||||
|
(*vdfbuf)[0] = '\0';
|
||||||
|
|
||||||
|
// account for escape sequences
|
||||||
|
char *writeseeker = token, *readseeker = token;
|
||||||
|
while (readseeker <= *vdfbuf)
|
||||||
|
{
|
||||||
|
if (readseeker[0] == '\\')
|
||||||
|
readseeker++;
|
||||||
|
|
||||||
|
writeseeker[0] = readseeker[0];
|
||||||
|
|
||||||
|
writeseeker++;
|
||||||
|
readseeker++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyValues_SkipToEndOfUnquotedToken(vdfbuf, vdfbufend);
|
||||||
|
(*vdfbuf)[0] = '\0';
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
static void KeyValues_FindKey(char **vdfbuf, char * const vdfbufend, const char *token)
|
||||||
|
{
|
||||||
|
char *ParentKey = KeyValues_NormalizeToken(vdfbuf, vdfbufend);
|
||||||
|
if (token != NULL) // pass in NULL to find the next key instead of a specific one
|
||||||
|
while (Bstrcmp(ParentKey, token) != 0 && *vdfbuf < vdfbufend)
|
||||||
|
{
|
||||||
|
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
|
||||||
|
ParentKey = KeyValues_NormalizeToken(vdfbuf, vdfbufend);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||||
|
}
|
||||||
|
static int32_t KeyValues_FindParentKey(char **vdfbuf, char * const vdfbufend, const char *token)
|
||||||
|
{
|
||||||
|
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||||
|
|
||||||
|
// end of scope
|
||||||
|
if ((*vdfbuf)[0] == '}')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
KeyValues_FindKey(vdfbuf, vdfbufend, token);
|
||||||
|
|
||||||
|
// ignore the wrong type
|
||||||
|
while ((*vdfbuf)[0] != '{' && *vdfbuf < vdfbufend)
|
||||||
|
{
|
||||||
|
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
|
||||||
|
KeyValues_FindKey(vdfbuf, vdfbufend, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*vdfbuf == vdfbufend)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static char* KeyValues_FindKeyValue(char **vdfbuf, char * const vdfbufend, const char *token)
|
||||||
|
{
|
||||||
|
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||||
|
|
||||||
|
// end of scope
|
||||||
|
if ((*vdfbuf)[0] == '}')
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
KeyValues_FindKey(vdfbuf, vdfbufend, token);
|
||||||
|
|
||||||
|
// ignore the wrong type
|
||||||
|
while ((*vdfbuf)[0] == '{' && *vdfbuf < vdfbufend)
|
||||||
|
{
|
||||||
|
KeyValues_SkipNextWhatever(vdfbuf, vdfbufend);
|
||||||
|
KeyValues_FindKey(vdfbuf, vdfbufend, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyValues_SkipWhitespace(vdfbuf, vdfbufend);
|
||||||
|
|
||||||
|
if (*vdfbuf == vdfbufend)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return KeyValues_NormalizeToken(vdfbuf, vdfbufend);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void G_ParseSteamKeyValuesForPaths(const char *vdf)
|
||||||
|
{
|
||||||
|
int32_t fd = Bopen(vdf, BO_RDONLY);
|
||||||
|
int32_t size = Bfilelength(fd);
|
||||||
|
char *vdfbufstart, *vdfbuf, *vdfbufend;
|
||||||
|
|
||||||
|
if (size <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vdfbufstart = vdfbuf = (char*)Bmalloc(size);
|
||||||
|
size = (int32_t)Bread(fd, vdfbuf, size);
|
||||||
|
Bclose(fd);
|
||||||
|
vdfbufend = vdfbuf + size;
|
||||||
|
|
||||||
|
if (KeyValues_FindParentKey(&vdfbuf, vdfbufend, "LibraryFolders"))
|
||||||
|
{
|
||||||
|
char *result;
|
||||||
|
vdfbuf++;
|
||||||
|
while ((result = KeyValues_FindKeyValue(&vdfbuf, vdfbufend, NULL)) != NULL)
|
||||||
|
G_AddSteamPathsApple(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bfree(vdfbufstart);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void G_AddSearchPaths(void)
|
void G_AddSearchPaths(void)
|
||||||
{
|
{
|
||||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||||
|
@ -613,10 +800,27 @@ void G_AddSearchPaths(void)
|
||||||
addsearchpath("/usr/share/games/eduke32");
|
addsearchpath("/usr/share/games/eduke32");
|
||||||
addsearchpath("/usr/local/share/games/eduke32");
|
addsearchpath("/usr/local/share/games/eduke32");
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
addsearchpath("/Library/Application Support/JFDuke3D");
|
char buf[BMAX_PATH];
|
||||||
addsearchpath("/Library/Application Support/EDuke32");
|
char *applications = osx_getapplicationsdir();
|
||||||
|
char *support = Bgetsupportdir();
|
||||||
|
|
||||||
|
Bsnprintf(buf, sizeof(buf), "%s/Steam", support);
|
||||||
|
G_AddSteamPathsApple(buf);
|
||||||
|
|
||||||
|
Bsnprintf(buf, sizeof(buf), "%s/Steam/steamapps/libraryfolders.vdf", support);
|
||||||
|
G_ParseSteamKeyValuesForPaths(buf);
|
||||||
|
|
||||||
|
Bsnprintf(buf, sizeof(buf), "%s/Duke Nukem 3D.app/Contents/Resources/Duke Nukem 3D.boxer/C.harddisk", applications);
|
||||||
|
addsearchpath(buf);
|
||||||
|
|
||||||
|
Bsnprintf(buf, sizeof(buf), "%s/JFDuke3D", support);
|
||||||
|
addsearchpath(buf);
|
||||||
|
Bsnprintf(buf, sizeof(buf), "%s/EDuke32", support);
|
||||||
|
addsearchpath(buf);
|
||||||
|
|
||||||
|
Bfree(applications);
|
||||||
|
Bfree(support);
|
||||||
#elif defined (_WIN32)
|
#elif defined (_WIN32)
|
||||||
// detect Steam and GOG versions of Duke3D
|
|
||||||
char buf[BMAX_PATH];
|
char buf[BMAX_PATH];
|
||||||
const char* instpath;
|
const char* instpath;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue