Unicode support.

This commit is contained in:
Dario 2024-12-15 11:39:24 -03:00
parent 52b4f0ee5e
commit 6a6dcea781
8 changed files with 42 additions and 29 deletions

View file

@ -52,7 +52,7 @@ static std::unique_ptr<VirtualFileSystem> createFileSystemFromPath(const std::fi
{
return XContentFileSystem::create(path);
}
else if (toLower(path.extension().string()) == ISOExtension)
else if (toLower(fromPath(path.extension())) == ISOExtension)
{
return ISOFileSystem::create(path);
}
@ -122,7 +122,7 @@ static bool copyFile(const FilePair &pair, const uint64_t *fileHashes, VirtualFi
if (!outStream.is_open())
{
journal.lastResult = Journal::Result::FileCreationFailed;
journal.lastErrorMessage = fmt::format("Failed to create file at {}.", targetPath.string());
journal.lastErrorMessage = fmt::format("Failed to create file at {}.", fromPath(targetPath));
return false;
}
@ -132,7 +132,7 @@ static bool copyFile(const FilePair &pair, const uint64_t *fileHashes, VirtualFi
if (outStream.bad())
{
journal.lastResult = Journal::Result::FileWriteFailed;
journal.lastErrorMessage = fmt::format("Failed to create file at {}.", targetPath.string());
journal.lastErrorMessage = fmt::format("Failed to create file at {}.", fromPath(targetPath));
return false;
}
@ -162,7 +162,7 @@ static DLC detectDLC(const std::filesystem::path &sourcePath, VirtualFileSystem
if (typeStartLocation == nullptr || typeEndLocation == nullptr)
{
journal.lastResult = Journal::Result::DLCParsingFailed;
journal.lastErrorMessage = "Failed to find DLC type for " + sourcePath.string() + ".";
journal.lastErrorMessage = "Failed to find DLC type for " + fromPath(sourcePath) + ".";
return DLC::Unknown;
}
@ -171,7 +171,7 @@ static DLC detectDLC(const std::filesystem::path &sourcePath, VirtualFileSystem
if (typeNumberCount != 1)
{
journal.lastResult = Journal::Result::UnknownDLCType;
journal.lastErrorMessage = "DLC type for " + sourcePath.string() + " is unknown.";
journal.lastErrorMessage = "DLC type for " + fromPath(sourcePath) + " is unknown.";
return DLC::Unknown;
}
@ -191,7 +191,7 @@ static DLC detectDLC(const std::filesystem::path &sourcePath, VirtualFileSystem
return DLC::EmpireCityAdabat;
default:
journal.lastResult = Journal::Result::UnknownDLCType;
journal.lastErrorMessage = "DLC type for " + sourcePath.string() + " is unknown.";
journal.lastErrorMessage = "DLC type for " + fromPath(sourcePath) + " is unknown.";
return DLC::Unknown;
}
}

View file

@ -49,7 +49,7 @@ SWA_API FileHandle* XCreateFileA
assert(((dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) == 0) && "Unknown share mode bits.");
assert(((dwCreationDisposition & ~(CREATE_NEW | CREATE_ALWAYS)) == 0) && "Unknown creation disposition bits.");
std::filesystem::path filePath = FileSystem::TransformPath(lpFileName);
std::filesystem::path filePath = std::u8string_view((const char8_t*)(FileSystem::TransformPath(lpFileName)));
std::fstream fileStream;
std::ios::openmode fileOpenMode = std::ios::binary;
if (dwDesiredAccess & (GENERIC_READ | FILE_READ_DATA))
@ -238,15 +238,15 @@ FindHandle* XFindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData
std::filesystem::path dirPath;
if (strstr(transformedPath, "\\*") == (&transformedPath[transformedPathLength - 2]))
{
dirPath = std::string(transformedPath, transformedPathLength - 2);
dirPath = std::u8string_view((const char8_t*)(transformedPath), transformedPathLength - 2);
}
else if (strstr(transformedPath, "\\*.*") == (&transformedPath[transformedPathLength - 4]))
{
dirPath = std::string(transformedPath, transformedPathLength - 4);
dirPath = std::u8string_view((const char8_t *)(transformedPath), transformedPathLength - 4);
}
else
{
dirPath = std::string(transformedPath, transformedPathLength);
dirPath = std::u8string_view((const char8_t *)(transformedPath), transformedPathLength);
assert(!dirPath.has_extension() && "Unknown search pattern.");
}
@ -310,7 +310,7 @@ BOOL XReadFileEx(FileHandle* hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
DWORD XGetFileAttributesA(LPCSTR lpFileName)
{
std::filesystem::path filePath = FileSystem::TransformPath(lpFileName);
std::filesystem::path filePath(std::u8string_view((const char8_t*)(FileSystem::TransformPath(lpFileName))));
if (std::filesystem::is_directory(filePath))
return FILE_ATTRIBUTE_DIRECTORY;
else if (std::filesystem::is_regular_file(filePath))

View file

@ -303,7 +303,8 @@ SWA_API uint32_t XamContentCreateEx(DWORD dwUserIndex, LPCSTR szRootName, const
if (pContentData->dwContentType == XCONTENTTYPE_SAVEDATA)
{
root = GetSavePath().string();
std::u8string savePathU8 = GetSavePath().u8string();
root = (const char *)(savePathU8.c_str());
}
else if (pContentData->dwContentType == XCONTENTTYPE_DLC)
{

View file

@ -56,9 +56,11 @@ void KiSystemStartup()
const auto savePath = GetSavePath();
const auto saveName = "SYS-DATA";
// TODO: implement save slots?
if (std::filesystem::exists(savePath / saveName))
XamRegisterContent(XamMakeContent(XCONTENTTYPE_SAVEDATA, saveName), savePath.string());
{
std::u8string savePathU8 = savePath.u8string();
XamRegisterContent(XamMakeContent(XCONTENTTYPE_SAVEDATA, saveName), (const char *)(savePathU8.c_str()));
}
// Mount game
XamContentCreateEx(0, "game", &gameContent, OPEN_EXISTING, nullptr, nullptr, 0, 0, nullptr);
@ -91,9 +93,9 @@ void KiSystemStartup()
XAudioInitializeSystem();
}
uint32_t LdrLoadModule(const char* path)
uint32_t LdrLoadModule(const std::filesystem::path &path)
{
auto loadResult = LoadFile(FileSystem::TransformPath(GAME_XEX_PATH));
auto loadResult = LoadFile(path);
if (loadResult.empty())
{
assert("Failed to load module" && false);
@ -175,7 +177,8 @@ int main(int argc, char *argv[])
KiSystemStartup();
uint32_t entry = LdrLoadModule(FileSystem::TransformPath(GAME_XEX_PATH));
const char *modulePath = FileSystem::TransformPath(GAME_XEX_PATH);
uint32_t entry = LdrLoadModule(std::u8string_view((const char8_t*)(modulePath)));
if (!runInstallerWizard)
Video::CreateHostDevice();

View file

@ -2,9 +2,9 @@
std::filesystem::path os::process::detail::GetExecutablePath()
{
char exePath[MAX_PATH];
WCHAR exePath[MAX_PATH];
if (!GetModuleFileNameA(nullptr, exePath, MAX_PATH))
if (!GetModuleFileNameW(nullptr, exePath, MAX_PATH))
return std::filesystem::path();
return std::filesystem::path(exePath);
@ -12,9 +12,9 @@ std::filesystem::path os::process::detail::GetExecutablePath()
std::filesystem::path os::process::detail::GetWorkingDirectory()
{
char workPath[MAX_PATH];
WCHAR workPath[MAX_PATH];
if (!GetCurrentDirectoryA(MAX_PATH, workPath))
if (!GetCurrentDirectoryW(MAX_PATH, workPath))
return std::filesystem::path();
return std::filesystem::path(workPath);
@ -28,14 +28,17 @@ bool os::process::detail::StartProcess(const std::filesystem::path path, const s
if (work.empty())
work = path.parent_path();
auto cli = path.string();
auto cli = path.wstring();
// NOTE: We assume the CLI arguments only contain ASCII characters.
for (auto& arg : args)
cli += " " + arg;
cli += L" " + std::wstring(arg.begin(), arg.end());
STARTUPINFOA startInfo{ sizeof(STARTUPINFOA) };
STARTUPINFOW startInfo{ sizeof(STARTUPINFOW) };
PROCESS_INFORMATION procInfo{};
if (!CreateProcessA(path.string().c_str(), cli.data(), nullptr, nullptr, false, 0, nullptr, work.string().c_str(), &startInfo, &procInfo))
std::wstring pathW = path.wstring();
std::wstring workW = work.wstring();
if (!CreateProcessW(pathW.c_str(), cli.data(), nullptr, nullptr, false, 0, nullptr, workW.c_str(), &startInfo, &procInfo))
return false;
CloseHandle(procInfo.hProcess);

View file

@ -973,7 +973,8 @@ static void ParseSourcePaths(std::list<std::filesystem::path> &paths)
stringStream << Localise("Installer_Message_InvalidFilesList") << std::endl;
for (const std::filesystem::path &path : failedPaths)
{
stringStream << std::endl << "- " << Truncate(path.filename().string(), 32, true, true);
std::u8string filenameU8 = path.filename().u8string();
stringStream << std::endl << "- " << Truncate(std::string(filenameU8.begin(), filenameU8.end()), 32, true, true);
}
if (isFailedPathsOverLimit)

View file

@ -13,7 +13,12 @@ void Config::Load()
try
{
auto toml = toml::parse_file(configPath.string());
toml::parse_result toml;
std::ifstream tomlStream(configPath);
if (tomlStream.is_open())
{
toml = toml::parse(tomlStream);
}
for (auto def : Config::Definitions)
{

@ -1 +1 @@
Subproject commit 847842cd28a2427b9db520d2aaa7416e5dec3822
Subproject commit 45c00cfec6c2ad141ebf8fce1f5dbcdde2816e94