From 2375dd1588c4d245617a6228f78db5ffc12dc9bd Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sun, 24 Jun 2012 16:17:15 +0200 Subject: [PATCH] Use My Documents/My Games/dhewm3 on windows Includes savegames, configs, screenshots and so on. And "My Documents" is actually CSIDL_PERSONAL, see http://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx This somehow matches the behaviour on Linux and OSX where this stuff is saved in some kind of home-dir (e.g. ~/.doom3) Taken (with kind permission) from Yamagi Quake II's Sys_GetHomeDir() --- neo/sys/win32/win_main.cpp | 66 +++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) diff --git a/neo/sys/win32/win_main.cpp b/neo/sys/win32/win_main.cpp index 02b60117..9f219c3d 100644 --- a/neo/sys/win32/win_main.cpp +++ b/neo/sys/win32/win_main.cpp @@ -44,6 +44,7 @@ If you have questions concerning this license or the applicable additional terms #include #include #include +#include #ifndef __MRC__ #include @@ -228,6 +229,64 @@ const char *Sys_Cwd( void ) { return cwd; } +/* +============== +Returns "My Documents"/My Games/$savedir directory (or equivalent - "CSIDL_PERSONAL"). +To be used with Sys_DefaultSavePath(), so savegames, screenshots etc will be +saved to the users files instead of systemwide. + +Based on (with kind permission) Yamagi Quake II's Sys_GetHomeDir() + +Returns the number of characters written to dst +============== + */ +static int GetHomeDir(char *dst, size_t size, const char *savedir) +{ + int len; + char profile[MAX_OSPATH]; + WCHAR sprofile[MAX_OSPATH]; + WCHAR uprofile[MAX_OSPATH]; + BOOL default_char = FALSE; + + /* Get the path to "My Documents" directory */ + SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, uprofile); + + // test if we can convert lossless + len = WideCharToMultiByte(CP_ACP, 0, uprofile, -1, profile, sizeof(profile), NULL, &default_char); + + if (default_char) { + /* The following lines implement a horrible + hack to connect the UTF-16 WinAPI to the + ASCII doom3 strings. While this should work in + most cases, it'll fail if the "Windows to + DOS filename translation" is switched off. + In that case the function will return NULL + and no homedir is used. */ + len = GetShortPathNameW(uprofile, sprofile, sizeof(sprofile)); + + if (len == 0) + return 0; + + /* Since the DOS path contains no UTF-16 characters, convert it to the system's default code page */ + len = WideCharToMultiByte(CP_ACP, 0, sprofile, len, profile, sizeof(profile) - 1, NULL, NULL); + } + + if (len == 0) + return 0; + + profile[len] = 0; + len = idStr::snPrintf(dst, size, "%s/My Games/%s", profile, savedir); + if (len >= size) + return 0; + + /* Replace backslashes by slashes */ + for (int i = 0; i < len; ++i) + if (dst[i] == '\\') + dst[i] = '/'; + + return len; +} + bool Sys_GetPath(sysPath_t type, idStr &path) { char buf[MAX_OSPATH]; @@ -237,7 +296,12 @@ bool Sys_GetPath(sysPath_t type, idStr &path) { return true; case PATH_SAVE: - path = cvarSystem->GetCVarString("fs_basepath"); + if (GetHomeDir(buf, sizeof(buf), "dhewm3") < 1) { + Sys_Error("ERROR: Couldn't get dir to home path"); + return false; + } + + path = buf; return true; case PATH_EXE: