From db06f058e4f2ae19a74806aaf28c8e2dc94ac79f Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 25 Feb 2015 03:23:42 -0600 Subject: [PATCH 1/2] Move user directory detection location to UICommon. The UI should decide on where it wants the user directory, not our core system. This is in anticipation of some upcoming work on Android which will need proper user directory setting. --- .../dolphinemu/dolphinemu/NativeLibrary.java | 6 ++ Source/Core/Common/FileUtil.cpp | 61 --------------- Source/Core/DolphinQt/Main.cpp | 1 + Source/Core/DolphinWX/Main.cpp | 9 +-- Source/Core/DolphinWX/MainAndroid.cpp | 10 +++ Source/Core/DolphinWX/MainNoGUI.cpp | 1 + Source/Core/UICommon/UICommon.cpp | 77 +++++++++++++++++++ Source/Core/UICommon/UICommon.h | 1 + 8 files changed, 98 insertions(+), 68 deletions(-) diff --git a/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java index 027d476095..91b29e4410 100644 --- a/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java +++ b/Source/Android/src/org/dolphinemu/dolphinemu/NativeLibrary.java @@ -169,6 +169,12 @@ public final class NativeLibrary */ public static native void CreateUserFolders(); + /** + * Sets the current working user directory + * If not set, it auto-detects a location + */ + public static native void SetUserDirectory(String directory); + /** * Begins emulation. * diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp index a20543e3ec..e4fc2bb5c7 100644 --- a/Source/Core/Common/FileUtil.cpp +++ b/Source/Core/Common/FileUtil.cpp @@ -21,7 +21,6 @@ #include // getcwd #include #include -#include // for SHGetFolderPath #include #else #include @@ -743,66 +742,6 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new // Set up all paths and files on the first run if (paths[D_USER_IDX].empty()) { -#ifdef _WIN32 - // Detect where the User directory is. There are five different cases (on top of the - // command line flag, which overrides all this): - // 1. GetExeDirectory()\portable.txt exists - // -> Use GetExeDirectory()\User - // 2. HKCU\Software\Dolphin Emulator\LocalUserConfig exists and is true - // -> Use GetExeDirectory()\User - // 3. HKCU\Software\Dolphin Emulator\UserConfigPath exists - // -> Use this as the user directory path - // 4. My Documents exists - // -> Use My Documents\Dolphin Emulator as the User directory path - // 5. Default - // -> Use GetExeDirectory()\User - - // Check our registry keys - HKEY hkey; - DWORD local = 0; - TCHAR configPath[MAX_PATH] = {0}; - if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Dolphin Emulator"), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) - { - DWORD size = 4; - if (RegQueryValueEx(hkey, TEXT("LocalUserConfig"), nullptr, nullptr, reinterpret_cast(&local), &size) != ERROR_SUCCESS) - local = 0; - - size = MAX_PATH; - if (RegQueryValueEx(hkey, TEXT("UserConfigPath"), nullptr, nullptr, (LPBYTE)configPath, &size) != ERROR_SUCCESS) - configPath[0] = 0; - RegCloseKey(hkey); - } - - local = local || File::Exists(GetExeDirectory() + DIR_SEP "portable.txt"); - - // Get Program Files path in case we need it. - TCHAR my_documents[MAX_PATH]; - bool my_documents_found = SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_MYDOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, my_documents)); - - if (local) // Case 1-2 - paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; - else if (configPath[0]) // Case 3 - paths[D_USER_IDX] = TStrToUTF8(configPath); - else if (my_documents_found) // Case 4 - paths[D_USER_IDX] = TStrToUTF8(my_documents) + DIR_SEP "Dolphin Emulator" DIR_SEP; - else // Case 5 - paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; - - // Prettify the path: it will be displayed in some places, we don't want a mix of \ and /. - paths[D_USER_IDX] = ReplaceAll(paths[D_USER_IDX], "\\", DIR_SEP); - - // Make sure it ends in DIR_SEP. - if (*paths[D_USER_IDX].rbegin() != DIR_SEP_CHR) - paths[D_USER_IDX] += DIR_SEP; -#else - if (File::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) - paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; - else - paths[D_USER_IDX] = std::string(getenv("HOME") ? - getenv("HOME") : getenv("PWD") ? - getenv("PWD") : "") + DIR_SEP DOLPHIN_DATA_DIR DIR_SEP; -#endif - paths[D_GCUSER_IDX] = paths[D_USER_IDX] + GC_USER_DIR DIR_SEP; paths[D_WIIROOT_IDX] = paths[D_USER_IDX] + WII_USER_DIR; paths[D_WIIUSER_IDX] = paths[D_WIIROOT_IDX] + DIR_SEP; diff --git a/Source/Core/DolphinQt/Main.cpp b/Source/Core/DolphinQt/Main.cpp index dd622a5290..65baf122da 100644 --- a/Source/Core/DolphinQt/Main.cpp +++ b/Source/Core/DolphinQt/Main.cpp @@ -42,6 +42,7 @@ int main(int argc, char* argv[]) app.setAttribute(Qt::AA_UseHighDpiPixmaps); // TODO: Add command line options + UICommon::SetUserDirectory(""); // Auto-detect user folder UICommon::CreateDirectories(); UICommon::Init(); diff --git a/Source/Core/DolphinWX/Main.cpp b/Source/Core/DolphinWX/Main.cpp index e0a36c023b..ecc7ca6e57 100644 --- a/Source/Core/DolphinWX/Main.cpp +++ b/Source/Core/DolphinWX/Main.cpp @@ -229,12 +229,7 @@ bool DolphinApp::OnInit() selectAudioEmulation = parser.Found("audio_emulation", &audioEmulationName); selectPerfDir = parser.Found("perf_dir", &perfDir); playMovie = parser.Found("movie", &movieFile); - - if (parser.Found("user", &userPath)) - { - File::CreateFullPath(WxStrToStr(userPath) + DIR_SEP); - File::GetUserPath(D_USER_IDX, userPath.ToStdString() + DIR_SEP); - } + parser.Found("user", &userPath); #endif // wxUSE_CMDLINE_PARSER // Register message box and translation handlers @@ -249,6 +244,7 @@ bool DolphinApp::OnInit() wxHandleFatalExceptions(true); #endif + UICommon::SetUserDirectory(userPath.ToStdString()); UICommon::CreateDirectories(); UICommon::Init(); @@ -421,7 +417,6 @@ void DolphinApp::OnFatalException() WiimoteReal::Shutdown(); } - // ------------ // Talk to GUI diff --git a/Source/Core/DolphinWX/MainAndroid.cpp b/Source/Core/DolphinWX/MainAndroid.cpp index 527e76f17a..78960533cd 100644 --- a/Source/Core/DolphinWX/MainAndroid.cpp +++ b/Source/Core/DolphinWX/MainAndroid.cpp @@ -49,6 +49,7 @@ ANativeWindow* surf; std::string g_filename; +std::string g_set_userpath = ""; #define DOLPHIN_TAG "Dolphinemu" @@ -231,6 +232,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetFilename( JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveState(JNIEnv *env, jobject obj, jint slot); JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadState(JNIEnv *env, jobject obj, jint slot); JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_CreateUserFolders(JNIEnv *env, jobject obj); +JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserDirectory(JNIEnv *env, jobject obj, jstring jDirectory); JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj, jobject _surf); JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_UnPauseEmulation(JNIEnv *env, jobject obj) @@ -361,6 +363,13 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_CreateUserFo File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + JAP_DIR DIR_SEP); } +JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserDirectory(JNIEnv *env, jobject obj, jstring jDirectory) +{ + std::string directory = GetJString(env, jDirectory); + g_set_userpath = directory; + UICommon::SetUserDirectory(directory); +} + JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj, jobject _surf) { surf = ANativeWindow_fromSurface(env, _surf); @@ -371,6 +380,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv * RegisterMsgAlertHandler(&MsgAlert); + UICommon::SetUserDirectory(g_set_userpath); UICommon::Init(); // No use running the loop when booting fails diff --git a/Source/Core/DolphinWX/MainNoGUI.cpp b/Source/Core/DolphinWX/MainNoGUI.cpp index 8d6d0282a6..bd82c8b4f5 100644 --- a/Source/Core/DolphinWX/MainNoGUI.cpp +++ b/Source/Core/DolphinWX/MainNoGUI.cpp @@ -324,6 +324,7 @@ int main(int argc, char* argv[]) return 1; } + UICommon::SetUserDirectory(""); // Auto-detect user folder UICommon::Init(); platform->Init(); diff --git a/Source/Core/UICommon/UICommon.cpp b/Source/Core/UICommon/UICommon.cpp index 735487306a..2c4b9b4a87 100644 --- a/Source/Core/UICommon/UICommon.cpp +++ b/Source/Core/UICommon/UICommon.cpp @@ -2,6 +2,10 @@ // Licensed under GPLv2 // Refer to the license.txt file included. +#ifdef _WIN32 +#include // for SHGetFolderPath +#endif + #include "Common/CommonPaths.h" #include "Common/FileUtil.h" #include "Common/Logging/LogManager.h" @@ -70,4 +74,77 @@ void CreateDirectories() File::CreateFullPath(File::GetUserPath(D_THEMES_IDX)); } +void SetUserDirectory(const std::string& custom_path) +{ + if (custom_path.size() != 0) + { + File::CreateFullPath(custom_path + DIR_SEP); + File::GetUserPath(D_USER_IDX, custom_path + DIR_SEP); + return; + } + + std::string user_path = ""; +#ifdef _WIN32 + // Detect where the User directory is. There are five different cases (on top of the + // command line flag, which overrides all this): + // 1. GetExeDirectory()\portable.txt exists + // -> Use GetExeDirectory()\User + // 2. HKCU\Software\Dolphin Emulator\LocalUserConfig exists and is true + // -> Use GetExeDirectory()\User + // 3. HKCU\Software\Dolphin Emulator\UserConfigPath exists + // -> Use this as the user directory path + // 4. My Documents exists + // -> Use My Documents\Dolphin Emulator as the User directory path + // 5. Default + // -> Use GetExeDirectory()\User + + // Check our registry keys + HKEY hkey; + DWORD local = 0; + TCHAR configPath[MAX_PATH] = {0}; + if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Dolphin Emulator"), 0, KEY_QUERY_VALUE, &hkey) == ERROR_SUCCESS) + { + DWORD size = 4; + if (RegQueryValueEx(hkey, TEXT("LocalUserConfig"), nullptr, nullptr, reinterpret_cast(&local), &size) != ERROR_SUCCESS) + local = 0; + + size = MAX_PATH; + if (RegQueryValueEx(hkey, TEXT("UserConfigPath"), nullptr, nullptr, (LPBYTE)configPath, &size) != ERROR_SUCCESS) + configPath[0] = 0; + RegCloseKey(hkey); + } + + local = local || File::Exists(File::GetExeDirectory() + DIR_SEP "portable.txt"); + + // Get Program Files path in case we need it. + TCHAR my_documents[MAX_PATH]; + bool my_documents_found = SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_MYDOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, my_documents)); + + if (local) // Case 1-2 + user_path = File::GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; + else if (configPath[0]) // Case 3 + user_path = TStrToUTF8(configPath); + else if (my_documents_found) // Case 4 + user_path = TStrToUTF8(my_documents) + DIR_SEP "Dolphin Emulator" DIR_SEP; + else // Case 5 + user_path = File::GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; + + // Prettify the path: it will be displayed in some places, we don't want a mix of \ and /. + user_path = ReplaceAll(user_path, "\\", DIR_SEP); + + // Make sure it ends in DIR_SEP. + if (*user_path.rbegin() != DIR_SEP_CHR) + user_path += DIR_SEP; +#else + if (File::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) + user_path = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; + else + user_path = std::string(getenv("HOME") ? + getenv("HOME") : getenv("PWD") ? + getenv("PWD") : "") + DIR_SEP DOLPHIN_DATA_DIR DIR_SEP; +#endif + + File::GetUserPath(D_USER_IDX, user_path); +} + } // namespace UICommon diff --git a/Source/Core/UICommon/UICommon.h b/Source/Core/UICommon/UICommon.h index d177727986..6a5e05fbaf 100644 --- a/Source/Core/UICommon/UICommon.h +++ b/Source/Core/UICommon/UICommon.h @@ -11,5 +11,6 @@ void Init(); void Shutdown(); void CreateDirectories(); +void SetUserDirectory(const std::string& custom_path); } // namespace UICommon From ca6e154f0bcc98ff9582f1abba9ea5ee49baafa9 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 25 Feb 2015 05:45:25 -0600 Subject: [PATCH 2/2] Fix a bug on user path re-assignment. The Load directory wasn't being properly reassigned when the user path changed, which causes a bunch of issues with things loading from the wrong place when using the -U option in Dolphin. --- Source/Core/Common/FileUtil.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp index e4fc2bb5c7..17a4a3d3c5 100644 --- a/Source/Core/Common/FileUtil.cpp +++ b/Source/Core/Common/FileUtil.cpp @@ -808,6 +808,7 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string &new paths[D_SHADERS_IDX] = paths[D_USER_IDX] + SHADERS_DIR DIR_SEP; paths[D_STATESAVES_IDX] = paths[D_USER_IDX] + STATESAVES_DIR DIR_SEP; paths[D_SCREENSHOTS_IDX] = paths[D_USER_IDX] + SCREENSHOTS_DIR DIR_SEP; + paths[D_LOAD_IDX] = paths[D_USER_IDX] + LOAD_DIR DIR_SEP; paths[D_HIRESTEXTURES_IDX] = paths[D_LOAD_IDX] + HIRES_TEXTURES_DIR DIR_SEP; paths[D_DUMP_IDX] = paths[D_USER_IDX] + DUMP_DIR DIR_SEP; paths[D_DUMPFRAMES_IDX] = paths[D_DUMP_IDX] + DUMP_FRAMES_DIR DIR_SEP;