handle UTF-8 command-line paths

This commit is contained in:
Augusto Domingos
2026-09-19 14:12:35 +02:00
parent 001dfea501
commit b61b3f2a40
4 changed files with 90 additions and 27 deletions
+49 -10
View File
@@ -10,6 +10,8 @@
#include <charconv>
#include <cstdio>
#include <string_view>
#include <vector>
#include <fmt/format.h>
#include <magic_enum.hpp>
@@ -207,15 +209,19 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
}
value = Common::FixFilenameSlash(value);
if (Common::File::IsDirectoryExisting(value)) {
options.app0_dir = value;
const auto path = Common::PathFromUtf8(value);
if (Common::File::IsDirectoryExisting(path)) {
options.app0_dir = path;
options.elf = "/app0/eboot.bin";
} else if (Common::File::IsFileExisting(value)) {
options.app0_dir = Common::DirectoryWithoutFilename(value);
} else if (Common::File::IsFileExisting(path)) {
options.app0_dir = path.parent_path();
if (options.app0_dir.empty()) {
options.app0_dir = ".";
}
options.elf = "/app0/" + Common::FilenameWithoutDirectory(value);
options.elf = std::filesystem::path("/app0") / path.filename();
} else {
::printf("--game must point to an existing directory or ELF: %s\n", value.c_str());
return false;
@@ -226,7 +232,9 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
return false;
}
value = Common::FixFilenameSlash(value);
if (!Common::File::IsFileExisting(value)) {
const auto path = Common::PathFromUtf8(value);
if (!Common::File::IsFileExisting(path)) {
::printf("--game-patch must point to an existing file: %s\n", value.c_str());
return false;
}
@@ -291,14 +299,14 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
return false;
}
} else if (arg == "--shader-log-folder") {
options.config.shader_log_folder = value;
options.config.shader_log_folder = Common::PathFromUtf8(value);
} else if (arg == "--command-buffer-dump") {
if (!ParseBool(value, options.config.command_buffer_dump_enabled)) {
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());
return false;
}
} else if (arg == "--command-buffer-dump-folder") {
options.config.command_buffer_dump_folder = value;
options.config.command_buffer_dump_folder = Common::PathFromUtf8(value);
} else if (arg == "--graphics-debug-dump") {
if (!ParseBool(value, options.config.graphics_debug_dump_enabled)) {
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());
@@ -310,7 +318,7 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
return false;
}
} else if (arg == "--printf-output-file") {
options.config.printf_output_file = value;
options.config.printf_output_file = Common::PathFromUtf8(value);
} else if (arg == "--spirv-debug-printf") {
if (!ParseBool(value, options.config.spirv_debug_printf_enabled)) {
::printf("invalid boolean for %s: %s\n", arg.c_str(), value.c_str());
@@ -341,7 +349,7 @@ static bool ParseArgs(int argc, char* argv[], RunOptions& options, bool& show_he
return show_help || (!options.app0_dir.empty() && !options.elf.empty());
}
int main(int argc, char* argv[]) {
static int Main(int argc, char* argv[]) {
VirtualMemory::Init();
InitializeThreads();
@@ -367,3 +375,34 @@ int main(int argc, char* argv[]) {
return 0;
}
#if KYTY_PLATFORM == KYTY_PLATFORM_WINDOWS
int wmain(int argc, wchar_t* argv[]) {
std::vector<std::string> utf8_args;
utf8_args.reserve(static_cast<size_t>(argc));
for (int index = 0; index < argc; index++) {
const std::wstring_view wide(argv[index]);
const std::u16string utf16(wide.begin(), wide.end());
utf8_args.push_back(Common::Utf16ToUtf8(utf16));
}
std::vector<char*> utf8_argv;
utf8_argv.reserve(utf8_args.size());
for (auto& argument: utf8_args) {
utf8_argv.push_back(argument.data());
}
return Main(argc, utf8_argv.data());
}
#else
int main(int argc, char* argv[]) {
return Main(argc, argv);
}
#endif