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).
This commit is contained in:
The Dax 2014-08-31 01:17:25 -04:00
parent cdbcc12a4e
commit 3590352429
4 changed files with 65 additions and 26 deletions

View File

@ -22,6 +22,8 @@ extern "C" void _ReadBarrier();
#else #else
#include <Windows.h> #include <Windows.h>
#include <vector>
extern std::vector<std::wstring> GetWideCmdLine();
#endif #endif
#undef min #undef min

View File

@ -694,8 +694,11 @@ std::map<std::string, std::pair<std::string, int>> GetLangValuesMapping() {
} }
void Config::Load(const char *iniFileName, const char *controllerIniFilename) { void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
iniFilename_ = FindConfigFile(iniFileName != NULL ? iniFileName : "ppsspp.ini"); const bool useIniFilename = (iniFileName != NULL) && (strlen(iniFileName) > 0);
controllerIniFilename_ = FindConfigFile(controllerIniFilename != NULL ? controllerIniFilename : "controls.ini"); 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()); INFO_LOG(LOADER, "Loading config: %s", iniFilename_.c_str());
bSaveSettings = true; bSaveSettings = true;

View File

@ -89,7 +89,27 @@ unsigned int WINAPI TheThread(void *)
Host *oldHost = host; 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 Convert<whatever>To<whatever>).
// 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<std::wstring> wideArgs = GetWideCmdLine();
std::vector<std::string> argsUTF8;
for (auto& i : wideArgs)
{
argsUTF8.push_back(ConvertWStringToUTF8(i));
}
std::vector<const char *> args;
for (auto& string: argsUTF8)
{
args.push_back(string.c_str());
}
NativeInit(args.size(), &args[0], "1234", "1234", "1234");
Host *nativeHost = host; Host *nativeHost = host;
host = oldHost; host = oldHost;

View File

@ -334,6 +334,16 @@ void MakePPSSPPDPIAware()
} }
} }
std::vector<std::wstring> GetWideCmdLine() {
wchar_t **wargv;
int wargc = -1;
wargv = CommandLineToArgvW(GetCommandLineW(), &wargc);
std::vector<std::wstring> wideArgs(wargv, wargv + wargc);
return wideArgs;
}
int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{ {
setCurrentThreadName("Main"); setCurrentThreadName("Main");
@ -385,23 +395,29 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin
osName = GetWindowsVersion() + " " + GetWindowsSystemArchitecture(); osName = GetWindowsVersion() + " " + GetWindowsSystemArchitecture();
const char *configFilename = NULL; char configFilename[MAX_PATH] = { 0 };
const char *configOption = "--config="; const std::wstring configOption = L"--config=";
const char *controlsConfigFilename = NULL; char controlsConfigFilename[MAX_PATH] = { 0 };
const char *controlsOption = "--controlconfig="; const std::wstring controlsOption = L"--controlconfig=";
for (int i = 1; i < __argc; ++i) std::vector<std::wstring> wideArgs = GetWideCmdLine();
for (size_t i = 1; i < wideArgs.size(); ++i)
{ {
if (__argv[i][0] == '\0') if (wideArgs[i][0] == L'\0')
continue; continue;
if (__argv[i][0] == '-') if (wideArgs[i][0] == L'-') {
{ if (wideArgs[i].find(configOption) != std::wstring::npos && wideArgs[i].size() > configOption.size()) {
if (!strncmp(__argv[i], configOption, strlen(configOption)) && strlen(__argv[i]) > strlen(configOption)) { const std::wstring tempWide = wideArgs[i].substr(configOption.size());
configFilename = __argv[i] + strlen(configOption); 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; bool debugLogLevel = false;
// The rest is handled in NativeInit(). // 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; continue;
if (__argv[i][0] == '-') if (wideArgs[i][0] == L'-') {
{ switch (wideArgs[i][1]) {
switch (__argv[i][1]) case L'l':
{
case 'l':
showLog = true; showLog = true;
g_Config.bEnableLogging = true; g_Config.bEnableLogging = true;
break; break;
case 's': case L's':
g_Config.bAutoRun = false; g_Config.bAutoRun = false;
g_Config.bSaveSettings = false; g_Config.bSaveSettings = false;
break; break;
case 'd': case L'd':
debugLogLevel = true; debugLogLevel = true;
break; break;
} }
if (!strncmp(__argv[i], "--fullscreen", strlen("--fullscreen"))) if (wideArgs[i] == L"--fullscreen")
g_Config.bFullScreen = true; g_Config.bFullScreen = true;
if (!strncmp(__argv[i], "--windowed", strlen("--windowed"))) if (wideArgs[i] == L"--windowed")
g_Config.bFullScreen = false; g_Config.bFullScreen = false;
} }
} }