From 3590352429042b16155c5f7f910efcfc33cf4881 Mon Sep 17 00:00:00 2001 From: The Dax Date: Sun, 31 Aug 2014 01:17:25 -0400 Subject: [PATCH] Win32: Use wide strings to parse most command-line arguments. Also do a tiny bit of cleanup in main.cpp (replacing strcmps with simple string equality checks). --- Common/CommonWindows.h | 2 ++ Core/Config.cpp | 7 +++-- Windows/EmuThread.cpp | 22 +++++++++++++++- Windows/main.cpp | 60 ++++++++++++++++++++++++++---------------- 4 files changed, 65 insertions(+), 26 deletions(-) diff --git a/Common/CommonWindows.h b/Common/CommonWindows.h index 2780a8dfed..f028f5d1de 100644 --- a/Common/CommonWindows.h +++ b/Common/CommonWindows.h @@ -22,6 +22,8 @@ extern "C" void _ReadBarrier(); #else #include +#include +extern std::vector GetWideCmdLine(); #endif #undef min diff --git a/Core/Config.cpp b/Core/Config.cpp index 3fbd6c7ef3..e65ab53c41 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -694,8 +694,11 @@ std::map> GetLangValuesMapping() { } void Config::Load(const char *iniFileName, const char *controllerIniFilename) { - iniFilename_ = FindConfigFile(iniFileName != NULL ? iniFileName : "ppsspp.ini"); - controllerIniFilename_ = FindConfigFile(controllerIniFilename != NULL ? controllerIniFilename : "controls.ini"); + const bool useIniFilename = (iniFileName != NULL) && (strlen(iniFileName) > 0); + iniFilename_ = FindConfigFile(useIniFilename ? iniFileName : "ppsspp.ini"); + + const bool useControllerIniFilename = (controllerIniFilename != NULL) && (strlen(controllerIniFilename) > 0); + controllerIniFilename_ = FindConfigFile(useControllerIniFilename ? controllerIniFilename : "controls.ini"); INFO_LOG(LOADER, "Loading config: %s", iniFilename_.c_str()); bSaveSettings = true; diff --git a/Windows/EmuThread.cpp b/Windows/EmuThread.cpp index 02fb35f110..dff7aca8b9 100644 --- a/Windows/EmuThread.cpp +++ b/Windows/EmuThread.cpp @@ -89,7 +89,27 @@ unsigned int WINAPI TheThread(void *) Host *oldHost = host; - NativeInit(__argc, (const char **)__argv, "1234", "1234", "1234"); + // Convert the command-line arguments to Unicode, then to proper UTF-8 + // (the benefit being that we don't have to pollute the UI project with win32 ifdefs and lots of ConvertTo). + // This avoids issues with PPSSPP inadvertently destroying paths with Unicode glyphs + // (using the ANSI args resulted in Japanese/Chinese glyphs being turned into question marks, at least for me..). + // -TheDax + std::vector wideArgs = GetWideCmdLine(); + std::vector argsUTF8; + for (auto& i : wideArgs) + { + argsUTF8.push_back(ConvertWStringToUTF8(i)); + } + + std::vector args; + + for (auto& string: argsUTF8) + { + args.push_back(string.c_str()); + } + + NativeInit(args.size(), &args[0], "1234", "1234", "1234"); + Host *nativeHost = host; host = oldHost; diff --git a/Windows/main.cpp b/Windows/main.cpp index 2f329a0232..d4ff963d40 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -334,6 +334,16 @@ void MakePPSSPPDPIAware() } } +std::vector GetWideCmdLine() { + wchar_t **wargv; + int wargc = -1; + wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); + + std::vector wideArgs(wargv, wargv + wargc); + + return wideArgs; +} + int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) { setCurrentThreadName("Main"); @@ -385,23 +395,29 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin osName = GetWindowsVersion() + " " + GetWindowsSystemArchitecture(); - const char *configFilename = NULL; - const char *configOption = "--config="; + char configFilename[MAX_PATH] = { 0 }; + const std::wstring configOption = L"--config="; - const char *controlsConfigFilename = NULL; - const char *controlsOption = "--controlconfig="; + char controlsConfigFilename[MAX_PATH] = { 0 }; + const std::wstring controlsOption = L"--controlconfig="; - for (int i = 1; i < __argc; ++i) + std::vector wideArgs = GetWideCmdLine(); + + for (size_t i = 1; i < wideArgs.size(); ++i) { - if (__argv[i][0] == '\0') + if (wideArgs[i][0] == L'\0') continue; - if (__argv[i][0] == '-') - { - if (!strncmp(__argv[i], configOption, strlen(configOption)) && strlen(__argv[i]) > strlen(configOption)) { - configFilename = __argv[i] + strlen(configOption); + if (wideArgs[i][0] == L'-') { + if (wideArgs[i].find(configOption) != std::wstring::npos && wideArgs[i].size() > configOption.size()) { + const std::wstring tempWide = wideArgs[i].substr(configOption.size()); + const std::string tempStr = ConvertWStringToUTF8(tempWide); + std::strncpy(configFilename, tempStr.c_str(), MAX_PATH); } - if (!strncmp(__argv[i], controlsOption, strlen(controlsOption)) && strlen(__argv[i]) > strlen(controlsOption)) { - controlsConfigFilename = __argv[i] + strlen(controlsOption); + + if (wideArgs[i].find(controlsOption) != std::wstring::npos && wideArgs[i].size() > controlsOption.size()) { + const std::wstring tempWide = wideArgs[i].substr(configOption.size()); + const std::string tempStr = ConvertWStringToUTF8(tempWide); + std::strncpy(configFilename, tempStr.c_str(), MAX_PATH); } } } @@ -420,32 +436,30 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin bool debugLogLevel = false; // The rest is handled in NativeInit(). - for (int i = 1; i < __argc; ++i) + for (size_t i = 1; i < wideArgs.size(); ++i) { - if (__argv[i][0] == '\0') + if (wideArgs[i][0] == L'\0') continue; - if (__argv[i][0] == '-') - { - switch (__argv[i][1]) - { - case 'l': + if (wideArgs[i][0] == L'-') { + switch (wideArgs[i][1]) { + case L'l': showLog = true; g_Config.bEnableLogging = true; break; - case 's': + case L's': g_Config.bAutoRun = false; g_Config.bSaveSettings = false; break; - case 'd': + case L'd': debugLogLevel = true; break; } - if (!strncmp(__argv[i], "--fullscreen", strlen("--fullscreen"))) + if (wideArgs[i] == L"--fullscreen") g_Config.bFullScreen = true; - if (!strncmp(__argv[i], "--windowed", strlen("--windowed"))) + if (wideArgs[i] == L"--windowed") g_Config.bFullScreen = false; } }