diff --git a/game/gamesave.c b/game/gamesave.c index 6a7f969..388835d 100644 --- a/game/gamesave.c +++ b/game/gamesave.c @@ -776,11 +776,12 @@ int save_game(long game_time,char *gamename, char is_autosave) temp_storage_store("playtime",&new_play_time, sizeof(new_play_time)); svf=fopen_icase(sn,"wb"); - if (svf==NULL) - { - char buff[256]; - sprintf(buff,"Nelze ulozit pozici na cestu: %s", sn); - display_error(buff); + if (svf==NULL){ + if (!is_autosave) { + char buff[256]; + sprintf(buff,"Failed to create savegame at path %s", sn); + message(1,0,0,"",buff,texty[80]); + } } else { diff --git a/platform/file_access.cpp b/platform/file_access.cpp index b6d1f15..71d13d7 100644 --- a/platform/file_access.cpp +++ b/platform/file_access.cpp @@ -7,23 +7,35 @@ #include "../libs/logfile.h" -std::filesystem::path break_and_compose_path(const std::string_view &pathname, char sep) { + +std::filesystem::path break_and_compose_path(std::string_view pathname, char sep) { + auto utf8_to_path = [](std::string_view sv) -> std::filesystem::path { + return std::filesystem::path(std::u8string(reinterpret_cast(sv.data()), sv.size())); + }; + auto p = pathname.rfind(sep); + if (p == pathname.npos) { if (pathname == "." || pathname == "..") { return std::filesystem::canonical("."); - } else if (pathname.empty()) { - return std::filesystem::current_path().root_path(); - } else if (pathname == std::filesystem::current_path().root_name()) { - return std::filesystem::current_path().root_path(); - } else { - return std::filesystem::current_path()/pathname; } - } - return break_and_compose_path(pathname.substr(0,p), sep) / pathname.substr(p+1); -} + // Detekce Windows drive letter jako "C:" + if (pathname.size() == 2 && std::isalpha(static_cast(pathname[0])) && pathname[1] == ':') { + return utf8_to_path(std::string(pathname) + "\\"); // vždy konstruujeme s \ pro root disku + } + // Kontrola na root (např. "/") – musíme převést pro porovnání + if (utf8_to_path(pathname) == std::filesystem::current_path().root_path()) { + return std::filesystem::current_path().root_path(); + } + + // Vše ostatní relativně vůči current_path + return std::filesystem::current_path() / utf8_to_path(pathname); + } + + return break_and_compose_path(pathname.substr(0, p), sep) / utf8_to_path(pathname.substr(p + 1)); +} std::filesystem::path convert_pathname_to_path(const std::string_view &pathname) { auto p = pathname.find('\\'); @@ -81,7 +93,12 @@ const char *file_icase_find(const char *pathname) { FILE *fopen_icase(const char *pathname, const char *mode) { std::filesystem::path path = try_to_find_file(convert_pathname_to_path(pathname)); +#ifdef _WIN32 + std::wstring wmode(mode, mode + std::strlen(mode)); // bezpečnější převod + return _wfopen(path.wstring().c_str(), wmode.c_str()); +#else return fopen(path.string().c_str(), mode); +#endif } static thread_local std::string build_pathname_buffer; diff --git a/platform/windows/save_folder.cpp b/platform/windows/save_folder.cpp index c0b53c9..5b002a3 100644 --- a/platform/windows/save_folder.cpp +++ b/platform/windows/save_folder.cpp @@ -15,13 +15,17 @@ std::string getSavedGamesDirectory() { PWSTR path = nullptr; if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_SavedGames, 0, NULL, &path))) { fs::path savedGamesPath(path); - CoTaskMemFree(path); - return (savedGamesPath / SAVEGAME_FOLDERNAME).string(); + CoTaskMemFree(path); + + // Převod na UTF-8 std::string + std::u8string utf8 = (savedGamesPath / SAVEGAME_FOLDERNAME).u8string(); + return std::string(reinterpret_cast(utf8.data()), utf8.size()); } else { - display_error("Failed to retrieve FOLDEROD_SavedGames"); + display_error("Failed to retrieve FOLDERID_SavedGames"); abort(); } } + const char *get_default_savegame_directory() { static std::string dir = getSavedGamesDirectory();