示例#1
0
        private void BuildSceneItems()
        {
            lock (LoadingTaskMan._lock_TaskDictEdit)
            {
                MapMenuEntriesToTaskKeys.Clear();
                Items.Clear();

                foreach (var it in baseMenuItems)
                {
                    Items.Add(it);
                }

                foreach (var kvp in LoadingTaskMan.TaskDict)
                {
                    var menuItem = new DbgMenuItem()
                    {
                        ClickAction         = (m) => LoadingTaskMan.KillTask(kvp.Key),
                        RefreshTextFunction = () => $"{kvp.Key} [{kvp.Value.ProgressRatio:0.00}] [\"{kvp.Value.DisplayString}\"]",
                        CustomColorFunction = () => kvp.Value.IsBeingKilledManually ? Color.Red : Color.Cyan
                    };

                    Items.Add(menuItem);
                    MapMenuEntriesToTaskKeys.Add(menuItem, kvp.Key);
                }

                RequestTextRefresh();
            }
        }
        private void UpdateText()
        {
            string actionText = IsRegionSpawner ? "Click to Spawn MAP - Event Regions" : "Click to Spawn MAP - Models";

            if (!IsRegionSpawner)
            {
                CustomColorFunction = () => (
                    LoadingTaskMan.IsTaskRunning($"{nameof(InterrootLoader.LoadMapInBackground)}_Textures[{IDList[IDIndex]}]") ||
                    LoadingTaskMan.IsTaskRunning($"{nameof(InterrootLoader.LoadMapInBackground)}_Models[{IDList[IDIndex]}]"))
                    ? Color.Cyan * 0.5f : Color.Cyan;
            }

            if (IDList.Count == 0)
            {
                IDIndex = 0;
                Text    = $"{actionText} [Invalid Data Root Selected]";
            }
            else
            {
                if (IDIndex >= IDList.Count)
                {
                    IDIndex = IDList.Count - 1;
                }

                Text = $"{actionText} [ID: <{IDList[IDIndex]}>]";
            }
        }
示例#3
0
        public static void Init()
        {
            CurrentMenu.Text  = "Main Menu";
            CurrentMenu.Items = new List <DbgMenuItem>()
            {
                //new DbgMenuItem()
                //{
                //    Text = "<-- TESTING -->",
                //    Items = new List<DbgMenuItem>
                //    {
                //        new DbgMenuItem()
                //        {
                //            Text = "Write TextureFetchRequest.DEBUG_AllKnownDS1Formats to Console",
                //            ClickAction = () =>
                //            {
                //                foreach (var f in TextureFetchRequest.DEBUG_AllKnownDS1Formats)
                //                {
                //                    Console.WriteLine(f.ToString());
                //                }
                //            }
                //        }
                //    }
                //},
                new DbgMenuItemSceneList(isModelGroupingKind: false)
                {
                    Text = "Scene Parts"
                },
                new DbgMenuItemSceneList(isModelGroupingKind: true)
                {
                    Text = "Scene Models"
                },
                new DbgMenuItem()
                {
                    Text        = "Click to remove all debug primitives",
                    ClickAction = (m) => DBG.ClearPrimitives()
                },
                new DbgMenuItem()
                {
                    Text  = "Game Data",
                    Items = new List <DbgMenuItem>
                    {
                        new DbgMenuItemTextLabel(() => $"Data Root: \"{InterrootLoader.Interroot}\"\n     [Click to Browse...]")
                        {
                            ClickAction = (m) =>
                            {
                                InterrootLoader.Browse();
                                CurrentMenu.RequestTextRefresh();
                            }
                        },
                        new DbgMenuItemEnum <InterrootLoader.InterrootType>("Game Type",
                                                                            v =>
                        {
                            InterrootLoader.Type = v;
                            CFG.Save();
                        },
                                                                            () => InterrootLoader.Type,
                                                                            nameOverrides: new Dictionary <InterrootLoader.InterrootType, string>
                        {
                            { InterrootLoader.InterrootType.InterrootBloodborne, "Bloodborne" },
                            { InterrootLoader.InterrootType.InterrootDS1, "Dark Souls" },
                            { InterrootLoader.InterrootType.InterrootDS1R, "Dark Souls Remastered" },
                            // { InterrootLoader.InterrootType.InterrootDS2, "Dark Souls II" },
                            { InterrootLoader.InterrootType.InterrootDS3, "Dark Souls III" },
                        }
                                                                            ),
                        new DbgMenuItem()
                        {
                            Text        = "Refresh Spawn Lists",
                            ClickAction = m =>
                            {
                                DbgMenuItemSpawnChr.UpdateSpawnIDs();
                                DbgMenuItemSpawnObj.UpdateSpawnIDs();
                                DbgMenuItemSpawnMap.UpdateSpawnIDs();
                            }
                        },
                        new DbgMenuItemTaskKiller()
                        {
                            Text = "[LOAD TASK KILLER]"
                        },
                        new DbgMenuItem()
                        {
                            Text        = "Scan All Separate Texture Files (DS1 Only)",
                            ClickAction = (m) =>
                            {
                                TexturePool.AddAllExternalDS1TexturesInBackground();
                            }
                        },
                        new DbgMenuItem()
                        {
                            Text        = "Purge Texture Cache",
                            ClickAction = (m) =>
                            {
                                TexturePool.Flush();
                            }
                        },
                        new DbgMenuItem()
                        {
                            Text        = "[CLICK TO CLEAR SCENE MODELS]",
                            ClickAction = (m) => GFX.ModelDrawer.ClearScene()
                        },
                        new DbgMenuItem()
                        {
                            Text        = "[CLICK TO CLEAR SCENE REGIONS]",
                            ClickAction = (m) => DBG.ClearPrimitives()
                        },
                        new DbgMenuItemSpawnChr()
                        {
                            CustomColorFunction = () => Color.Cyan
                        },
                        new DbgMenuItemSpawnObj()
                        {
                            CustomColorFunction = () => Color.Cyan
                        },
                        new DbgMenuItemSpawnMap(isRegionSpawner: false),
                        new DbgMenuItemSpawnMap(isRegionSpawner: true)
                        {
                            CustomColorFunction = () => Color.Cyan
                        },
                        new DbgMenuItem()
                        {
                            Text                = "Load All Characters Lineup",
                            ClickAction         = (m) => GFX.ModelDrawer.TestAddAllChr(),
                            CustomColorFunction = () => LoadingTaskMan.IsTaskRunning($"{nameof(GFX.ModelDrawer.TestAddAllChr)}") ? Color.Cyan * 0.5f : Color.Cyan
                        },
                        new DbgMenuItem()
                        {
                            Text                = "Load All Objects Lineup",
                            ClickAction         = (m) => GFX.ModelDrawer.TestAddAllObj(),
                            CustomColorFunction = () => LoadingTaskMan.IsTaskRunning($"{nameof(GFX.ModelDrawer.TestAddAllObj)}") ? Color.Cyan * 0.5f : Color.Cyan
                        },
                    }
                },
                //new DbgMenuItem()
                //{
                //    Text = "[DIAGNOSTICS]",
                //    Items = new List<DbgMenuItem>
                //    {
                //        new DbgMenuItem()
                //        {
                //            Text = $"Log {nameof(InterrootLoader)}.{nameof(InterrootLoader.DDS_INFO)}",
                //            ClickAction = () =>
                //            {
                //                foreach (var x in InterrootLoader.DDS_INFO)
                //                {
                //                    Console.WriteLine($"{x.Name} - {x.DDSFormat}");
                //                }
                //            }
                //        }
                //    }
                //},
                new DbgMenuItem()
                {
                    Text  = "General Options",
                    Items = new List <DbgMenuItem>
                    {
                        new DbgMenuItemGfxFlverShaderAdjust(),
                        //new DbgMenuItemGfxBlendStateAdjust(),
                        //new DbgMenuItemGfxDepthStencilStateAdjust(),
                        new DbgMenuItemEnum <LODMode>("LOD Mode", v => GFX.LODMode = v, () => GFX.LODMode,
                                                      nameOverrides: new Dictionary <LODMode, string>
                        {
                            { LODMode.ForceFullRes, "Force Full Resolution" },
                            { LODMode.ForceLOD1, "Force LOD Level 1" },
                            { LODMode.ForceLOD2, "Force LOD Level 2" },
                        }),
                        new DbgMenuItemNumber("LOD1 Distance", 0, 10000, 1,
                                              (f) => GFX.LOD1Distance = f, () => GFX.LOD1Distance),
                        new DbgMenuItemNumber("LOD2 Distance", 0, 10000, 1,
                                              (f) => GFX.LOD2Distance = f, () => GFX.LOD2Distance),
                        new DbgMenuItemBool("Show Map Region Names", "YES", "NO",
                                            (b) => DBG.ShowPrimitiveNametags = b, () => DBG.ShowPrimitiveNametags),
                        new DbgMenuItemBool("Show Model Names", "YES", "NO",
                                            (b) => DBG.ShowModelNames = b, () => DBG.ShowModelNames),
                        new DbgMenuItemBool("Show Model Bounding Boxes", "YES", "NO",
                                            (b) => DBG.ShowModelBoundingBoxes = b, () => DBG.ShowModelBoundingBoxes),
                        new DbgMenuItemBool("Show Model Submesh Bounding Boxes", "YES", "NO",
                                            (b) => DBG.ShowModelSubmeshBoundingBoxes = b, () => DBG.ShowModelSubmeshBoundingBoxes),
                        new DbgMenuItemBool("Show Grid", "YES", "NO",
                                            (b) => DBG.ShowGrid = b, () => DBG.ShowGrid),
                        new DbgMenuItemBool("Textures", "ON", "OFF",
                                            (b) => GFX.EnableTextures = b, () => GFX.EnableTextures),
                        new DbgMenuItemBool("Wireframe Mode", "ON", "OFF",
                                            (b) => GFX.Wireframe = b, () => GFX.Wireframe),
                        new DbgMenuItemBool("View Frustum Culling (Experimental)", "ON", "OFF",
                                            (b) => GFX.EnableFrustumCulling = b, () => GFX.EnableFrustumCulling),
                        new DbgMenuItemNumber("Vertical Field of View (Degrees)", 20, 150, 1,
                                              (f) => GFX.World.FieldOfView = f, () => GFX.World.FieldOfView,
                                              (f) => $"{((int)(Math.Round(f)))}"),
                        new DbgMenuItemNumber("Camera Turn Speed (Gamepad)", 0.01f, 10f, 0.01f,
                                              (f) => GFX.World.CameraTurnSpeedGamepad = f, () => GFX.World.CameraTurnSpeedGamepad),
                        new DbgMenuItemNumber("Camera Turn Speed (Mouse)", 0.001f, 10f, 0.001f,
                                              (f) => GFX.World.CameraTurnSpeedMouse = f, () => GFX.World.CameraTurnSpeedMouse),
                        new DbgMenuItemNumber("Camera Move Speed", 0.1f, 100f, 0.1f,
                                              (f) => GFX.World.CameraMoveSpeed = f, () => GFX.World.CameraMoveSpeed),
                        new DbgMenuItemNumber("Near Clip Distance", 0.0001f, 5, 0.0001f,
                                              (f) => GFX.World.NearClipDistance = f, () => GFX.World.NearClipDistance),
                        new DbgMenuItemNumber("Far Clip Distance", 100, 1000000, 100,
                                              (f) => GFX.World.FarClipDistance = f, () => GFX.World.FarClipDistance),
                    }
                },
                new DbgMenuItem()
                {
                    Text  = "Graphics Options",
                    Items = new List <DbgMenuItem>
                    {
                        new DbgMenuItemResolutionChange(),
                        new DbgMenuItemBool("Fullscreen", "YES", "NO", v => GFX.Display.Fullscreen  = v, () => GFX.Display.Fullscreen),
                        new DbgMenuItemBool("Vsync", "ON", "OFF", v => GFX.Display.Vsync            = v, () => GFX.Display.Vsync),
                        new DbgMenuItemBool("Simple MSAA", "ON", "OFF", v => GFX.Display.SimpleMSAA = v, () => GFX.Display.SimpleMSAA),
                        new DbgMenuItem()
                        {
                            Text        = "Apply Changes",
                            ClickAction = (m) => GFX.Display.Apply(),
                        }
                    }
                },
                new DbgMenuItem()
                {
                    Text        = "Return Camera to Origin",
                    ClickAction = m => GFX.World.ResetCameraLocation()
                },
                new DbgMenuItem()
                {
                    Text  = "Help",
                    Items = new List <DbgMenuItem>
                    {
                        new DbgMenuItem()
                        {
                            Text  = "Menu Overlay Controls (Gamepad)",
                            Items = new List <DbgMenuItem>
                            {
                                new DbgMenuItem()
                                {
                                    Text = "Back: Toggle Menu (Active/Visible/Hidden)"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "D-Pad Up/Down: Move Cursor Up/Down"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "A: Enter/Activate (when applicable)"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "B: Go Back (when applicable)"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "D-Pad Left/Right: Decrease/Increase"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Start: Reset Value to Default"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold LB: Increase/Decrease 10x Faster"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold X: Increase/Decrease 100x Faster"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold RB + Move LS: Move Menu"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold RB + Move RS: Resize Menu"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold LB + Move or Resize Menu: Move or Resize Menu Faster"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Click RS: Toggle 3D Render Pause"
                                },
                            }
                        },
                        new DbgMenuItem()
                        {
                            Text  = "General 3D Controls (Gamepad)",
                            Items = new List <DbgMenuItem>
                            {
                                new DbgMenuItem()
                                {
                                    Text = "LS: Move Camera Laterally"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "LT: Move Camera Directly Downward"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "RT: Move Camera Directly Upward"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "RS: Turn Camera"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold LB: Move Camera More Slowly"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold RB: Move Camera More Quickly"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Click LS and Hold: Turn Light With RS Instead of Camera"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Click RS: Reset Camera To Origin"
                                },
                            }
                        },
                        new DbgMenuItem()
                        {
                            Text  = "Menu Overlay Controls (Mouse & Keyboard)",
                            Items = new List <DbgMenuItem>
                            {
                                new DbgMenuItem()
                                {
                                    Text = "Tilde (~): Toggle Menu (Active/Visible/Hidden)"
                                },

                                new DbgMenuItem()
                                {
                                    Text = "Move Mouse Cursor: Move Cursor"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold Spacebar + Scroll Mouse Wheel: Change Values"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Mouse Wheel: Scroll Menu"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Enter/Left Click: Enter/Activate (when applicable)"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Backspace/Right Click: Go Back (when applicable)"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Up/Down: Move Cursor Up/Down"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Left/Right: Decrease/Increase"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Home/Middle Click: Reset Value to Default"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold Shift: Increase/Decrease 10x Faster"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold Ctrl: Increase/Decrease 100x Faster"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Pause Key: Toggle 3D Render Pause"
                                },
                            }
                        },
                        new DbgMenuItem()
                        {
                            Text  = "General 3D Controls (Mouse & Keyboard)",
                            Items = new List <DbgMenuItem>
                            {
                                new DbgMenuItem()
                                {
                                    Text = "WASD: Move Camera Laterally"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Q: Move Camera Directly Downward"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "E: Move Camera Directly Upward"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Right Click + Move Mouse: Turn Camera"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold Shift: Move Camera More Slowly"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold Ctrl: Move Camera More Quickly"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "Hold Spacebar: Turn Light With Mouse Instead of Camera"
                                },
                                new DbgMenuItem()
                                {
                                    Text = "R: Reset Camera To Origin"
                                },
                            }
                        },
                    }
                },
                new DbgMenuItem()
                {
                    Text  = "Exit",
                    Items = new List <DbgMenuItem>
                    {
                        new DbgMenuItem()
                        {
                            Text = "Are you sure you want to exit?"
                        },
                        new DbgMenuItem()
                        {
                            Text        = "No",
                            ClickAction = (m) => REQUEST_GO_BACK = true
                        },
                        new DbgMenuItem()
                        {
                            Text        = "Yes",
                            ClickAction = (m) => Main.REQUEST_EXIT = true
                        }
                    }
                },
            };
        }
示例#4
0
        public void LoadFromPath(string file)
        {
            filePath = file;

            containerANIBND = null;

            taeInBND.Clear();
            hkxInBND.Clear();



            if (BND3.Is(file))
            {
                ContainerType   = TaeFileContainerType.ANIBND;
                containerANIBND = BND3.Read(file);
            }
            else if (BND4.Is(file))
            {
                ContainerType   = TaeFileContainerType.ANIBND;
                containerANIBND = BND4.Read(file);
            }
            else if (TAE.Is(file))
            {
                CheckGameVersionForTaeInterop(file);

                ContainerType = TaeFileContainerType.TAE;
                taeInBND.Add(file, TAE.Read(file));
            }

            void DoBnd(IBinder bnd)
            {
            }

            if (ContainerType == TaeFileContainerType.ANIBND)
            {
                LoadingTaskMan.DoLoadingTaskSynchronous("TaeFileContainer_ANIBND", "Loading all TAE files in ANIBND...", innerProgress =>
                {
                    double i = 0;
                    foreach (var f in containerANIBND.Files)
                    {
                        innerProgress.Report(++i / containerANIBND.Files.Count);

                        CheckGameVersionForTaeInterop(f.Name);
                        if (BND3.Is(f.Bytes))
                        {
                            ContainerType          = TaeFileContainerType.OBJBND;
                            containerOBJBND        = containerANIBND;
                            containerANIBND        = BND3.Read(f.Bytes);
                            anibndPathInsideObjbnd = f.Name;
                            break;
                        }
                        else if (BND4.Is(f.Bytes))
                        {
                            ContainerType          = TaeFileContainerType.OBJBND;
                            containerOBJBND        = containerANIBND;
                            containerANIBND        = BND4.Read(f.Bytes);
                            anibndPathInsideObjbnd = f.Name;
                            break;
                        }
                        else if (TAE.Is(f.Bytes))
                        {
                            taeInBND.Add(f.Name, TAE.Read(f.Bytes));
                        }
                        else if (f.Name.ToUpper().EndsWith(".HKX"))
                        {
                            hkxInBND.Add(f.Name, f.Bytes);
                        }
                    }
                    innerProgress.Report(1);

                    if (ContainerType == TaeFileContainerType.OBJBND)
                    {
                        i = 0;
                        foreach (var f in containerANIBND.Files)
                        {
                            innerProgress.Report(++i / containerANIBND.Files.Count);

                            CheckGameVersionForTaeInterop(f.Name);
                            if (TAE.Is(f.Bytes))
                            {
                                taeInBND.Add(f.Name, TAE.Read(f.Bytes));
                            }
                            else if (f.Name.ToUpper().EndsWith(".HKX"))
                            {
                                hkxInBND.Add(f.Name, f.Bytes);
                            }
                        }
                        innerProgress.Report(1);
                    }
                });
            }
        }
示例#5
0
        public static void BuildMenuBar()
        {
            bool isAnyMenuExpanded = false;

            if (ImGui.BeginMenu("File"))
            {
                isAnyMenuExpanded = true;

                bool clickedOpen = ClickItem("Open...");
                ImGui.Separator();
                bool isRecentFilesExpanded = ImGui.BeginMenu("Recent Files");
                if (isRecentFilesExpanded)
                {
                    if (ClickItem("Clear all recent files..."))
                    {
                        DialogManager.AskForMultiChoice("Clear Recent Files",
                                                        "Clear all recent files?", (cancelType, answer) =>
                        {
                            if (answer == "YES")
                            {
                                lock (Main.Config._lock_ThreadSensitiveStuff)
                                {
                                    Main.Config.RecentFilesList.Clear();
                                }
                                Main.SaveConfig();
                            }
                        }, Dialog.CancelTypes.Combo_ClickTitleBarX_PressEscape, "YES", "NO");
                    }

                    ImGui.Separator();

                    try
                    {
                        string fileOpened = null;
                        lock (Main.Config._lock_ThreadSensitiveStuff)
                        {
                            foreach (var f in Main.Config.RecentFilesList)
                            {
                                if (fileOpened == null && ClickItem(f))
                                {
                                    fileOpened = f;
                                }
                            }
                        }

                        if (fileOpened != null)
                        {
                            Tae.DirectOpenFile(fileOpened);
                        }
                    }
                    catch
                    {
                    }

                    ImGui.EndMenu();
                }

                ImGui.Separator();
                bool clickedReloadGameParam = ClickItem("Reload GameParam and FMGs", enabled: Tae.IsFileOpen);
                ImGui.Separator();
                bool clickedSave      = ClickItem("Save", enabled: Tae.IsFileOpen && Tae.IsModified, shortcut: "Ctrl+S");
                bool clickedSaveAs    = ClickItem("Save As...", enabled: Tae.IsFileOpen, shortcut: "Ctrl+Shift+S");
                bool clickedExportTAE = ClickItem("Export *.TAE Containing The Currently Selected Animation...", enabled: Tae.SelectedTae != null);
                ImGui.Separator();
                var prevValueSaveAdditionalEventRowInfoToLegacyGames = Main.Config.SaveAdditionalEventRowInfoToLegacyGames;
                var nextValueSaveAdditionalEventRowInfoToLegacyGames = Checkbox("Save Row Data To Legacy Games",
                                                                                prevValueSaveAdditionalEventRowInfoToLegacyGames, enabled: true,
                                                                                shortcut: "DeS/DS1 Only");
                if (nextValueSaveAdditionalEventRowInfoToLegacyGames != prevValueSaveAdditionalEventRowInfoToLegacyGames)
                {
                    if (nextValueSaveAdditionalEventRowInfoToLegacyGames)
                    {
                        DialogManager.AskYesNo("Warning", "This option has not been tested in the long run and may cause the game to behave " +
                                               "\nstrangely, or it may not. Are you sure you wish to use this option? " +
                                               "\nNote: effect is reversable if you run into issues.", choice =>
                        {
                            if (choice)
                            {
                                Main.Config.SaveAdditionalEventRowInfoToLegacyGames = true;

                                if (GameDataManager.GameTypeUsesLegacyEmptyEventGroups)
                                {
                                    Tae.StripExtraEventGroupsInAllLoadedFilesIfNeeded();
                                }
                            }
                        }, allowCancel: true, enterKeyForYes: false);
                    }
                    else
                    {
                        DialogManager.AskYesNo("Warning", "Disabling this option will IMMEDIATELY REMOVE ALL of the extra row data from all " +
                                               "\nanimations in anibnd files which utilized this option previously and make them all use the standard " +
                                               "\nautomatic row sorting, which will PERMANENTLY save into the file when resaved. " +
                                               "\nAre you sure you wish to do this?", choice =>
                        {
                            if (choice)
                            {
                                Main.Config.SaveAdditionalEventRowInfoToLegacyGames = false;
                                Tae.StripExtraEventGroupsInAllLoadedFilesIfNeeded();
                            }
                        }, allowCancel: true, enterKeyForYes: false);
                    }
                }
                ImGui.Separator();
                bool clickedLiveRefreshNow = ClickItem("(DS3/DS1R Only) Force Ingame Character Reload Now",
                                                       enabled: Tae.IsFileOpen &&
                                                       GameDataManager.GameType ==
                                                       SoulsAssetPipeline.SoulsGames.DS1R ||
                                                       GameDataManager.GameType ==
                                                       SoulsAssetPipeline.SoulsGames.DS3, shortcut: "F5");
                bool liveRefreshOnSaveValue = Checkbox(
                    "(DS3/DS1R Only) Force Ingame Character Reload Upon Saving",
                    Tae.Config.LiveRefreshOnSave);
                ImGui.Separator();
                bool clickedSaveConfigManually = ClickItem("Save Config File");
                Main.DisableConfigFileAutoSave = !Checkbox("Enable Config File Autosaving", !Main.DisableConfigFileAutoSave);
                bool clickedLoadConfigManually = ClickItem("Reload Config File");

                ImGui.Separator();
                bool clickedExit = ClickItem("Exit");

                // Only do the interaction layer with the main window if the recent files list isn't covering it...
                if (!isRecentFilesExpanded)
                {
                    if (clickedOpen)
                    {
                        Tae.File_Open();
                    }

                    if (clickedReloadGameParam)
                    {
                        LoadingTaskMan.DoLoadingTask("FileReloadGameParam",
                                                     "Reloading GameParam and FMGs...", prog =>
                        {
                            GameDataManager.ReloadParams();
                            GameDataManager.ReloadFmgs();
                            Tae.Graph?.ViewportInteractor?.CurrentModel?.RescanNpcParams();
                            Tae.Graph?.ViewportInteractor?.OnScrubFrameChange();
                        }, disableProgressBarByDefault: true);
                    }

                    if (clickedSave)
                    {
                        Tae.SaveCurrentFile();
                    }

                    if (clickedSaveAs)
                    {
                        Tae.File_SaveAs();
                    }

                    if (clickedExportTAE)
                    {
                        Tae.Tools_ExportCurrentTAE();
                    }

                    if (clickedLiveRefreshNow)
                    {
                        Tae.LiveRefresh();
                    }

                    Tae.Config.LiveRefreshOnSave = liveRefreshOnSaveValue;

                    if (clickedSaveConfigManually)
                    {
                        Main.SaveConfig(isManual: true);
                    }

                    if (clickedLoadConfigManually)
                    {
                        Main.LoadConfig(isManual: true);
                    }

                    if (clickedExit)
                    {
                        Main.WinForm.Close();
                    }
                }

                ImGui.EndMenu();
            }

            if (ImGui.BeginMenu("Edit"))
            {
                isAnyMenuExpanded = true;

                if (ClickItem("Undo", Tae.UndoMan?.CanUndo ?? false, "Ctrl+Z"))
                {
                    Tae.UndoMan?.Undo();
                }
                if (ClickItem("Redo", Tae.UndoMan?.CanRedo ?? false, "Ctrl+Y"))
                {
                    Tae.UndoMan?.Redo();
                }

                ImGui.Separator();

                if (ClickItem("Collapse All TAE Sections", Tae.IsFileOpen))
                {
                    Tae.SetAllTAESectionsCollapsed(true);
                }
                if (ClickItem("Expand All TAE Sections", Tae.IsFileOpen))
                {
                    Tae.SetAllTAESectionsCollapsed(false);
                }

                ImGui.Separator();

                if (ClickItem("Find Value...", Tae.IsFileOpen, "Ctrl+F"))
                {
                    Tae.ShowDialogFind();
                }

                if (ClickItem("Go To Animation ID...", Tae.IsFileOpen, "Ctrl+G"))
                {
                    Tae.ShowDialogGotoAnimID();
                }

                if (ClickItem("Go To Animation Section ID...", Tae.IsFileOpen, "Ctrl+H"))
                {
                    Tae.ShowDialogGotoAnimSectionID();
                }

                if (ClickItem("Import From Animation ID...", Tae.IsFileOpen, "Ctrl+I"))
                {
                    Tae.ShowDialogImportFromAnimID();
                }

                ImGui.Separator();

                if (ClickItem("Change Type of Selected Event", Tae.IsFileOpen && Tae.SingleEventBoxSelected, "F1"))
                {
                    Tae.ChangeTypeOfSelectedEvent();
                }

                if (ClickItem("Edit Current Animation Name...", Tae.IsFileOpen, "F2"))
                {
                    Tae.ShowDialogChangeAnimName();
                }

                if (ClickItem("Edit Current Animation Properties...", Tae.IsFileOpen, "F3"))
                {
                    Tae.ShowDialogEditCurrentAnimInfo();
                }

                if (ClickItem("Go to Referenced Event Source Animation", Tae.IsFileOpen, "F4"))
                {
                    Tae.GoToEventSource();
                }

                if (ClickItem("Duplicate Animation", Tae.IsFileOpen, "Insert"))
                {
                    Tae.DuplicateCurrentAnimation();
                }

                ImGui.EndMenu();
            }

            if (ImGui.BeginMenu("Event Graph"))
            {
                isAnyMenuExpanded = true;

                Tae.Config.EventSnapType = EnumSelectorItem <TaeEditor.TaeConfigFile.EventSnapTypes>("Snap Events To Framerate",
                                                                                                     Tae.Config.EventSnapType, new Dictionary <TaeEditor.TaeConfigFile.EventSnapTypes, string>
                {
                    { TaeEditor.TaeConfigFile.EventSnapTypes.None, "None" },
                    { TaeEditor.TaeConfigFile.EventSnapTypes.FPS30, "30 FPS (used by FromSoft)" },
                    { TaeEditor.TaeConfigFile.EventSnapTypes.FPS60, "60 FPS" },
                }, enabled: Tae.IsFileOpen);

                ImGui.Separator();

                Tae.Config.IsNewGraphVisiMode               = Checkbox("Use New Graph Design", Tae.Config.IsNewGraphVisiMode);
                Tae.Config.EnableFancyScrollingStrings      = Checkbox("Use Fancy Text Scrolling", Tae.Config.EnableFancyScrollingStrings);
                Tae.Config.FancyScrollingStringsScrollSpeed = FloatSlider("Fancy Text Scroll Speed", Tae.Config.FancyScrollingStringsScrollSpeed, 1, 256, "%f pixels/sec");
                ImGui.Separator();
                Tae.Config.AutoCollapseAllTaeSections = Checkbox("Start with all TAE sections collapsed", Tae.Config.AutoCollapseAllTaeSections);
                ImGui.Separator();
                Tae.Config.AutoScrollDuringAnimPlayback = Checkbox("Auto-scroll During Anim Playback", Tae.Config.AutoScrollDuringAnimPlayback);
                ImGui.Separator();
                Tae.Config.SoloHighlightEventOnHover = Checkbox("Solo Highlight Event on Hover", Tae.Config.SoloHighlightEventOnHover);
                Tae.Config.ShowEventHoverInfo        = Checkbox("Show Event Info Popup When Hovering Over Event", Tae.Config.ShowEventHoverInfo);

                ImGui.EndMenu();
            }

            if (ImGui.BeginMenu("Simulation"))
            {
                foreach (var thing in TaeEditor.TaeEventSimulationEnvironment.AllEntryDisplayNames)
                {
                    Tae.Config.EventSimulationsEnabled[thing.Key] = Checkbox(thing.Value, Tae.Config.EventSimulationsEnabled[thing.Key]);
                }
                ImGui.EndMenu();
            }

            if (ImGui.BeginMenu("Animation"))
            {
                isAnyMenuExpanded = true;

                Tae.Config.LockFramerateToOriginalAnimFramerate = Checkbox(
                    "Lock to Frame Rate Defined in HKX", Tae.Config.LockFramerateToOriginalAnimFramerate,
                    shortcut: Tae.PlaybackCursor != null
                    ? $"({((int)Math.Round(Tae.PlaybackCursor.CurrentSnapFPS))} FPS)" : null);

                TaeEditor.TaePlaybackCursor.GlobalBasePlaybackSpeed = FloatSlider("Playback Speed",
                                                                                  TaeEditor.TaePlaybackCursor.GlobalBasePlaybackSpeed * 100f, 0, 100, "%.2f %%") / 100f;



                ImGui.Separator();

                Tae.Config.EnableAnimRootMotion = Checkbox(
                    "Enable Root Motion", Tae.Config.EnableAnimRootMotion);

                Tae.Config.CameraFollowsRootMotion = Checkbox(
                    "Camera Follows Root Motion Translation", Tae.Config.CameraFollowsRootMotion);

                Tae.Config.CameraFollowsRootMotionRotation = Checkbox(
                    "Camera Follows Root Motion Rotation", Tae.Config.CameraFollowsRootMotionRotation);

                Tae.Config.WrapRootMotion = Checkbox(
                    "Prevent Root Motion From Reaching End Of Grid", Tae.Config.WrapRootMotion);

                ImGui.EndMenu();
            }

            if (ImGui.BeginMenu("FMOD Sound"))
            {
                isAnyMenuExpanded = true;

                if (ClickItem("Retry Initialization", !FmodManager.IsInitialized))
                {
                    FmodManager.InitTest();
                    Tae.Graph?.ViewportInteractor?.LoadSoundsForCurrentModel();
                }

                if (ClickItem("STOP ALL SOUNDS", FmodManager.IsInitialized, "Escape"))
                {
                    FmodManager.StopAllSounds();
                }

                if (ImGui.BeginMenu("Load Additional Sounds", enabled: FmodManager.IsInitialized &&
                                    FmodManager.MediaPath != null))
                {
                    string[] fevFiles = Directory.GetFiles(FmodManager.MediaPath, "*.fev");

                    for (int i = 0; i < fevFiles.Length; i++)
                    {
                        var shortName = Path.GetFileNameWithoutExtension(fevFiles[i]);
                        if (ClickItem(shortName, shortcut: FmodManager.LoadedFEVs.Contains(shortName) ? "(Loaded)" : null))
                        {
                            int underscoreIndex = shortName.IndexOf('_');
                            if (underscoreIndex >= 0)
                            {
                                shortName = shortName.Substring(Math.Min(underscoreIndex + 1, shortName.Length - 1));
                            }
                            FmodManager.LoadInterrootFEV(shortName);
                        }
                    }



                    ImGui.EndMenu();
                }

                ImGui.Separator();

                FmodManager.ArmorMaterial = EnumSelectorItem("Player Armor Material",
                                                             FmodManager.ArmorMaterial, new Dictionary <FmodManager.ArmorMaterialType, string>
                {
                    { FmodManager.ArmorMaterialType.Plates, "Platemail" },
                    { FmodManager.ArmorMaterialType.Chains, "Chainmail" },
                    { FmodManager.ArmorMaterialType.Cloth, "Cloth" },
                    { FmodManager.ArmorMaterialType.None, "Naked" },
                });

                if (ImGui.BeginMenu("Footstep Material"))
                {
                    foreach (var mat in FmodManager.FloorMaterialNames)
                    {
                        if (ClickItem($"Material {mat.Key:D2}", shortcut: mat.Value, shortcutColor: Color.White))
                        {
                            FmodManager.FloorMaterial = mat.Key;
                        }
                    }

                    ImGui.EndMenu();
                }

                ImGui.EndMenu();
            }

            //TODO - HELP. BETTER.

            void DoWindow(Window w)
            {
                w.IsOpen = Checkbox(w.Title, w.IsOpen);
            }

            if (ImGui.BeginMenu("Tools"))
            {
                isAnyMenuExpanded = true;

                if (ClickItem("Combo Viewer", shortcut: "F8"))
                {
                    Tae.ShowComboMenu();
                }

#if DEBUG
                if (ClickItem("Scan for Unused Animations", shortcut: "[DEBUG]",
                              textColor: Color.Red, shortcutColor: Color.Red))
                {
                    Tae.Tools_ScanForUnusedAnimations();
                }
#endif

                if (ClickItem("Downgrade Havok 2015 ANIBND(s) to 2010...", shortcut: "For DS1R/Sekiro", shortcutColor: Color.Cyan))
                {
                    Tae.Tools_DowngradeSekiroAnibnds();
                }

                if (ClickItem("Import all DS1:PTDE ANIBNDs to DS1R...", shortcut: "Much faster than above option,\n" +
                              "but requires an unpacked copy of both games.", shortcutColor: Color.Magenta))
                {
                    Tae.Tools_ImportAllPTDEAnibndToDS1R();
                }


                ImGui.Separator();

                if (ClickItem("Open Animation Importer"))
                {
                    Tae.BringUpImporter_FBXAnim();
                }

                ImGui.EndMenu();
            }

            if (ImGui.BeginMenu("Window"))
            {
                DoWindow(OSD.WindowEntitySettings);
                //DoWindow(OSD.WindowEditPlayerEquip); //handled in player menu
                //DoWindow(OSD.WindowHelp); //handled in help menu
                DoWindow(OSD.WindowSceneManager);
                DoWindow(OSD.WindowToolbox);

                if (OSD.EnableDebugMenu)
                {
                    ImGui.Separator();
                    DoWindow(OSD.WindowDebug);
                }
                else
                {
                    OSD.WindowDebug.IsOpen = false;
                }

                ImGui.EndMenu();
            }

            ImGui.PushStyleColor(ImGuiCol.Text, Color.Cyan.ToNVector4());
            bool helpMenu = ImGui.BeginMenu("Help");
            ImGui.PopStyleColor();
            if (helpMenu)
            {
                isAnyMenuExpanded = true;

                OSD.WindowHelp.IsOpen = Checkbox("Show Basic Help Window", OSD.WindowHelp.IsOpen, textColor: Color.White);

                ImGui.Separator();

                if (ClickItem("Souls Modding Discord Server", textColor: Color.White,
                              shortcut: "?ServerName? (https://discord.gg/mT2JJjx)", shortcutColor: Color.Cyan))
                {
                    Process.Start("https://discord.gg/mT2JJjx");
                }

                if (ClickItem("My Discord Server (Less Active)", textColor: Color.White,
                              shortcut: "Meowmaritus Zone (https://discord.gg/J79XMgR)", shortcutColor: Color.Cyan))
                {
                    Process.Start("https://discord.gg/J79XMgR");
                }

                ImGui.EndMenu();
            }

            ImGui.PushStyleColor(ImGuiCol.Text, Color.Lime.ToNVector4());
            bool supportMenu = ImGui.BeginMenu("Support Meowmaritus");
            ImGui.PopStyleColor();

            if (supportMenu)
            {
                isAnyMenuExpanded = true;

                if (ClickItem("On Patreon...", textColor: Color.Lime,
                              shortcut: "(https://www.patreon.com/Meowmaritus)", shortcutColor: Color.Lime))
                {
                    Process.Start("https://www.patreon.com/Meowmaritus");
                }

                if (ClickItem("On Paypal...", textColor: Color.Lime,
                              shortcut: "(https://paypal.me/Meowmaritus)", shortcutColor: Color.Lime))
                {
                    Process.Start("https://paypal.me/Meowmaritus");
                }

                if (ClickItem("On Ko-fi...", textColor: Color.Lime,
                              shortcut: "(https://ko-fi.com/meowmaritus)", shortcutColor: Color.Lime))
                {
                    Process.Start("https://ko-fi.com/meowmaritus");
                }

                ImGui.EndMenu();
            }

            IsAnyMenuOpen = isAnyMenuExpanded;

            IsAnyMenuOpenChanged = IsAnyMenuOpen != prevIsAnyMenuOpen;

            prevIsAnyMenuOpen = IsAnyMenuOpen;
        }