diff --git a/FDK/src/01.Framework/Core/Game.cs b/FDK/src/01.Framework/Core/Game.cs index e2aba2d2..06b389f0 100644 --- a/FDK/src/01.Framework/Core/Game.cs +++ b/FDK/src/01.Framework/Core/Game.cs @@ -74,7 +74,7 @@ namespace SampleFramework { } Marshal.FreeHGlobal((IntPtr)out_pixels); - ImGuiIO.Fonts.SetTexID((nint)ImGuiFontAtlas.Texture_); + ImGuiIO.Fonts.SetTexID((nint)ImGuiFontAtlas.Pointer); } } } diff --git a/FDK/src/02.Input/CInputGamepad.cs b/FDK/src/02.Input/CInputGamepad.cs index cd80ac3c..4800fa28 100644 --- a/FDK/src/02.Input/CInputGamepad.cs +++ b/FDK/src/02.Input/CInputGamepad.cs @@ -118,7 +118,7 @@ namespace FDK { #region [ private ] //----------------- - private (bool, int)[] ButtonStates = new (bool, int)[15]; + public (bool, int)[] ButtonStates { get; private set; } = new (bool, int)[15]; private bool IsDisposed; private void Joystick_ButtonDown(IGamepad joystick, Button button) { diff --git a/FDK/src/02.Input/CInputJoystick.cs b/FDK/src/02.Input/CInputJoystick.cs index 41ece0e3..915244ba 100644 --- a/FDK/src/02.Input/CInputJoystick.cs +++ b/FDK/src/02.Input/CInputJoystick.cs @@ -131,7 +131,7 @@ namespace FDK { #region [ private ] //----------------- - private (bool, int)[] ButtonStates = new (bool, int)[18]; + public (bool, int)[] ButtonStates { get; private set; } = new (bool, int)[18]; private bool IsDisposed; private void Joystick_ButtonDown(IJoystick joystick, Button button) { diff --git a/FDK/src/02.Input/CInputKeyboard.cs b/FDK/src/02.Input/CInputKeyboard.cs index fbe5344a..ff39c44f 100644 --- a/FDK/src/02.Input/CInputKeyboard.cs +++ b/FDK/src/02.Input/CInputKeyboard.cs @@ -113,7 +113,7 @@ namespace FDK { #region [ private ] //----------------- - private (bool, int)[] KeyStates = new (bool, int)[144]; + public (bool, int)[] KeyStates { get; private set; } = new (bool, int)[144]; private bool IsDisposed; //private CTimer timer; //private CTimer ct; diff --git a/FDK/src/02.Input/CInputMouse.cs b/FDK/src/02.Input/CInputMouse.cs index e7fc4f0f..1b2e3444 100644 --- a/FDK/src/02.Input/CInputMouse.cs +++ b/FDK/src/02.Input/CInputMouse.cs @@ -113,7 +113,7 @@ namespace FDK { #region [ private ] //----------------- - private (bool, int)[] MouseStates = new (bool, int)[12]; + public (bool, int)[] MouseStates { get; private set; } = new (bool, int)[12]; private bool IsDisposed; private void Mouse_Click(IMouse mouse, MouseButton mouseButton, Vector2 vector2) { diff --git a/FDK/src/04.Graphics/CTexture.cs b/FDK/src/04.Graphics/CTexture.cs index c61510b2..44578cf9 100644 --- a/FDK/src/04.Graphics/CTexture.cs +++ b/FDK/src/04.Graphics/CTexture.cs @@ -316,7 +316,7 @@ namespace FDK { /// public static float f画面比率 = 1.0f; - public uint Texture_ { get; internal set; } + public uint Pointer { get; internal set; } // Constructor @@ -337,12 +337,12 @@ namespace FDK { this.b加算合成 = tx.b加算合成; this.fZ軸中心回転 = tx.fZ軸中心回転; this.vcScaleRatio = tx.vcScaleRatio; - Texture_ = tx.Texture_; + Pointer = tx.Pointer; // this._txData = null; } public void UpdateTexture(CTexture texture, int n幅, int n高さ) { - Texture_ = texture.Texture_; + Pointer = texture.Pointer; this.sz画像サイズ = new Size(n幅, n高さ); this.szTextureSize = this.t指定されたサイズを超えない最適なテクスチャサイズを返す(this.sz画像サイズ); this.rc全画像 = new Rectangle(0, 0, this.sz画像サイズ.Width, this.sz画像サイズ.Height); @@ -350,9 +350,9 @@ namespace FDK { public void UpdateTexture(IntPtr texture, int width, int height, PixelFormat rgbaType) { unsafe { - Game.Gl.DeleteTexture(Texture_); //解放 + Game.Gl.DeleteTexture(Pointer); //解放 void* data = texture.ToPointer(); - Texture_ = GenTexture(data, (uint)width, (uint)height, rgbaType); + Pointer = GenTexture(data, (uint)width, (uint)height, rgbaType); } this.sz画像サイズ = new Size(width, height); this.szTextureSize = this.t指定されたサイズを超えない最適なテクスチャサイズを返す(this.sz画像サイズ); @@ -452,12 +452,12 @@ namespace FDK { unsafe { fixed (void* data = bitmap.Pixels) { if (Thread.CurrentThread.ManagedThreadId == Game.MainThreadID) { - Texture_ = GenTexture(data, (uint)bitmap.Width, (uint)bitmap.Height, PixelFormat.Bgra); + Pointer = GenTexture(data, (uint)bitmap.Width, (uint)bitmap.Height, PixelFormat.Bgra); } else { SKBitmap bm = bitmap.Copy(); Action createInstance = () => { fixed (void* data2 = bitmap.Pixels) { - Texture_ = GenTexture(data2, (uint)bitmap.Width, (uint)bitmap.Height, PixelFormat.Bgra); + Pointer = GenTexture(data2, (uint)bitmap.Width, (uint)bitmap.Height, PixelFormat.Bgra); } bm.Dispose(); }; @@ -696,7 +696,7 @@ namespace FDK { Game.Gl.UseProgram(ShaderProgram);//Uniform4よりこれが先 - Game.Gl.BindTexture(TextureTarget.Texture2D, Texture_); //テクスチャをバインド + Game.Gl.BindTexture(TextureTarget.Texture2D, Pointer); //テクスチャをバインド //MVPを設定---- unsafe { @@ -832,7 +832,7 @@ namespace FDK { Game.Gl.UseProgram(ShaderProgram);//Uniform4よりこれが先 - Game.Gl.BindTexture(TextureTarget.Texture2D, Texture_); //テクスチャをバインド + Game.Gl.BindTexture(TextureTarget.Texture2D, Pointer); //テクスチャをバインド //MVPを設定---- unsafe { @@ -894,7 +894,7 @@ namespace FDK { //----------------- public void Dispose() { if (!this.bDispose完了済み) { - Game.Gl.DeleteTexture(Texture_); //解放 + Game.Gl.DeleteTexture(Pointer); //解放 this.bDispose完了済み = true; } diff --git a/OpenTaiko/src/Common/ImGuiDebugWindow.cs b/OpenTaiko/src/Common/ImGuiDebugWindow.cs index d3444ef6..07566ba5 100644 --- a/OpenTaiko/src/Common/ImGuiDebugWindow.cs +++ b/OpenTaiko/src/Common/ImGuiDebugWindow.cs @@ -1,8 +1,11 @@ using System.Diagnostics; +using System.Drawing; +using System.Numerics; using System.Reflection; using System.Runtime.InteropServices; using FDK; using ImGuiNET; +using SampleFramework; namespace OpenTaiko { /* @@ -14,6 +17,11 @@ namespace OpenTaiko { private static long memoryReadTimer = 0; private static long pagedmemory = 0; + private static int textureMemoryUsage = 0; + + private static int sortType = -1; + private static readonly string[] sortNames = ["Memory Usage (Highest->Lowest)", "Memory Usage (Lowest->Highest)", "Pointer ID"]; + private static string reloadTexPath = ""; public static void Draw() { if (SampleFramework.Game.ImGuiController == null) return; @@ -47,8 +55,10 @@ namespace OpenTaiko { #region Tabs System(); + Inputs(); Profile(); Stage(); + Textures(); #endregion ImGui.EndTabBar(); @@ -56,6 +66,7 @@ namespace OpenTaiko { ImGui.End(); } } + #region Tabs private static void System() { if (ImGui.BeginTabItem("System")) { ImGui.TextWrapped($"Path: {(Environment.ProcessPath != null ? Environment.ProcessPath : "???")}"); @@ -63,7 +74,81 @@ namespace OpenTaiko { ImGui.Text($"OS Version: {Environment.OSVersion} ({RuntimeInformation.RuntimeIdentifier})"); ImGui.Text($"OS Architecture: {RuntimeInformation.OSArchitecture}"); ImGui.Text($"Framework Version: {RuntimeInformation.FrameworkDescription}"); - ImGui.Text($"Is Privileged: {Environment.IsPrivilegedProcess}"); + ImGui.NewLine(); + ImGui.Text("Graphics API: " + Game.GraphicsDeviceType_); + ImGui.Text("Audio Device: " + OpenTaiko.SoundManager.GetCurrentSoundDeviceType()); + + ImGui.EndTabItem(); + } + } + private static void Inputs() { + if (ImGui.BeginTabItem("Inputs")) { + + ImGui.Text("Total Inputs Found: " + OpenTaiko.InputManager.InputDevices.Count()); + + ImGui.NewLine(); + + ImGui.Text("Input Count:"); + ImGui.Indent(); + ImGui.Text("Keyboard: " + OpenTaiko.InputManager.InputDevices.Count(device => device.CurrentType == InputDeviceType.Keyboard)); + ImGui.Text("Mouse: " + OpenTaiko.InputManager.InputDevices.Count(device => device.CurrentType == InputDeviceType.Mouse)); + ImGui.Text("Gamepad: " + OpenTaiko.InputManager.InputDevices.Count(device => device.CurrentType == InputDeviceType.Gamepad)); + ImGui.Text("Joystick: " + OpenTaiko.InputManager.InputDevices.Count(device => device.CurrentType == InputDeviceType.Joystick)); + ImGui.Text("MIDI: " + OpenTaiko.InputManager.InputDevices.Count(device => device.CurrentType == InputDeviceType.MidiIn)); + ImGui.Text("Unknown: " + OpenTaiko.InputManager.InputDevices.Count(device => device.CurrentType == InputDeviceType.Unknown)); + + foreach (IInputDevice device in OpenTaiko.InputManager.InputDevices) { + if (ImGui.TreeNodeEx(device.CurrentType.ToString() + " (ID " + device.ID + ")")) { + switch (device.CurrentType) { + case InputDeviceType.Keyboard: + var keyboard = (CInputKeyboard)device; + for (int i = 0; i < keyboard.KeyStates.Length; i++) { + if (keyboard.KeyPressed(i)) { ImGui.Text((SlimDXKeys.Key)i + " Pressed!"); } + if (keyboard.KeyPressing(i)) { ImGui.Text((SlimDXKeys.Key)i + " Pressing!"); } + if (keyboard.KeyReleased(i)) { ImGui.Text((SlimDXKeys.Key)i + " Released!"); } + } + break; + case InputDeviceType.Mouse: + var mouse = (CInputMouse)device; + for (int i = 0; i < mouse.MouseStates.Length; i++) { + if (mouse.KeyPressed(i)) { ImGui.Text((Silk.NET.Input.MouseButton)i + " Pressed!"); } + if (mouse.KeyPressing(i)) { ImGui.Text((Silk.NET.Input.MouseButton)i + " Pressing!"); } + if (mouse.KeyReleased(i)) { ImGui.Text((Silk.NET.Input.MouseButton)i + " Released!"); } + } + break; + case InputDeviceType.Gamepad: + var gamepad = (CInputGamepad)device; + for (int i = 0; i < gamepad.ButtonStates.Length; i++) { + if (gamepad.KeyPressed(i)) { ImGui.Text((Silk.NET.Input.ButtonName)i + " Pressed!"); } + if (gamepad.KeyPressing(i)) { ImGui.Text((Silk.NET.Input.ButtonName)i + " Pressing!"); } + if (gamepad.KeyReleased(i)) { ImGui.Text((Silk.NET.Input.ButtonName)i + " Released!"); } + } + break; + case InputDeviceType.Joystick: + var joystick = (CInputJoystick)device; + for (int i = 0; i < joystick.ButtonStates.Length; i++) { + if (joystick.KeyPressed(i)) { ImGui.Text((Silk.NET.Input.ButtonName)i + " Pressed!"); } + if (joystick.KeyPressing(i)) { ImGui.Text((Silk.NET.Input.ButtonName)i + " Pressing!"); } + if (joystick.KeyReleased(i)) { ImGui.Text((Silk.NET.Input.ButtonName)i + " Released!"); } + } + break; + case InputDeviceType.MidiIn: + var midiin = (CInputMIDI)device; + //for (int i = 0; i < midiin.InputEvents.Count; i++) { + // if (midiin.InputEvents[i].Pressed) { ImGui.Text(midiin.InputEvents[i].nKey + " Pressed!"); } + // if (midiin.KeyPressing(i)) { ImGui.Text("Pressing!"); } + // if (midiin.InputEvents[i].Released) { ImGui.Text(midiin.InputEvents[i].nKey + " Released!"); } + //} + ImGui.TextColored(new Vector4(1, 0, 0, 1), "MIDI input polling is currently disabled."); + break; + case InputDeviceType.Unknown: + ImGui.TextDisabled("Unknown input device type."); + ImGui.TextDisabled("GUID: " + device.GUID); + break; + } + ImGui.TreePop(); + } + } ImGui.EndTabItem(); } @@ -197,48 +282,177 @@ namespace OpenTaiko { } break; case CStage.EStage.Game: - switch (OpenTaiko.DifficultyNumberToEnum(OpenTaiko.stageSongSelect.nChoosenSongDifficulty[0])) { - case Difficulty.Dan: - ImGui.SeparatorText("Dan Dojo Mode"); - break; - case Difficulty.Tower: - ImGui.SeparatorText("Tower Mode"); - break; - default: - ImGui.SeparatorText(OpenTaiko.ConfigIni.nGameType[0] == EGameType.Konga ? "Konga Mode" : "Taiko Mode"); - break; - - } - for (int i = 0; i < OpenTaiko.ConfigIni.nPlayerCount; i++) - ImGui.Text($"Auto Play ({i + 1}P): " + OpenTaiko.ConfigIni.bAutoPlay[i]); - - ImGui.NewLine(); - - ImGui.Text("Title: " + OpenTaiko.DTX.TITLE.GetString("???")); - ImGui.Text("Subtitle: " + OpenTaiko.DTX.SUBTITLE.GetString("???")); - if (!string.IsNullOrEmpty(OpenTaiko.DTX.MAKER)) { - ImGui.Text("Charter: " + OpenTaiko.DTX.MAKER); - } else { - ImGui.TextDisabled("Charter: (None)"); - } for (int i = 0; i < OpenTaiko.ConfigIni.nPlayerCount; i++) { - var dtx = OpenTaiko.GetDTX(i); + if (ImGui.TreeNodeEx($"Player {i+1}###GAME_CHART_{i}", ImGuiTreeNodeFlags.Framed)) { + + Difficulty game_difficulty = OpenTaiko.DifficultyNumberToEnum(OpenTaiko.stageSongSelect.nChoosenSongDifficulty[i]); + var dtx = OpenTaiko.GetDTX(i); + + switch (game_difficulty) { + case Difficulty.Dan: + ImGui.SeparatorText("Dan Dojo Mode"); + break; + case Difficulty.Tower: + ImGui.SeparatorText("Tower Mode"); + ImGui.Text("Side: " + dtx.SIDE); + ImGui.Text("Life: " + dtx.LIFE); + ImGui.Text("Floor Count: " + OpenTaiko.stageSongSelect.rNowSelectedSong.arスコア[5].譜面情報.nTotalFloor); + break; + default: + ImGui.SeparatorText(OpenTaiko.ConfigIni.nGameType[i] == EGameType.Konga ? "Konga Mode" : "Taiko Mode"); + break; - ImGui.Text("BPM: " + dtx.BASEBPM + (dtx.listBPM.Count > 1 ? (" (Min: " + dtx.MinBPM + " / Max: " + dtx.MaxBPM + ")") : "")); - if (dtx.listBPM.Count > 1) { - if (ImGui.TreeNodeEx($"BPM List ({dtx.listBPM.Count})###GAME_BPM_LIST_{i}")) { - foreach (CDTX.CBPM bpm in dtx.listBPM.Values) { - ImGui.Text($"(Time: {String.Format("{0:0.#}s", (bpm.bpm_change_time / 1000))}) {bpm.dbBPM値}"); - } - ImGui.TreePop(); } + ImGui.TextColored(ColorToVector4(OpenTaiko.Skin.SongSelect_Difficulty_Colors[(int)game_difficulty]), $"Difficulty: {game_difficulty}"); + ImGui.Text($"Auto Play: " + OpenTaiko.ConfigIni.bAutoPlay[i]); + + ImGui.NewLine(); + + ImGui.Text("ID: " + dtx.uniqueID.data.id); + ImGui.Text("Title: " + dtx.TITLE.GetString("")); + ImGui.Text("Subtitle: " + dtx.SUBTITLE.GetString("")); + ImGui.Text("Charter: " + dtx.MAKER); + + // BPM + ImGui.Text("BPM: " + dtx.BASEBPM + (dtx.listBPM.Count > 1 ? (" (Min: " + dtx.MinBPM + " / Max: " + dtx.MaxBPM + ")") : "")); + if (dtx.listBPM.Count > 1) { + if (ImGui.TreeNodeEx($"BPM List ({dtx.listBPM.Count})###GAME_BPM_LIST_{i}")) { + foreach (CDTX.CBPM bpm in dtx.listBPM.Values) { + ImGui.Text($"(Time: {String.Format("{0:0.#}s", (bpm.bpm_change_time / 1000))}) {bpm.dbBPM値}"); + } + ImGui.TreePop(); + } + } + + ImGui.NewLine(); + + ImGui.Text("Note Count: "); + ImGui.Indent(); + ImGui.Text("Normal: " + dtx.nノーツ数_Branch[0] + + " / Expert: " + dtx.nノーツ数_Branch[1] + + " / Master: " + dtx.nノーツ数_Branch[2]); + ImGui.Unindent(); + + ImGui.TreePop(); } + } + break; } ImGui.EndTabItem(); } } + private static void Textures() { + if (ImGui.BeginTabItem("Textures")) { + ImGui.Text("Total Texture Count: " + OpenTaiko.Tx.listTexture.Count); + ImGui.Text("Total Memory Usage: " + textureMemoryUsage + "bytes (" + GetMemAllocationInMegabytes(textureMemoryUsage) + "MB)"); + if (ImGui.Button("Refresh") || textureMemoryUsage == 0) { + textureMemoryUsage = OpenTaiko.Tx.listTexture.Where(tex => tex != null).Sum(tex => tex.szTextureSize.Width * tex.szTextureSize.Height * 4); + } + if (ImGui.BeginCombo("Change Sort", sortType != -1 ? sortNames[sortType] : "(Default)")) { + if (ImGui.Selectable(sortNames[0], sortType == 0)) { + OpenTaiko.Tx.listTexture.Sort((tex1, tex2) => (tex2 != null ? tex2.szTextureSize.Width * tex2.szTextureSize.Height : -1).CompareTo(tex1 != null ? tex1.szTextureSize.Width * tex1.szTextureSize.Height : -1)); + sortType = 0; + } + if (ImGui.Selectable(sortNames[1], sortType == 1)) { + OpenTaiko.Tx.listTexture.Sort((tex1, tex2) => (tex1 != null ? tex1.szTextureSize.Width * tex1.szTextureSize.Height : -1).CompareTo(tex2 != null ? tex2.szTextureSize.Width * tex2.szTextureSize.Height : -1)); + sortType = 1; + } + if (ImGui.Selectable(sortNames[2], sortType == 2)) { + OpenTaiko.Tx.listTexture.Sort((tex1, tex2) => (tex1 != null ? (int)tex1.Pointer : -1).CompareTo(tex2 != null ? (int)tex2.Pointer : -1)); + sortType = 2; + } + ImGui.EndCombo(); + } + + if (ImGui.TreeNodeEx("Show All Textures###TEXTURE_SHOWALL")) { + int index = 0; + if (OpenTaiko.r現在のステージ.eStageID == CStage.EStage.StartUp) + ImGui.TextDisabled("To prevent crash during enumeration,\nyou can not view the texture list during StartUp stage."); + else + foreach (CTexture tex in OpenTaiko.Tx.listTexture) { + CTexturePopup(tex, $"#{index} (Pointer: {(tex != null ? tex.Pointer : "null")})###TEXTURE_SHOW_POPUP_{index++}"); + } + ImGui.TreePop(); + } + ImGui.EndTabItem(); + } + } + #endregion + + #region ImGui Items + private static void CTexturePopup(CTexture texture, string label) { + if (ImGui.TreeNodeEx(label, ImGuiTreeNodeFlags.Framed)) { + + ImGui.BeginDisabled(); + ImGui.InputText("Path", ref reloadTexPath, 2048); + if (ImGui.Button("Reload via. Path (To-do)")) { + // To-do + } + ImGui.EndDisabled(); + + ImGui.TreePop(); + } + if (ImGui.IsItemHovered(ImGuiHoveredFlags.DelayNone)) { + if (ImGui.BeginItemTooltip()) { + if (DrawCTextureForImGui(texture, 800, 800)) { + ImGui.Text("Pointer: " + texture.Pointer); + ImGui.Text("Size: x" + texture.szTextureSize.Width + ",y" + texture.szTextureSize.Height); + ImGui.Text("Memory allocated: " + String.Format("{0:0.###}",GetTextureMemAllocationInMegabytes(texture)) + "MB"); + } + else { + ImGui.TextDisabled("Texture is not loaded."); + } + ImGui.EndTooltip(); + } + } + } + private static bool DrawCTextureForImGui(CTexture texture) { + if (texture == null) return false; + return DrawCTextureForImGui(texture, + new Vector2(texture.szTextureSize.Width, texture.szTextureSize.Height), + new Vector2(0,0), new Vector2(1,1)); + } + private static bool DrawCTextureForImGui(CTexture texture, int max_width, int max_height) { + if (texture == null) return false; + return DrawCTextureForImGui(texture, 0, 0, + Math.Min(texture.szTextureSize.Width, max_width), Math.Min(texture.szTextureSize.Height, max_height)); + } + private static bool DrawCTextureForImGui(CTexture texture, int x, int y, int width, int height) { + return DrawCTextureForImGui(texture, new Rectangle(x, y, width, height)); + } + private static bool DrawCTextureForImGui(CTexture texture, Rectangle rect) { + if (texture == null) return false; + return DrawCTextureForImGui(texture, + new Vector2(rect.Width, rect.Height), + new Vector2((float)rect.X / texture.szTextureSize.Width, (float)rect.Y / texture.szTextureSize.Height), + new Vector2((float)rect.Right / texture.szTextureSize.Width, (float)rect.Bottom / texture.szTextureSize.Height)); + } + /// Must be in pixels + /// Value is typically between 0.0f and 1.0f + /// Value is typically between 0.0f and 1.0f + private static bool DrawCTextureForImGui(CTexture texture, Vector2 image_size, Vector2 pos, Vector2 size) { + if (texture == null) return false; + ImGui.Image((nint)texture.Pointer, image_size, pos, size); + return true; + } + #endregion + + #region Helpers + private static float GetMemAllocationInMegabytes(int bytes) { return (float)bytes / (1024 * 1024); } + private static float GetTextureMemAllocationInMegabytes(CTexture texture) { + return (float)GetTextureMemAllocation(texture) / (1024 * 1024); + } + private static int GetTextureMemAllocation(CTexture texture) { + if (texture == null) return 0; + return texture.szTextureSize.Width * texture.szTextureSize.Height * 4; + } + private static Vector4 ColorToVector4(Color color) { + return new Vector4((float)color.R / 255, (float)color.G / 255, (float)color.B / 255, (float)color.A / 255); + } + #endregion + } } diff --git a/OpenTaiko/src/Stages/07.Game/Taiko/CActImplBackground.cs b/OpenTaiko/src/Stages/07.Game/Taiko/CActImplBackground.cs index dc5c9f46..3c7cd7fb 100644 --- a/OpenTaiko/src/Stages/07.Game/Taiko/CActImplBackground.cs +++ b/OpenTaiko/src/Stages/07.Game/Taiko/CActImplBackground.cs @@ -573,8 +573,8 @@ namespace OpenTaiko { //private CTexture tx下背景クリアメイン; //private CTexture tx下背景クリアサブ1; - private ScriptBG UpScript; - private ScriptBG DownScript; + public ScriptBG UpScript; + public ScriptBG DownScript; private TitleTextureKey ttkTouTatsuKaiSuu; private TitleTextureKey ttkKai;