diff --git a/CUE4Parse b/CUE4Parse index 7ea875e5..50d5e06d 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit 7ea875e520ce683f03ca46c688e9bee1aad32fa4 +Subproject commit 50d5e06d421e2935cc4107df6352b36c341ec7c0 diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj index 51f3260a..3822bf06 100644 --- a/FModel/FModel.csproj +++ b/FModel/FModel.csproj @@ -45,6 +45,12 @@ + + + + + + @@ -145,7 +151,7 @@ - + @@ -181,6 +187,12 @@ + + + + + + diff --git a/FModel/Framework/ImGuiController.cs b/FModel/Framework/ImGuiController.cs index 9077553b..8e1e2c91 100644 --- a/FModel/Framework/ImGuiController.cs +++ b/FModel/Framework/ImGuiController.cs @@ -1,10 +1,13 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; using System.Numerics; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Windows; using System.Windows.Forms; +using FModel.Settings; using ImGuiNET; using OpenTK.Graphics.OpenGL4; using OpenTK.Windowing.Desktop; @@ -34,7 +37,6 @@ public class ImGuiController : IDisposable private int _windowWidth; private int _windowHeight; - // private string _iniPath; public ImFontPtr FontNormal; public ImFontPtr FontBold; @@ -49,7 +51,6 @@ public class ImGuiController : IDisposable { _windowWidth = width; _windowHeight = height; - // _iniPath = Path.Combine(UserSettings.Default.OutputDirectory, ".data", "imgui.ini"); int major = GL.GetInteger(GetPName.MajorVersion); int minor = GL.GetInteger(GetPName.MinorVersion); @@ -58,9 +59,13 @@ public class ImGuiController : IDisposable IntPtr context = ImGui.CreateContext(); ImGui.SetCurrentContext(context); - // ImGui.LoadIniSettingsFromDisk(_iniPath); var io = ImGui.GetIO(); + unsafe + { + var iniFileNamePtr = Marshal.StringToCoTaskMemUTF8(Path.Combine(UserSettings.Default.OutputDirectory, ".data", "imgui.ini")); + io.NativePtr->IniFilename = (byte*)iniFileNamePtr; + } FontNormal = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeui.ttf", 16 * DpiScale); FontBold = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\segoeuib.ttf", 16 * DpiScale); FontSemiBold = io.Fonts.AddFontFromFileTTF("C:\\Windows\\Fonts\\seguisb.ttf", 16 * DpiScale); @@ -71,7 +76,6 @@ public class ImGuiController : IDisposable io.Fonts.Flags |= ImFontAtlasFlags.NoBakedLines; CreateDeviceResources(); - SetKeyMappings(); SetPerFrameImGuiData(1f / 60f); @@ -271,8 +275,8 @@ outputColor = color * texture(in_fontTexture, texCoord); foreach (Keys key in Enum.GetValues(typeof(Keys))) { - if (key == Keys.Unknown || io.KeyMap[(int) key] == -1) continue; - io.AddKeyEvent((ImGuiKey) io.KeyMap[(int) key], kState.IsKeyDown(key)); + if (key == Keys.Unknown) continue; + io.AddKeyEvent(TranslateKey(key), kState.IsKeyDown(key)); } foreach (var c in PressedChars) @@ -292,115 +296,6 @@ outputColor = color * texture(in_fontTexture, texCoord); PressedChars.Add(keyChar); } - private static void SetKeyMappings() - { - ImGuiIOPtr io = ImGui.GetIO(); - io.KeyMap[(int)ImGuiKey.LeftShift] = (int)Keys.LeftShift; - io.KeyMap[(int)ImGuiKey.RightShift] = (int)Keys.RightShift; - io.KeyMap[(int)ImGuiKey.LeftCtrl] = (int)Keys.LeftControl; - io.KeyMap[(int)ImGuiKey.RightCtrl] = (int)Keys.RightControl; - io.KeyMap[(int)ImGuiKey.LeftAlt] = (int)Keys.LeftAlt; - io.KeyMap[(int)ImGuiKey.RightAlt] = (int)Keys.RightAlt; - io.KeyMap[(int)ImGuiKey.LeftSuper] = (int)Keys.LeftSuper; - io.KeyMap[(int)ImGuiKey.RightSuper] = (int)Keys.RightSuper; - io.KeyMap[(int)ImGuiKey.Menu] = (int)Keys.Menu; - io.KeyMap[(int)ImGuiKey.UpArrow] = (int)Keys.Up; - io.KeyMap[(int)ImGuiKey.DownArrow] = (int)Keys.Down; - io.KeyMap[(int)ImGuiKey.LeftArrow] = (int)Keys.Left; - io.KeyMap[(int)ImGuiKey.RightArrow] = (int)Keys.Right; - io.KeyMap[(int)ImGuiKey.Enter] = (int)Keys.Enter; - io.KeyMap[(int)ImGuiKey.Escape] = (int)Keys.Escape; - io.KeyMap[(int)ImGuiKey.Space] = (int)Keys.Space; - io.KeyMap[(int)ImGuiKey.Tab] = (int)Keys.Tab; - io.KeyMap[(int)ImGuiKey.Backspace] = (int)Keys.Backspace; - io.KeyMap[(int)ImGuiKey.Insert] = (int)Keys.Insert; - io.KeyMap[(int)ImGuiKey.Delete] = (int)Keys.Delete; - io.KeyMap[(int)ImGuiKey.PageUp] = (int)Keys.PageUp; - io.KeyMap[(int)ImGuiKey.PageDown] = (int)Keys.PageDown; - io.KeyMap[(int)ImGuiKey.Home] = (int)Keys.Home; - io.KeyMap[(int)ImGuiKey.End] = (int)Keys.End; - io.KeyMap[(int)ImGuiKey.CapsLock] = (int)Keys.CapsLock; - io.KeyMap[(int)ImGuiKey.ScrollLock] = (int)Keys.ScrollLock; - io.KeyMap[(int)ImGuiKey.PrintScreen] = (int)Keys.PrintScreen; - io.KeyMap[(int)ImGuiKey.Pause] = (int)Keys.Pause; - io.KeyMap[(int)ImGuiKey.NumLock] = (int)Keys.NumLock; - io.KeyMap[(int)ImGuiKey.KeypadDivide] = (int)Keys.KeyPadDivide; - io.KeyMap[(int)ImGuiKey.KeypadMultiply] = (int)Keys.KeyPadMultiply; - io.KeyMap[(int)ImGuiKey.KeypadSubtract] = (int)Keys.KeyPadSubtract; - io.KeyMap[(int)ImGuiKey.KeypadAdd] = (int)Keys.KeyPadAdd; - io.KeyMap[(int)ImGuiKey.KeypadDecimal] = (int)Keys.KeyPadDecimal; - io.KeyMap[(int)ImGuiKey.KeypadEnter] = (int)Keys.KeyPadEnter; - io.KeyMap[(int)ImGuiKey.GraveAccent] = (int)Keys.GraveAccent; - io.KeyMap[(int)ImGuiKey.Minus] = (int)Keys.Minus; - io.KeyMap[(int)ImGuiKey.Equal] = (int)Keys.Equal; - io.KeyMap[(int)ImGuiKey.LeftBracket] = (int)Keys.LeftBracket; - io.KeyMap[(int)ImGuiKey.RightBracket] = (int)Keys.RightBracket; - io.KeyMap[(int)ImGuiKey.Semicolon] = (int)Keys.Semicolon; - io.KeyMap[(int)ImGuiKey.Apostrophe] = (int)Keys.Apostrophe; - io.KeyMap[(int)ImGuiKey.Comma] = (int)Keys.Comma; - io.KeyMap[(int)ImGuiKey.Period] = (int)Keys.Period; - io.KeyMap[(int)ImGuiKey.Slash] = (int)Keys.Slash; - io.KeyMap[(int)ImGuiKey.Backslash] = (int)Keys.Backslash; - io.KeyMap[(int)ImGuiKey.F1] = (int)Keys.F1; - io.KeyMap[(int)ImGuiKey.F2] = (int)Keys.F2; - io.KeyMap[(int)ImGuiKey.F3] = (int)Keys.F3; - io.KeyMap[(int)ImGuiKey.F4] = (int)Keys.F4; - io.KeyMap[(int)ImGuiKey.F5] = (int)Keys.F5; - io.KeyMap[(int)ImGuiKey.F6] = (int)Keys.F6; - io.KeyMap[(int)ImGuiKey.F7] = (int)Keys.F7; - io.KeyMap[(int)ImGuiKey.F8] = (int)Keys.F8; - io.KeyMap[(int)ImGuiKey.F9] = (int)Keys.F9; - io.KeyMap[(int)ImGuiKey.F10] = (int)Keys.F10; - io.KeyMap[(int)ImGuiKey.F11] = (int)Keys.F11; - io.KeyMap[(int)ImGuiKey.F12] = (int)Keys.F12; - io.KeyMap[(int)ImGuiKey.Keypad0] = (int)Keys.KeyPad0; - io.KeyMap[(int)ImGuiKey.Keypad1] = (int)Keys.KeyPad1; - io.KeyMap[(int)ImGuiKey.Keypad2] = (int)Keys.KeyPad2; - io.KeyMap[(int)ImGuiKey.Keypad3] = (int)Keys.KeyPad3; - io.KeyMap[(int)ImGuiKey.Keypad4] = (int)Keys.KeyPad4; - io.KeyMap[(int)ImGuiKey.Keypad5] = (int)Keys.KeyPad5; - io.KeyMap[(int)ImGuiKey.Keypad6] = (int)Keys.KeyPad6; - io.KeyMap[(int)ImGuiKey.Keypad7] = (int)Keys.KeyPad7; - io.KeyMap[(int)ImGuiKey.Keypad8] = (int)Keys.KeyPad8; - io.KeyMap[(int)ImGuiKey.Keypad9] = (int)Keys.KeyPad9; - io.KeyMap[(int)ImGuiKey._0] = (int)Keys.D0; - io.KeyMap[(int)ImGuiKey._1] = (int)Keys.D1; - io.KeyMap[(int)ImGuiKey._2] = (int)Keys.D2; - io.KeyMap[(int)ImGuiKey._3] = (int)Keys.D3; - io.KeyMap[(int)ImGuiKey._4] = (int)Keys.D4; - io.KeyMap[(int)ImGuiKey._5] = (int)Keys.D5; - io.KeyMap[(int)ImGuiKey._6] = (int)Keys.D6; - io.KeyMap[(int)ImGuiKey._7] = (int)Keys.D7; - io.KeyMap[(int)ImGuiKey._8] = (int)Keys.D8; - io.KeyMap[(int)ImGuiKey._9] = (int)Keys.D9; - io.KeyMap[(int)ImGuiKey.A] = (int)Keys.A; - io.KeyMap[(int)ImGuiKey.B] = (int)Keys.B; - io.KeyMap[(int)ImGuiKey.C] = (int)Keys.C; - io.KeyMap[(int)ImGuiKey.D] = (int)Keys.D; - io.KeyMap[(int)ImGuiKey.E] = (int)Keys.E; - io.KeyMap[(int)ImGuiKey.F] = (int)Keys.F; - io.KeyMap[(int)ImGuiKey.G] = (int)Keys.G; - io.KeyMap[(int)ImGuiKey.H] = (int)Keys.H; - io.KeyMap[(int)ImGuiKey.I] = (int)Keys.I; - io.KeyMap[(int)ImGuiKey.J] = (int)Keys.J; - io.KeyMap[(int)ImGuiKey.K] = (int)Keys.K; - io.KeyMap[(int)ImGuiKey.L] = (int)Keys.L; - io.KeyMap[(int)ImGuiKey.M] = (int)Keys.M; - io.KeyMap[(int)ImGuiKey.N] = (int)Keys.N; - io.KeyMap[(int)ImGuiKey.O] = (int)Keys.O; - io.KeyMap[(int)ImGuiKey.P] = (int)Keys.P; - io.KeyMap[(int)ImGuiKey.Q] = (int)Keys.Q; - io.KeyMap[(int)ImGuiKey.R] = (int)Keys.R; - io.KeyMap[(int)ImGuiKey.S] = (int)Keys.S; - io.KeyMap[(int)ImGuiKey.T] = (int)Keys.T; - io.KeyMap[(int)ImGuiKey.U] = (int)Keys.U; - io.KeyMap[(int)ImGuiKey.V] = (int)Keys.V; - io.KeyMap[(int)ImGuiKey.W] = (int)Keys.W; - io.KeyMap[(int)ImGuiKey.X] = (int)Keys.X; - io.KeyMap[(int)ImGuiKey.Y] = (int)Keys.Y; - io.KeyMap[(int)ImGuiKey.Z] = (int)Keys.Z; - } - private void RenderImDrawData(ImDrawDataPtr draw_data) { if (draw_data.CmdListsCount == 0) @@ -643,4 +538,71 @@ outputColor = color * texture(in_fontTexture, texCoord); { return Math.Max((float)(Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth), (float)(Screen.PrimaryScreen.Bounds.Height / SystemParameters.PrimaryScreenHeight)); } + + public static ImGuiKey TranslateKey(Keys key) + { + if (key is >= Keys.D0 and <= Keys.D9) + return key - Keys.D0 + ImGuiKey._0; + + if (key is >= Keys.A and <= Keys.Z) + return key - Keys.A + ImGuiKey.A; + + if (key is >= Keys.KeyPad0 and <= Keys.KeyPad9) + return key - Keys.KeyPad0 + ImGuiKey.Keypad0; + + if (key is >= Keys.F1 and <= Keys.F24) + return key - Keys.F1 + ImGuiKey.F24; + + return key switch + { + Keys.Tab => ImGuiKey.Tab, + Keys.Left => ImGuiKey.LeftArrow, + Keys.Right => ImGuiKey.RightArrow, + Keys.Up => ImGuiKey.UpArrow, + Keys.Down => ImGuiKey.DownArrow, + Keys.PageUp => ImGuiKey.PageUp, + Keys.PageDown => ImGuiKey.PageDown, + Keys.Home => ImGuiKey.Home, + Keys.End => ImGuiKey.End, + Keys.Insert => ImGuiKey.Insert, + Keys.Delete => ImGuiKey.Delete, + Keys.Backspace => ImGuiKey.Backspace, + Keys.Space => ImGuiKey.Space, + Keys.Enter => ImGuiKey.Enter, + Keys.Escape => ImGuiKey.Escape, + Keys.Apostrophe => ImGuiKey.Apostrophe, + Keys.Comma => ImGuiKey.Comma, + Keys.Minus => ImGuiKey.Minus, + Keys.Period => ImGuiKey.Period, + Keys.Slash => ImGuiKey.Slash, + Keys.Semicolon => ImGuiKey.Semicolon, + Keys.Equal => ImGuiKey.Equal, + Keys.LeftBracket => ImGuiKey.LeftBracket, + Keys.Backslash => ImGuiKey.Backslash, + Keys.RightBracket => ImGuiKey.RightBracket, + Keys.GraveAccent => ImGuiKey.GraveAccent, + Keys.CapsLock => ImGuiKey.CapsLock, + Keys.ScrollLock => ImGuiKey.ScrollLock, + Keys.NumLock => ImGuiKey.NumLock, + Keys.PrintScreen => ImGuiKey.PrintScreen, + Keys.Pause => ImGuiKey.Pause, + Keys.KeyPadDecimal => ImGuiKey.KeypadDecimal, + Keys.KeyPadDivide => ImGuiKey.KeypadDivide, + Keys.KeyPadMultiply => ImGuiKey.KeypadMultiply, + Keys.KeyPadSubtract => ImGuiKey.KeypadSubtract, + Keys.KeyPadAdd => ImGuiKey.KeypadAdd, + Keys.KeyPadEnter => ImGuiKey.KeypadEnter, + Keys.KeyPadEqual => ImGuiKey.KeypadEqual, + Keys.LeftShift => ImGuiKey.LeftShift, + Keys.LeftControl => ImGuiKey.LeftCtrl, + Keys.LeftAlt => ImGuiKey.LeftAlt, + Keys.LeftSuper => ImGuiKey.LeftSuper, + Keys.RightShift => ImGuiKey.RightShift, + Keys.RightControl => ImGuiKey.RightCtrl, + Keys.RightAlt => ImGuiKey.RightAlt, + Keys.RightSuper => ImGuiKey.RightSuper, + Keys.Menu => ImGuiKey.Menu, + _ => ImGuiKey.None + }; + } } diff --git a/FModel/MainWindow.xaml.cs b/FModel/MainWindow.xaml.cs index 24d66a1a..a79f953a 100644 --- a/FModel/MainWindow.xaml.cs +++ b/FModel/MainWindow.xaml.cs @@ -61,8 +61,8 @@ public partial class MainWindow break; } - await _applicationView.CUE4Parse.InitOodle(); - await _applicationView.CUE4Parse.InitZlib(); + await _applicationView.InitOodle(); + await _applicationView.InitZlib(); await _applicationView.CUE4Parse.Initialize(); await _applicationView.AesManager.InitAes(); await _applicationView.UpdateProvider(true); @@ -85,10 +85,7 @@ public partial class MainWindow #if DEBUG await _threadWorkerView.Begin(cancellationToken => _applicationView.CUE4Parse.Extract(cancellationToken, - "fortnitegame/Content/Characters/Player/Female/Medium/Bodies/F_Med_Soldier_01/Meshes/F_Med_Soldier_01.uasset")); - await _threadWorkerView.Begin(cancellationToken => - _applicationView.CUE4Parse.Extract(cancellationToken, - "fortnitegame/Content/Animation/Game/MainPlayer/Emotes/Cowbell/Cowbell_CMM_Loop_M.uasset")); + "ShooterGame/Content/Characters/Smonk/S0/3P/Models/TP_Smonk_S0_Skelmesh.uasset")); #endif } diff --git a/FModel/Resources/cube.png b/FModel/Resources/cube.png new file mode 100644 index 00000000..00766874 Binary files /dev/null and b/FModel/Resources/cube.png differ diff --git a/FModel/Resources/cube_off.png b/FModel/Resources/cube_off.png new file mode 100644 index 00000000..eae850fa Binary files /dev/null and b/FModel/Resources/cube_off.png differ diff --git a/FModel/Resources/light.png b/FModel/Resources/light.png new file mode 100644 index 00000000..cdce6934 Binary files /dev/null and b/FModel/Resources/light.png differ diff --git a/FModel/Resources/light_off.png b/FModel/Resources/light_off.png new file mode 100644 index 00000000..5e2d5890 Binary files /dev/null and b/FModel/Resources/light_off.png differ diff --git a/FModel/Resources/square.png b/FModel/Resources/square.png new file mode 100644 index 00000000..1edb68e8 Binary files /dev/null and b/FModel/Resources/square.png differ diff --git a/FModel/Resources/square_off.png b/FModel/Resources/square_off.png new file mode 100644 index 00000000..cd743702 Binary files /dev/null and b/FModel/Resources/square_off.png differ diff --git a/FModel/ViewModels/ApplicationViewModel.cs b/FModel/ViewModels/ApplicationViewModel.cs index fcfa725b..444885f7 100644 --- a/FModel/ViewModels/ApplicationViewModel.cs +++ b/FModel/ViewModels/ApplicationViewModel.cs @@ -4,7 +4,7 @@ using System.IO; using System.IO.Compression; using System.Threading.Tasks; using System.Windows; - +using CUE4Parse.Compression; using FModel.Extensions; using FModel.Framework; using FModel.Services; @@ -190,13 +190,46 @@ public class ApplicationViewModel : ViewModel public async Task InitImGuiSettings(bool forceDownload) { - var imgui = Path.Combine(/*UserSettings.Default.OutputDirectory, ".data", */"imgui.ini"); - if (File.Exists(imgui) && !forceDownload) return; + var imgui = "imgui.ini"; + var imguiPath = Path.Combine(UserSettings.Default.OutputDirectory, ".data", imgui); - await ApplicationService.ApiEndpointView.DownloadFileAsync("https://cdn.fmodel.app/d/configurations/imgui.ini", imgui); - if (new FileInfo(imgui).Length == 0) + if (File.Exists(imgui)) File.Move(imgui, imguiPath, true); + if (File.Exists(imguiPath) && !forceDownload) return; + + await ApplicationService.ApiEndpointView.DownloadFileAsync($"https://cdn.fmodel.app/d/configurations/{imgui}", imguiPath); + if (new FileInfo(imguiPath).Length == 0) { FLogger.Append(ELog.Error, () => FLogger.Text("Could not download ImGui settings", Constants.WHITE, true)); } } + + public async Task InitOodle() + { + var oodlePath = Path.Combine(UserSettings.Default.OutputDirectory, ".data", OodleHelper.OODLE_DLL_NAME); + if (File.Exists(OodleHelper.OODLE_DLL_NAME)) + { + File.Move(OodleHelper.OODLE_DLL_NAME, oodlePath, true); + } + else if (!File.Exists(oodlePath)) + { + await OodleHelper.DownloadOodleDllAsync(oodlePath); + } + + OodleHelper.Initialize(oodlePath); + } + + public async Task InitZlib() + { + var zlibPath = Path.Combine(UserSettings.Default.OutputDirectory, ".data", ZlibHelper.DLL_NAME); + if (File.Exists(ZlibHelper.DLL_NAME)) + { + File.Move(ZlibHelper.DLL_NAME, zlibPath, true); + } + else if (!File.Exists(zlibPath)) + { + await ZlibHelper.DownloadDllAsync(zlibPath); + } + + ZlibHelper.Initialize(zlibPath); + } } diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index a858aa92..409b0d12 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -262,16 +262,18 @@ public class CUE4ParseViewModel : ViewModel break; case DefaultFileProvider: { - var ioStoreOnDemandPath = Path.Combine(UserSettings.Default.GameDirectory, - "..\\..\\..\\Cloud\\IoStoreOnDemand.ini"); - using var tr = File.OpenText(ioStoreOnDemandPath); + var ioStoreOnDemandPath = Path.Combine(UserSettings.Default.GameDirectory, "..\\..\\..\\Cloud\\IoStoreOnDemand.ini"); if (File.Exists(ioStoreOnDemandPath)) - IoStoreOnDemand.Read(tr); + { + using var s = new StreamReader(ioStoreOnDemandPath); + IoStoreOnDemand.Read(s); + } break; } } Provider.Initialize(); + Log.Information($"{Provider.Versions.Game} ({Provider.Versions.Platform}) | Archives: x{Provider.UnloadedVfs.Count} | AES: x{Provider.RequiredKeys.Count}"); foreach (var vfs in Provider.UnloadedVfs) // push files from the provider to the ui { @@ -319,6 +321,10 @@ public class CUE4ParseViewModel : ViewModel } InternalGameName = Provider.InternalGameName; + + var aesMax = Provider.RequiredKeys.Count + Provider.Keys.Count; + var archiveMax = Provider.UnloadedVfs.Count + Provider.MountedVfs.Count; + Log.Information($"Project: {InternalGameName} | Mounted: {Provider.MountedVfs.Count}/{archiveMax} | AES: {Provider.Keys.Count}/{aesMax}"); } public void ClearProvider() @@ -365,44 +371,6 @@ public class CUE4ParseViewModel : ViewModel }); } - public async Task InitOodle() - { - var dataDir = Directory.CreateDirectory(Path.Combine(UserSettings.Default.OutputDirectory, ".data")).FullName; - var oodlePath = Path.Combine(dataDir, OodleHelper.OODLE_DLL_NAME); - bool result; - if (File.Exists(OodleHelper.OODLE_DLL_NAME)) - { - File.Move(OodleHelper.OODLE_DLL_NAME, oodlePath, true); - result = true; - } - else - { - result = await OodleHelper.DownloadOodleDllAsync(oodlePath); - } - - OodleHelper.Initialize(oodlePath); - return result; - } - - public async Task InitZlib() - { - var dataDir = Directory.CreateDirectory(Path.Combine(UserSettings.Default.OutputDirectory, ".data")).FullName; - var zlibPath = Path.Combine(dataDir, ZlibHelper.DLL_NAME); - bool result; - if (File.Exists(ZlibHelper.DLL_NAME)) - { - File.Move(ZlibHelper.DLL_NAME, zlibPath, true); - result = true; - } - else - { - result = await ZlibHelper.DownloadDllAsync(zlibPath); - } - - ZlibHelper.Initialize(zlibPath); - return result; - } - public Task InitMappings(bool force = false) { if (!UserSettings.IsEndpointValid(EEndpointType.Mapping, out var endpoint)) diff --git a/FModel/Views/Snooper/Options.cs b/FModel/Views/Snooper/Options.cs index aab519e0..0493fcbd 100644 --- a/FModel/Views/Snooper/Options.cs +++ b/FModel/Views/Snooper/Options.cs @@ -42,6 +42,12 @@ public class Options Icons = new Dictionary { ["material"] = new ("materialicon"), + ["square"] = new ("square"), + ["square_off"] = new ("square_off"), + ["cube"] = new ("cube"), + ["cube_off"] = new ("cube_off"), + ["light"] = new ("light"), + ["light_off"] = new ("light_off"), ["noimage"] = new ("T_Placeholder_Item_Image"), ["checker"] = new ("checker"), ["pointlight"] = new ("pointlight"), diff --git a/FModel/Views/Snooper/SnimGui.cs b/FModel/Views/Snooper/SnimGui.cs index e774c83f..ff28a65a 100644 --- a/FModel/Views/Snooper/SnimGui.cs +++ b/FModel/Views/Snooper/SnimGui.cs @@ -215,15 +215,9 @@ public class SnimGui ImGui.SeparatorText("Editor"); if (ImGui.BeginTable("world_editor", 2)) { - Layout("Skybox");ImGui.PushID(1); - ImGui.Checkbox("", ref s.Renderer.ShowSkybox); - ImGui.PopID();Layout("Grid");ImGui.PushID(2); - ImGui.Checkbox("", ref s.Renderer.ShowGrid); - ImGui.PopID();Layout("Lights");ImGui.PushID(3); - ImGui.Checkbox("", ref s.Renderer.ShowLights); - ImGui.PopID();Layout("Animate With Rotation Only");ImGui.PushID(4); + Layout("Animate With Rotation Only");ImGui.PushID(1); ImGui.Checkbox("", ref s.Renderer.AnimateWithRotationOnly); - ImGui.PopID();Layout("Vertex Colors");ImGui.PushID(5); + ImGui.PopID();Layout("Vertex Colors");ImGui.PushID(2); var c = (int) s.Renderer.Color; ImGui.Combo("vertex_colors", ref c, "Default\0Sections\0Colors\0Normals\0Texture Coordinates\0"); @@ -783,13 +777,36 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio s.CursorState = CursorState.Normal; } + const float margin = 7.5f; + var buttonWidth = 14.0f * ImGui.GetWindowDpiScale(); + var basePos = new Vector2( size.X - buttonWidth - margin * 2, ImGui.GetFrameHeight() + margin); + ImGui.SetCursorPos(basePos); + ImGui.PushStyleColor(ImGuiCol.Button, Vector4.Zero); + ImGui.PushStyleColor(ImGuiCol.ButtonHovered, new Vector4(0.2f)); + ImGui.ImageButton("skybox_btn", s.Renderer.Options.Icons[s.Renderer.ShowSkybox ? "cube" : "cube_off"].GetPointer(), new Vector2(buttonWidth)); + TooltipCheckbox("Skybox", ref s.Renderer.ShowSkybox); + + basePos.X -= buttonWidth + margin; + ImGui.SetCursorPos(basePos); + ImGui.ImageButton("grid_btn", s.Renderer.Options.Icons[s.Renderer.ShowGrid ? "square" : "square_off"].GetPointer(), new Vector2(buttonWidth)); + TooltipCheckbox("Grid", ref s.Renderer.ShowGrid); + + basePos.X -= buttonWidth + margin; + ImGui.SetCursorPos(basePos); + ImGui.ImageButton("lights_btn", s.Renderer.Options.Icons[s.Renderer.ShowLights ? "light" : "light_off"].GetPointer(), new Vector2(buttonWidth)); + TooltipCheckbox("Lights", ref s.Renderer.ShowLights); + + ImGui.PopStyleColor(); + + float framerate = ImGui.GetIO().Framerate; - ImGui.SetCursorPos(size with { X = 7.5f }); + ImGui.SetCursorPos(size with { X = margin }); ImGui.Text($"FPS: {framerate:0} ({1000.0f / framerate:0.##} ms)"); const string label = "Previewed content may differ from final version saved or used in-game."; - ImGui.SetCursorPos(size with { X = size.X - ImGui.CalcTextSize(label).X - 7.5f }); + ImGui.SetCursorPos(size with { X = size.X - ImGui.CalcTextSize(label).X - margin }); ImGui.TextColored(new Vector4(0.50f, 0.50f, 0.50f, 1.00f), label); + }, false); ImGui.PopStyleVar(); } @@ -906,6 +923,17 @@ Snooper aims to give an accurate preview of models, materials, skeletal animatio if (ImGui.IsItemClicked()) ImGui.SetClipboardText(text ?? label); } + private static void TooltipCheckbox(string tooltip, ref bool value) + { + if (ImGui.IsItemHovered()) + { + ImGui.BeginTooltip(); + ImGui.Text($"{tooltip}: {value}"); + ImGui.EndTooltip(); + } + if (ImGui.IsItemClicked()) value = !value; + } + private void Theme() { var style = ImGui.GetStyle();