diff --git a/Editor/GeneralWindow.cpp b/Editor/GeneralWindow.cpp index 0352cd223..5c0e54a20 100644 --- a/Editor/GeneralWindow.cpp +++ b/Editor/GeneralWindow.cpp @@ -266,7 +266,9 @@ void GeneralWindow::Create(EditorComponent* _editor) params.extensions.push_back("xml"); wi::helper::FileDialog(params, [=](std::string fileName) { editor->GetGUI().ExportLocalization(editor->current_localization); - editor->current_localization.Export(wi::helper::ForceExtension(fileName, params.extensions.back())); + std::string filenameExt = wi::helper::ForceExtension(fileName, params.extensions.back()); + editor->current_localization.Export(filenameExt); + editor->PostSaveText("Localization template created: ", filenameExt); }); }); AddWidget(&localizationButton); diff --git a/Editor/languages/Magyar.xml b/Editor/languages/Magyar.xml index 19feac978..85bd85377 100644 --- a/Editor/languages/Magyar.xml +++ b/Editor/languages/Magyar.xml @@ -546,16 +546,17 @@ The Dump to header () option will use embedding and create a C++ header file Erőtér  Matrica  Hang  - Időjárás  - Emitter  - Haj Részecske  - Kamera  - Kocka  - Sík  - Animáció  - Szkript  - Ütköző  - Terep  + Videó  + Időjárás  + Emitter  + Haj Részecske  + Kamera  + Kocka  + Sík  + Animáció  + Szkript  + Ütköző  + Terep 
diff --git a/Editor/languages/日本語.xml b/Editor/languages/日本語.xml index ef70abe82..76c8dbb7c 100644 --- a/Editor/languages/日本語.xml +++ b/Editor/languages/日本語.xml @@ -547,16 +547,17 @@ The Dump to header () option will use embedding and create a C++ header file フォース  デカル  音  - 天気  - エミッター  - ヘアパーティクル  - カメラ  - 三乗  - プレーぬ  - アニメーション  - スクリプト  - コライダー  - 地形  + ビデオ  + 天気  + エミッター  + ヘアパーティクル  + カメラ  + 三乗  + プレーぬ  + アニメーション  + スクリプト  + コライダー  + 地形 
diff --git a/WickedEngine/wiBacklog.cpp b/WickedEngine/wiBacklog.cpp index 3f37aa27a..0134c943a 100644 --- a/WickedEngine/wiBacklog.cpp +++ b/WickedEngine/wiBacklog.cpp @@ -362,21 +362,17 @@ namespace wi::backlog } refitscroll = true; -#ifdef _WIN32 - OutputDebugStringA(str.c_str()); -#endif // _WIN32 - switch (level) { default: case LogLevel::Default: - std::cout << str; + wi::helper::DebugOut(str, wi::helper::DebugLevel::Normal); break; case LogLevel::Warning: - std::clog << str; + wi::helper::DebugOut(str, wi::helper::DebugLevel::Warning); break; case LogLevel::Error: - std::cerr << str; + wi::helper::DebugOut(str, wi::helper::DebugLevel::Error); break; } diff --git a/WickedEngine/wiFont.cpp b/WickedEngine/wiFont.cpp index 4e76030e8..3f4c64b65 100644 --- a/WickedEngine/wiFont.cpp +++ b/WickedEngine/wiFont.cpp @@ -324,6 +324,13 @@ namespace wi::font wi::backlog::post("wi::font Initialized (" + std::to_string((int)std::round(timer.elapsed())) + " ms)"); } + void InvalidateAtlas() + { + texture = {}; + glyph_lookup.clear(); + rect_lookup.clear(); + bitmap_lookup.clear(); + } void UpdateAtlas(float upscaling) { std::scoped_lock locker(glyphLock); @@ -334,10 +341,7 @@ namespace wi::font if (upscaling_prev != upscaling) { // If upscaling changed (DPI change), clear glyph caches, they will need to be re-rendered: - texture = {}; - glyph_lookup.clear(); - rect_lookup.clear(); - bitmap_lookup.clear(); + InvalidateAtlas(); upscaling_prev = upscaling; } @@ -483,6 +487,7 @@ namespace wi::font } fontStyles.push_back(std::make_unique()); fontStyles.back()->Create(fontName); + InvalidateAtlas(); // invalidate atlas, in case there were missing glyphs, upon adding new font style they could become valid return int(fontStyles.size() - 1); } int AddFontStyle(const std::string& fontName, const uint8_t* data, size_t size) @@ -497,6 +502,7 @@ namespace wi::font } fontStyles.push_back(std::make_unique()); fontStyles.back()->Create(fontName, data, size); + InvalidateAtlas(); // invalidate atlas, in case there were missing glyphs, upon adding new font style they could become valid return int(fontStyles.size() - 1); } diff --git a/WickedEngine/wiGraphicsDevice_DX12.cpp b/WickedEngine/wiGraphicsDevice_DX12.cpp index 549501b69..325166fe1 100644 --- a/WickedEngine/wiGraphicsDevice_DX12.cpp +++ b/WickedEngine/wiGraphicsDevice_DX12.cpp @@ -2318,9 +2318,7 @@ using namespace dx12_internal; if (FAILED(hr) || !allowTearing) { tearingSupported = false; -#ifdef _DEBUG - OutputDebugStringA("WARNING: Variable refresh rate displays not supported\n"); -#endif + wi::helper::DebugOut("WARNING: Variable refresh rate displays not supported\n"); } else { diff --git a/WickedEngine/wiHelper.cpp b/WickedEngine/wiHelper.cpp index 956b4e9c8..6d8db9f70 100644 --- a/WickedEngine/wiHelper.cpp +++ b/WickedEngine/wiHelper.cpp @@ -19,6 +19,7 @@ extern basist::etc1_global_selector_codebook g_basis_global_codebook; #include // string conversion #include #include +#include #ifdef _WIN32 #include @@ -77,7 +78,7 @@ namespace wi::helper // UWP can only show message box on main thread: wi::eventhandler::Subscribe_Once(wi::eventhandler::EVENT_THREAD_SAFE_POINT, [=](uint64_t userdata) { winrt::Windows::UI::Popups::MessageDialog(wmessage, wcaption).ShowAsync(); - }); + }); #endif // PLATFORM_UWP #elif SDL2 SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, caption.c_str(), msg.c_str(), NULL); @@ -96,7 +97,7 @@ namespace wi::helper directory = GetDirectoryFromPath(name); } - if(!directory.empty()) //PE: Crash if only filename is used with no folder. + if (!directory.empty()) //PE: Crash if only filename is used with no folder. DirectoryCreate(directory); std::string filename = name; @@ -737,6 +738,18 @@ namespace wi::helper return filename.substr(0, idx); } +#ifdef _WIN32 + // On windows we need to expand UTF8 strings to UTF16 when passing it to WinAPI: + std::wstring ToNativeString(const std::string& fileName) + { + std::wstring fileName_wide; + StringConvert(fileName, fileName_wide); + return fileName_wide; + } +#else +#define ToNativeString(x) (x) +#endif // _WIN32 + void MakePathRelative(const std::string& rootdir, std::string& path) { if (rootdir.empty() || path.empty()) @@ -754,14 +767,14 @@ namespace wi::helper #else - std::filesystem::path filepath = path; + std::filesystem::path filepath = ToNativeString(path); if (filepath.is_absolute()) { - std::filesystem::path rootpath = rootdir; - std::filesystem::path relative = std::filesystem::relative(path, rootdir); + std::filesystem::path rootpath = ToNativeString(rootdir); + std::filesystem::path relative = std::filesystem::relative(filepath, rootpath); if (!relative.empty()) { - path = relative.string(); + path = relative.generic_u8string(); } } @@ -771,17 +784,16 @@ namespace wi::helper void MakePathAbsolute(std::string& path) { - std::filesystem::path filepath = path; - std::filesystem::path absolute = std::filesystem::absolute(path); + std::filesystem::path absolute = std::filesystem::absolute(ToNativeString(path)); if (!absolute.empty()) { - path = absolute.string(); + path = absolute.generic_u8string(); } } void DirectoryCreate(const std::string& path) { - std::filesystem::create_directories(path); + std::filesystem::create_directories(ToNativeString(path)); } template typename vector_interface> @@ -790,18 +802,10 @@ namespace wi::helper #ifndef PLATFORM_UWP #ifdef SDL_FILESYSTEM_UNIX std::string filepath = fileName; - std::replace(filepath.begin(), filepath.end(), '\\', '/'); + std::replace(filepath.begin(), filepath.end(), '\\', '/'); // Linux cannot handle backslash in file path, need to convert it to forward slash std::ifstream file(filepath, std::ios::binary | std::ios::ate); #else - -#ifdef _WIN32 - std::wstring fileName_wide; - StringConvert(fileName, fileName_wide); - std::ifstream file(fileName_wide, std::ios::binary | std::ios::ate); -#else - std::ifstream file(fileName, std::ios::binary | std::ios::ate); -#endif //_WIN32 - + std::ifstream file(ToNativeString(fileName), std::ios::binary | std::ios::ate); #endif // SDL_FILESYSTEM_UNIX if (file.is_open()) { @@ -888,7 +892,7 @@ namespace wi::helper } #ifndef PLATFORM_UWP - std::ofstream file(fileName, std::ios::binary | std::ios::trunc); + std::ofstream file(ToNativeString(fileName), std::ios::binary | std::ios::trunc); if (file.is_open()) { file.write((const char*)data, (std::streamsize)size); @@ -956,7 +960,7 @@ namespace wi::helper bool FileExists(const std::string& fileName) { #ifndef PLATFORM_UWP - bool exists = std::filesystem::exists(fileName); + bool exists = std::filesystem::exists(ToNativeString(fileName)); return exists; #else using namespace winrt::Windows::Storage; @@ -1001,16 +1005,22 @@ namespace wi::helper #endif // PLATFORM_UWP } + uint64_t FileTimestamp(const std::string& fileName) + { + auto tim = std::filesystem::last_write_time(ToNativeString(fileName)); + return std::chrono::duration_cast>(tim.time_since_epoch()).count(); + } + std::string GetTempDirectoryPath() { auto path = std::filesystem::temp_directory_path(); - return path.string(); + return path.generic_u8string(); } std::string GetCurrentPath() { auto path = std::filesystem::current_path(); - return path.string(); + return path.generic_u8string(); } void FileDialog(const FileDialogParams& params, std::function onSuccess) @@ -1221,10 +1231,11 @@ namespace wi::helper void GetFileNamesInDirectory(const std::string& directory, std::function onSuccess, const std::string& filter_extension) { - if (!std::filesystem::exists(directory)) + std::filesystem::path directory_path = ToNativeString(directory); + if (!std::filesystem::exists(directory_path)) return; - for (const auto& entry : std::filesystem::directory_iterator(directory)) + for (const auto& entry : std::filesystem::directory_iterator(directory_path)) { std::string filename = entry.path().filename().generic_u8string(); if (filter_extension.empty() || wi::helper::toUpper(wi::helper::GetExtensionFromFileName(filename)).compare(filter_extension) == 0) @@ -1314,6 +1325,30 @@ namespace wi::helper #endif // _WIN32 } + void DebugOut(const std::string& str, DebugLevel level) + { +#ifdef _DEBUG +#ifdef _WIN32 + std::wstring wstr = ToNativeString(str); + OutputDebugString(wstr.c_str()); +#else + switch (level) + { + default: + case DebugLevel::Normal: + std::cout << str; + break; + case DebugLevel::Warning: + std::clog << str; + break; + case DebugLevel::Error: + std::cerr << str; + break; + } +#endif // _WIN32 +#endif // _DEBUG + } + void Sleep(float milliseconds) { std::this_thread::sleep_for(std::chrono::milliseconds((int)milliseconds)); diff --git a/WickedEngine/wiHelper.h b/WickedEngine/wiHelper.h index d118f8e00..e9904a279 100644 --- a/WickedEngine/wiHelper.h +++ b/WickedEngine/wiHelper.h @@ -96,6 +96,8 @@ namespace wi::helper bool FileExists(const std::string& fileName); + uint64_t FileTimestamp(const std::string& fileName); + std::string GetTempDirectoryPath(); std::string GetCurrentPath(); @@ -129,6 +131,15 @@ namespace wi::helper // returns result string length int StringConvert(const wchar_t* from, char* to); + // Prints debug info to the console output + enum class DebugLevel + { + Normal, + Warning, + Error + }; + void DebugOut(const std::string& str, DebugLevel level = DebugLevel::Normal); + // Puts the current thread to sleeping state for a given time (OS can overtake) void Sleep(float milliseconds); diff --git a/WickedEngine/wiShaderCompiler.cpp b/WickedEngine/wiShaderCompiler.cpp index 34c87f24e..80c701127 100644 --- a/WickedEngine/wiShaderCompiler.cpp +++ b/WickedEngine/wiShaderCompiler.cpp @@ -6,7 +6,6 @@ #include "wiUnorderedSet.h" #include -#include #ifdef PLATFORM_WINDOWS_DESKTOP #define SHADERCOMPILER_ENABLED @@ -741,7 +740,7 @@ namespace wi::shadercompiler return false; // no metadata file = no dependency, up to date (for example packaged builds) } - const auto tim = std::filesystem::last_write_time(filepath); + const uint64_t tim = wi::helper::FileTimestamp(filepath); wi::Archive dependencyLibrary(dependencylibrarypath); if (dependencyLibrary.IsOpen()) @@ -756,7 +755,7 @@ namespace wi::shadercompiler wi::helper::MakePathAbsolute(dependencypath); if (wi::helper::FileExists(dependencypath)) { - const auto dep_tim = std::filesystem::last_write_time(dependencypath); + const uint64_t dep_tim = wi::helper::FileTimestamp(dependencypath); if (tim < dep_tim) { diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 2980bf22d..7e0a4e37b 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 270; + const int revision = 271; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision); @@ -89,6 +89,7 @@ Contributors - Fixes - Dennis Brakhane | https://github.com/brakhane - Added Liberation Sans default font + - Vulkan improvements - Cop46 | https://github.com/Cop46 - Brightness, Contrast, Saturation post process @@ -131,6 +132,7 @@ Patreon supporters - Dominik Madarász - Segfault - Mike amanfo +- Dennis Brakhane )"; return credits;