From 75b3f84ba18dfceec406be34ffaf0b240b789db9 Mon Sep 17 00:00:00 2001 From: sin365 <353374337@qq.com> Date: Wed, 26 Feb 2025 19:56:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=AE=9A=E4=B9=89=E5=90=84?= =?UTF-8?q?=E7=A7=8DHandler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OpenGL.meta => Handlers.meta} | 2 +- .../StoicGoose.Common/OpenGL/Buffer.cs | 89 --- .../StoicGoose.Common/OpenGL/Buffer.cs.meta | 2 - .../StoicGoose.Common/OpenGL/ContextInfo.cs | 30 - .../OpenGL/ContextInfo.cs.meta | 2 - .../OpenGL/Shaders/Bundles/BundleManifest.cs | 18 - .../Shaders/Bundles/BundleManifest.cs.meta | 2 - .../OpenGL/Shaders/Program.cs | 80 --- .../OpenGL/Shaders/Program.cs.meta | 2 - .../OpenGL/Shaders/ShaderFactory.cs | 34 -- .../OpenGL/Shaders/ShaderFactory.cs.meta | 2 - .../StoicGoose.Common/OpenGL/State.cs | 109 ---- .../StoicGoose.Common/OpenGL/State.cs.meta | 2 - .../StoicGoose.Common/OpenGL/Texture.cs | 169 ----- .../StoicGoose.Common/OpenGL/Texture.cs.meta | 2 - .../OpenGL/Uniforms/Color4Uniform.cs | 16 - .../OpenGL/Uniforms/Color4Uniform.cs.meta | 2 - .../OpenGL/Uniforms/FloatUniform.cs | 15 - .../OpenGL/Uniforms/FloatUniform.cs.meta | 2 - .../OpenGL/Uniforms/GenericUniform.cs | 33 - .../OpenGL/Uniforms/GenericUniform.cs.meta | 2 - .../OpenGL/Uniforms/IntUniform.cs | 15 - .../OpenGL/Uniforms/IntUniform.cs.meta | 2 - .../OpenGL/Uniforms/Matrix2Uniform.cs | 16 - .../OpenGL/Uniforms/Matrix2Uniform.cs.meta | 2 - .../OpenGL/Uniforms/Matrix3Uniform.cs | 16 - .../OpenGL/Uniforms/Matrix3Uniform.cs.meta | 2 - .../OpenGL/Uniforms/Matrix4Uniform.cs | 16 - .../OpenGL/Uniforms/Matrix4Uniform.cs.meta | 2 - .../OpenGL/Uniforms/UintUniform.cs | 15 - .../OpenGL/Uniforms/UintUniform.cs.meta | 2 - .../OpenGL/Uniforms/Vector2Uniform.cs | 16 - .../OpenGL/Uniforms/Vector2Uniform.cs.meta | 2 - .../OpenGL/Uniforms/Vector3Uniform.cs | 16 - .../OpenGL/Uniforms/Vector3Uniform.cs.meta | 2 - .../OpenGL/Uniforms/Vector4Uniform.cs | 16 - .../OpenGL/Uniforms/Vector4Uniform.cs.meta | 2 - .../StoicGoose.Common/OpenGL/Vertices.meta | 8 - .../OpenGL/Vertices/IVertexStruct.cs | 4 - .../OpenGL/Vertices/IVertexStruct.cs.meta | 2 - .../OpenGL/Vertices/Vertex.cs | 13 - .../OpenGL/Vertices/Vertex.cs.meta | 2 - .../OpenGL/Vertices/VertexArray.cs | 213 ------- .../OpenGL/Vertices/VertexArray.cs.meta | 2 - .../OpenGL/Vertices/VertexAttribute.cs | 12 - .../OpenGL/Vertices/VertexAttribute.cs.meta | 2 - .../StoicGoose.Common/Utilities/Log.cs | 118 ++-- .../StoicGoose.Core/Interfaces/IMachine.cs | 13 +- .../OpenGL/Shaders.meta => Script.meta} | 2 +- .../Bundles.meta => Script/AppMain.meta} | 2 +- .../AppMain/Emulator.meta} | 2 +- Assets/Script/AppMain/Emulator/RingBuffer.cs | 72 +++ .../AppMain/Emulator/RingBuffer.cs.meta | 2 + .../AppMain/Emulator/StoicGooseEmulator.meta | 8 + .../StoicGooseEmulator/Configuration.cs | 90 +++ .../StoicGooseEmulator/Configuration.cs.meta | 2 + .../StoicGooseEmulator/GlobalVariables.cs | 27 + .../GlobalVariables.cs.meta | 2 + .../Emulator/StoicGooseEmulator/Handle.meta | 8 + .../Handle/DatabaseHandler.cs | 187 ++++++ .../Handle/DatabaseHandler.cs.meta | 2 + .../Handle/EmulatorHandler.cs | 121 ++++ .../Handle/EmulatorHandler.cs.meta | 2 + .../AppMain/Emulator/StoicGooseInterface.meta | 8 + .../StoicGooseInterface/SGKeyboard.cs | 16 + .../StoicGooseInterface/SGKeyboard.cs.meta | 2 + .../StoicGooseInterface/SGSoundPlayer.cs | 328 ++++++++++ .../StoicGooseInterface/SGSoundPlayer.cs.meta | 2 + .../StoicGooseInterface/SGVideoPlayer.cs | 12 + .../StoicGooseInterface/SGVideoPlayer.cs.meta | 2 + Assets/Script/AppMain/Emulator/UStoicGoose.cs | 577 ++++++++++++++++++ .../AppMain/Emulator/UStoicGoose.cs.meta | 2 + 72 files changed, 1535 insertions(+), 1089 deletions(-) rename Assets/Plugins/StoicGooseUnity/{StoicGoose.Common/OpenGL.meta => Handlers.meta} (77%) delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Buffer.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Buffer.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/ContextInfo.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/ContextInfo.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles/BundleManifest.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles/BundleManifest.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Program.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Program.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/ShaderFactory.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/ShaderFactory.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/State.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/State.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Texture.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Texture.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Color4Uniform.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Color4Uniform.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/FloatUniform.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/FloatUniform.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/GenericUniform.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/GenericUniform.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/IntUniform.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/IntUniform.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix2Uniform.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix2Uniform.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix3Uniform.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix3Uniform.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix4Uniform.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix4Uniform.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/UintUniform.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/UintUniform.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector2Uniform.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector2Uniform.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector3Uniform.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector3Uniform.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector4Uniform.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector4Uniform.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/IVertexStruct.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/IVertexStruct.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/Vertex.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/Vertex.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexArray.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexArray.cs.meta delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexAttribute.cs delete mode 100644 Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexAttribute.cs.meta rename Assets/{Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders.meta => Script.meta} (77%) rename Assets/{Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles.meta => Script/AppMain.meta} (77%) rename Assets/{Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms.meta => Script/AppMain/Emulator.meta} (77%) create mode 100644 Assets/Script/AppMain/Emulator/RingBuffer.cs create mode 100644 Assets/Script/AppMain/Emulator/RingBuffer.cs.meta create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseEmulator.meta create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseEmulator/Configuration.cs create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseEmulator/Configuration.cs.meta create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseEmulator/GlobalVariables.cs create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseEmulator/GlobalVariables.cs.meta create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle.meta create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/DatabaseHandler.cs create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/DatabaseHandler.cs.meta create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/EmulatorHandler.cs create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/EmulatorHandler.cs.meta create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseInterface.meta create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseInterface/SGKeyboard.cs create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseInterface/SGKeyboard.cs.meta create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseInterface/SGSoundPlayer.cs create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseInterface/SGSoundPlayer.cs.meta create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseInterface/SGVideoPlayer.cs create mode 100644 Assets/Script/AppMain/Emulator/StoicGooseInterface/SGVideoPlayer.cs.meta create mode 100644 Assets/Script/AppMain/Emulator/UStoicGoose.cs create mode 100644 Assets/Script/AppMain/Emulator/UStoicGoose.cs.meta diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL.meta b/Assets/Plugins/StoicGooseUnity/Handlers.meta similarity index 77% rename from Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL.meta rename to Assets/Plugins/StoicGooseUnity/Handlers.meta index 08b6b34..cf8328a 100644 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL.meta +++ b/Assets/Plugins/StoicGooseUnity/Handlers.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 574b4bdd297790146bf92464ada13031 +guid: f08bda821691d2a41a751fae22728b71 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Buffer.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Buffer.cs deleted file mode 100644 index 0c6e4d4..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Buffer.cs +++ /dev/null @@ -1,89 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -using OpenTK.Graphics.OpenGL4; - -using StoicGoose.Common.OpenGL.Vertices; - -namespace StoicGoose.Common.OpenGL -{ - public sealed class Buffer : IDisposable - { - internal readonly Type dataType = default; - internal readonly BufferTarget bufferTarget = 0; - internal readonly BufferUsageHint bufferUsageHint = 0; - - internal readonly int handle = GL.GenBuffer(); - internal readonly int sizeInBytes = 0; - internal int count = 0; - - public Buffer(Type type, BufferTarget target, BufferUsageHint usage) - { - dataType = type; - bufferTarget = target; - bufferUsageHint = usage; - - sizeInBytes = Marshal.SizeOf(dataType); - } - - ~Buffer() - { - Dispose(); - } - - public void Dispose() - { - if (GL.IsBuffer(handle)) - GL.DeleteBuffer(handle); - - GC.SuppressFinalize(this); - } - - public static Buffer CreateBuffer(BufferTarget target, BufferUsageHint usage) where T : struct => new(typeof(T), target, usage); - public static Buffer CreateVertexBuffer(BufferUsageHint usage) where T : struct, IVertexStruct => CreateBuffer(BufferTarget.ArrayBuffer, usage); - public static Buffer CreateIndexBuffer(BufferUsageHint usage) where T : struct, IConvertible => CreateBuffer(BufferTarget.ElementArrayBuffer, usage); - - public void Bind() - { - GL.BindBuffer(bufferTarget, handle); - } - - public void Update(T[] data) where T : struct - { - if (dataType != typeof(T)) - throw new Exception("Type mismatch on buffer update"); - - if (data != null) - { - Bind(); - - if (data.Length == count) - GL.BufferSubData(bufferTarget, IntPtr.Zero, new IntPtr(count * sizeInBytes), data); - else - { - count = data.Length; - GL.BufferData(bufferTarget, new IntPtr(count * sizeInBytes), data, bufferUsageHint); - } - } - } - - public void Update(IntPtr data, int size) where T : struct - { - if (dataType != typeof(T)) - throw new Exception("Type mismatch on buffer update"); - - if (data != IntPtr.Zero) - { - Bind(); - - if (size == count) - GL.BufferSubData(bufferTarget, IntPtr.Zero, new IntPtr(count * sizeInBytes), data); - else - { - count = size; - GL.BufferData(bufferTarget, new IntPtr(count * sizeInBytes), data, bufferUsageHint); - } - } - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Buffer.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Buffer.cs.meta deleted file mode 100644 index aaf40d3..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Buffer.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 758af90e896ed334daa4b2c0b1ab907e \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/ContextInfo.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/ContextInfo.cs deleted file mode 100644 index bea7029..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/ContextInfo.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Linq; - -using OpenTK.Graphics.OpenGL4; - -using StoicGoose.Common.Utilities; - -namespace StoicGoose.Common.OpenGL -{ - public static class ContextInfo - { - public static string GLRenderer { get; } = GL.GetString(StringName.Renderer); - public static string GLShadingLanguageVersion { get; } = GL.GetString(StringName.ShadingLanguageVersion); - public static string GLVendor { get; } = GL.GetString(StringName.Vendor); - public static string GLVersion { get; } = GL.GetString(StringName.Version); - public static string[] GLExtensions { get; } = new string[GL.GetInteger(GetPName.NumExtensions)].Select((x, i) => x = GL.GetString(StringNameIndexed.Extensions, i)).ToArray(); - - public static void WriteToLog(object source, bool withExtensions = false) - { - Log.WriteEvent(LogSeverity.Debug, source, "OpenGL context:"); - Log.WriteEvent(LogSeverity.Debug, source, $"- Renderer: {GLRenderer}"); - Log.WriteEvent(LogSeverity.Debug, source, $"- Vendor: {GLVendor}"); - Log.WriteEvent(LogSeverity.Debug, source, $"- Version: {GLVersion}"); - Log.WriteEvent(LogSeverity.Debug, source, $"- GLSL version: {GLShadingLanguageVersion}"); - Log.WriteEvent(LogSeverity.Debug, source, $"- {GLExtensions.Length} extension(s) supported."); - if (withExtensions) - foreach (var extension in GLExtensions) - Log.WriteEvent(LogSeverity.Debug, source, $" {extension}"); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/ContextInfo.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/ContextInfo.cs.meta deleted file mode 100644 index e09b9c9..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/ContextInfo.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 75f627f66f93bc941b7f2317eb530132 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles/BundleManifest.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles/BundleManifest.cs deleted file mode 100644 index 6a0d5ae..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles/BundleManifest.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; - -namespace StoicGoose.Common.OpenGL.Shaders.Bundles -{ - public enum FilterMode { Linear, Nearest } - - public enum WrapMode { Repeat, Edge, Border, Mirror } - - public class BundleManifest - { - [JsonConverter(typeof(StringEnumConverter))] - public FilterMode Filter { get; set; } = FilterMode.Linear; - [JsonConverter(typeof(StringEnumConverter))] - public WrapMode Wrap { get; set; } = WrapMode.Repeat; - public int Samplers { get; set; } = 3; - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles/BundleManifest.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles/BundleManifest.cs.meta deleted file mode 100644 index eda8780..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles/BundleManifest.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: d09910e9ec835b4499af6123b16a840a \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Program.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Program.cs deleted file mode 100644 index faf7713..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Program.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; -using System.Collections.Generic; - -using OpenTK.Graphics.OpenGL4; - -namespace StoicGoose.Common.OpenGL.Shaders -{ - public sealed class Program : IDisposable - { - public int Handle { get; } = GL.CreateProgram(); - - readonly Dictionary uniformLocations = new(); - - bool disposed = false; - - public Program(params int[] shaders) - { - foreach (var shader in shaders) GL.AttachShader(Handle, shader); - GL.LinkProgram(Handle); - - GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out int status); - if (status != 1) - { - GL.GetProgramInfoLog(Handle, out string info); - GL.DeleteProgram(Handle); - throw new Exception($"Program link failed:\n{info}"); - } - - foreach (var shader in shaders) - { - GL.DetachShader(Handle, shader); - GL.DeleteShader(shader); - } - - GL.UseProgram(0); - } - - ~Program() - { - Dispose(false); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (disposed) - return; - - if (disposing) - { - if (GL.IsProgram(Handle)) - GL.DeleteProgram(Handle); - } - - disposed = true; - } - - public void Bind() - { - GL.UseProgram(Handle); - } - - public int GetUniformLocation(string name) - { - if (!uniformLocations.ContainsKey(name)) - { - var location = GL.GetUniformLocation(Handle, name); - if (location != -1) uniformLocations[name] = location; - return location; - } - else - return uniformLocations[name]; - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Program.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Program.cs.meta deleted file mode 100644 index c867a70..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Program.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 178551683b089fd41bbc20f82964d581 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/ShaderFactory.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/ShaderFactory.cs deleted file mode 100644 index 0fd02cc..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/ShaderFactory.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Linq; - -using OpenTK.Graphics.OpenGL4; - -namespace StoicGoose.Common.OpenGL.Shaders -{ - public static class ShaderFactory - { - public static int FromSource(ShaderType shaderType, params string[] shaderSource) - { - shaderSource = Sanitize(shaderSource); - - int handle = GL.CreateShader(shaderType); - GL.ShaderSource(handle, shaderSource.Length, shaderSource, (int[])null); - GL.CompileShader(handle); - - GL.GetShader(handle, ShaderParameter.CompileStatus, out int status); - if (status != 1) - { - GL.GetShaderInfoLog(handle, out string info); - GL.DeleteShader(handle); - throw new Exception($"{shaderType} compile failed:\n{info}"); - } - - return handle; - } - - private static string[] Sanitize(string[] shaderSource) - { - return shaderSource.Where(x => !string.IsNullOrEmpty(x)).Select(z => string.Concat(z, Environment.NewLine)).ToArray(); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/ShaderFactory.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/ShaderFactory.cs.meta deleted file mode 100644 index 59bb161..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/ShaderFactory.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: d34d8d41a7c062747ba60af3cca96bdd \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/State.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/State.cs deleted file mode 100644 index 2ebf77b..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/State.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Drawing; -using System.Runtime.CompilerServices; - -using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; - -namespace StoicGoose.Common.OpenGL -{ - public class State - { - static State lastState = default; - - bool depthTestEnable = true, blendEnable = true, cullFaceEnable = true, scissorTestEnable = false; - BlendingFactor blendSource = BlendingFactor.SrcAlpha, blendDest = BlendingFactor.OneMinusSrcAlpha; - CullFaceMode cullFaceMode = CullFaceMode.Back; - Vector4i scissorBox = Vector4i.Zero; - Color clearColor = Color.Black; - Vector4i viewport = Vector4i.Zero; - - public void Enable(EnableCap cap) => SetCap(cap, true); - public void Disable(EnableCap cap) => SetCap(cap, false); - - public void SetBlending(BlendingFactor source, BlendingFactor dest) { blendSource = source; blendDest = dest; } - public void SetCullFace(CullFaceMode mode) => cullFaceMode = mode; - public void SetScissor(Vector4i box) => scissorBox = box; - public void SetScissor(int x, int y, int width, int height) => scissorBox = new(x, y, width, height); - public void SetClearColor(Color color) => clearColor = color; - public void SetViewport(Vector4i vp) => viewport = vp; - public void SetViewport(int x, int y, int width, int height) => viewport = new(x, y, width, height); - - private void SetCap(EnableCap cap, bool value) - { - switch (cap) - { - case EnableCap.DepthTest: depthTestEnable = value; break; - case EnableCap.Blend: blendEnable = value; break; - case EnableCap.CullFace: cullFaceEnable = value; break; - case EnableCap.ScissorTest: scissorTestEnable = value; break; - default: throw new StateException($"{cap} not implemented"); - } - } - - private bool GetCap(EnableCap cap) - { - return cap switch - { - EnableCap.DepthTest => depthTestEnable, - EnableCap.Blend => blendEnable, - EnableCap.CullFace => cullFaceEnable, - EnableCap.ScissorTest => scissorTestEnable, - _ => throw new StateException($"{cap} not implemented"), - }; - } - - public void Submit() - { - if (lastState?.clearColor != clearColor) - GL.ClearColor(clearColor); - - SubmitState(EnableCap.DepthTest, depthTestEnable); - SubmitState(EnableCap.Blend, blendEnable); - SubmitState(EnableCap.CullFace, cullFaceEnable); - SubmitState(EnableCap.ScissorTest, scissorTestEnable); - - if (lastState?.viewport != viewport) - GL.Viewport(viewport.X, viewport.Y, viewport.Z, viewport.W); - - lastState = (State)MemberwiseClone(); - } - - private void SubmitState(EnableCap cap, bool value) - { - var enableChanged = lastState?.GetCap(cap) != GetCap(cap); - - if (value) - { - if (enableChanged) GL.Enable(cap); - - switch (cap) - { - case EnableCap.Blend: - if (lastState?.blendSource != blendSource || lastState?.blendDest != blendDest) - GL.BlendFunc(blendSource, blendDest); - break; - - case EnableCap.CullFace: - if (lastState?.cullFaceMode != cullFaceMode) - GL.CullFace(cullFaceMode); - break; - - case EnableCap.ScissorTest: - if (lastState?.scissorBox != scissorBox) - GL.Scissor(scissorBox.X, scissorBox.Y, scissorBox.Z, scissorBox.W); - break; - } - } - else - { - if (enableChanged) GL.Disable(cap); - } - } - } - - public class StateException : Exception - { - public StateException(string message, [CallerMemberName] string callerName = "") : base($"In {callerName}: {message}") { } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/State.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/State.cs.meta deleted file mode 100644 index 3d65ff6..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/State.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 792e396ff7046af4eb6149dbaad83660 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Texture.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Texture.cs deleted file mode 100644 index aa0bd14..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Texture.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; - -using StoicGoose.Common.Drawing; - -namespace StoicGoose.Common.OpenGL -{ - public sealed class Texture : IDisposable - { - const TextureMinFilter defaultMinFilter = TextureMinFilter.Nearest; - const TextureMagFilter defaultMagFilter = TextureMagFilter.Nearest; - const TextureWrapMode defaultWrapModeS = TextureWrapMode.Repeat; - const TextureWrapMode defaultWrapModeT = TextureWrapMode.Repeat; - - public int Handle { get; } = GL.GenTexture(); - public Vector2i Size { get; private set; } = Vector2i.Zero; - - byte[] pixelData = default; - bool isDirty = false; - - bool disposed = false; - - public Texture(int width, int height) : this(width, height, 255, 255, 255, 255) { } - - public Texture(int width, int height, byte r, byte g, byte b, byte a) - { - Size = new Vector2i(width, height); - var data = new byte[width * height * 4]; - for (var i = 0; i < data.Length; i += 4) - { - data[i + 0] = r; - data[i + 1] = g; - data[i + 2] = b; - data[i + 3] = a; - } - SetInitialTexImage(data); - } - - public Texture(RgbaFile rgbaFile) - { - Size = new Vector2i((int)rgbaFile.Width, (int)rgbaFile.Height); - SetInitialTexImage(rgbaFile.PixelData); - } - - public Texture(int width, int height, byte[] data) - { - Size = new Vector2i(width, height); - SetInitialTexImage(data); - } - - public Texture(int width, int height, IntPtr data) - { - Size = new Vector2i(width, height); - SetInitialTexImage(data); - } - - ~Texture() - { - Dispose(false); - } - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (disposed) - return; - - if (disposing) - { - if (GL.IsTexture(Handle)) - GL.DeleteTexture(Handle); - } - - disposed = true; - } - - private void SetInitialTexImage(byte[] data) - { - var handle = GCHandle.Alloc(data, GCHandleType.Pinned); - var pointer = handle.AddrOfPinnedObject(); - SetInitialTexImage(pointer); - handle.Free(); - } - - private void SetInitialTexImage(IntPtr pixels) - { - ChangeTextureParams(() => - { - GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8, Size.X, Size.Y, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixels); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)defaultMinFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)defaultMagFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)defaultWrapModeS); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)defaultWrapModeT); - }); - } - - public void SetTextureFilter(TextureMinFilter textureMinFilter, TextureMagFilter textureMagFilter) - { - ChangeTextureParams(() => - { - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)textureMinFilter); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)textureMagFilter); - }); - } - - public void SetTextureWrapMode(TextureWrapMode textureWrapModeS, TextureWrapMode textureWrapModeT) - { - ChangeTextureParams(() => - { - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)textureWrapModeS); - GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)textureWrapModeT); - }); - } - - private void ChangeTextureParams(Action action) - { - var lastTextureSet = GL.GetInteger(GetPName.Texture2D); - if (Handle != lastTextureSet) GL.BindTexture(TextureTarget.Texture2D, Handle); - action?.Invoke(); - GL.BindTexture(TextureTarget.Texture2D, lastTextureSet); - } - - public void Bind() - { - Bind(0); - } - - public void Bind(int textureUnit) - { - GL.ActiveTexture(TextureUnit.Texture0 + textureUnit); - GL.BindTexture(TextureTarget.Texture2D, Handle); - - if (isDirty) - { - GL.TexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, Size.X, Size.Y, PixelFormat.Rgba, PixelType.UnsignedByte, pixelData); - isDirty = false; - } - } - - public void Update(byte[] data) - { - isDirty = true; - pixelData = data; - } - - public void Fill(byte r, byte g, byte b, byte a) - { - isDirty = true; - - var data = new byte[Size.X * Size.Y * 4]; - for (var i = 0; i < data.Length; i += 4) - { - data[i + 0] = r; - data[i + 1] = g; - data[i + 2] = b; - data[i + 3] = a; - } - pixelData = data; - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Texture.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Texture.cs.meta deleted file mode 100644 index 5fd55ae..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Texture.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: e8e182c0d8fab6345820f6479ae9d179 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Color4Uniform.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Color4Uniform.cs deleted file mode 100644 index db6e6c4..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Color4Uniform.cs +++ /dev/null @@ -1,16 +0,0 @@ -using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; - -namespace StoicGoose.Common.OpenGL.Uniforms -{ - public sealed class Color4Uniform : GenericUniform - { - public Color4Uniform(string name) : this(name, Color4.White) { } - public Color4Uniform(string name, Color4 value) : base(name, value) { } - - protected override void SubmitUniform(int location) - { - GL.Uniform4(location, value); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Color4Uniform.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Color4Uniform.cs.meta deleted file mode 100644 index 57a13a0..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Color4Uniform.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 9c1a6e5abf4fb164680ad3838edd5d0a \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/FloatUniform.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/FloatUniform.cs deleted file mode 100644 index 366ab5a..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/FloatUniform.cs +++ /dev/null @@ -1,15 +0,0 @@ -using OpenTK.Graphics.OpenGL4; - -namespace StoicGoose.Common.OpenGL.Uniforms -{ - public sealed class FloatUniform : GenericUniform - { - public FloatUniform(string name) : this(name, 0.0f) { } - public FloatUniform(string name, float value) : base(name, value) { } - - protected override void SubmitUniform(int location) - { - GL.Uniform1(location, value); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/FloatUniform.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/FloatUniform.cs.meta deleted file mode 100644 index 8a6e0d9..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/FloatUniform.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: def2e09bbdbff364a98af688ebd96f48 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/GenericUniform.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/GenericUniform.cs deleted file mode 100644 index 96d04db..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/GenericUniform.cs +++ /dev/null @@ -1,33 +0,0 @@ -using ShaderProgram = StoicGoose.Common.OpenGL.Shaders.Program; - -namespace StoicGoose.Common.OpenGL.Uniforms -{ - public abstract class GenericUniform - { - protected readonly string name; - protected T value; - - public string Name => name; - public T Value - { - get => value; - set => this.value = value; - } - - public GenericUniform(string name) : this(name, default) { } - - public GenericUniform(string name, T value) - { - this.name = name; - this.value = value; - } - - public void SubmitToProgram(ShaderProgram shaderProgram) - { - var location = shaderProgram.GetUniformLocation(name); - if (location != -1) SubmitUniform(location); - } - - protected abstract void SubmitUniform(int location); - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/GenericUniform.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/GenericUniform.cs.meta deleted file mode 100644 index d139d72..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/GenericUniform.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: f6af09d6382461c4ab65e947b2f2fb2b \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/IntUniform.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/IntUniform.cs deleted file mode 100644 index b994f39..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/IntUniform.cs +++ /dev/null @@ -1,15 +0,0 @@ -using OpenTK.Graphics.OpenGL4; - -namespace StoicGoose.Common.OpenGL.Uniforms -{ - public sealed class IntUniform : GenericUniform - { - public IntUniform(string name) : this(name, 0) { } - public IntUniform(string name, int value) : base(name, value) { } - - protected override void SubmitUniform(int location) - { - GL.Uniform1(location, value); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/IntUniform.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/IntUniform.cs.meta deleted file mode 100644 index 569a9df..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/IntUniform.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: fef7b73ffc9a5004390704d47e96f3d4 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix2Uniform.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix2Uniform.cs deleted file mode 100644 index 9e49c22..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix2Uniform.cs +++ /dev/null @@ -1,16 +0,0 @@ -using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; - -namespace StoicGoose.Common.OpenGL.Uniforms -{ - public sealed class Matrix2Uniform : GenericUniform - { - public Matrix2Uniform(string name) : this(name, Matrix2.Identity) { } - public Matrix2Uniform(string name, Matrix2 value) : base(name, value) { } - - protected override void SubmitUniform(int location) - { - GL.UniformMatrix2(location, false, ref value); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix2Uniform.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix2Uniform.cs.meta deleted file mode 100644 index bdbb00b..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix2Uniform.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: d4f7ad547458c8d43ab14ab22118f93d \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix3Uniform.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix3Uniform.cs deleted file mode 100644 index 15dbb01..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix3Uniform.cs +++ /dev/null @@ -1,16 +0,0 @@ -using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; - -namespace StoicGoose.Common.OpenGL.Uniforms -{ - public sealed class Matrix3Uniform : GenericUniform - { - public Matrix3Uniform(string name) : this(name, Matrix3.Identity) { } - public Matrix3Uniform(string name, Matrix3 value) : base(name, value) { } - - protected override void SubmitUniform(int location) - { - GL.UniformMatrix3(location, false, ref value); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix3Uniform.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix3Uniform.cs.meta deleted file mode 100644 index c24fd37..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix3Uniform.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 92c5ec8dd24a17346ae45748b1a0178f \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix4Uniform.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix4Uniform.cs deleted file mode 100644 index 88e95da..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix4Uniform.cs +++ /dev/null @@ -1,16 +0,0 @@ -using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; - -namespace StoicGoose.Common.OpenGL.Uniforms -{ - public sealed class Matrix4Uniform : GenericUniform - { - public Matrix4Uniform(string name) : this(name, Matrix4.Identity) { } - public Matrix4Uniform(string name, Matrix4 value) : base(name, value) { } - - protected override void SubmitUniform(int location) - { - GL.UniformMatrix4(location, false, ref value); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix4Uniform.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix4Uniform.cs.meta deleted file mode 100644 index 4900392..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Matrix4Uniform.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 35f3ae40f4eab43439ede677f7faa3ec \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/UintUniform.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/UintUniform.cs deleted file mode 100644 index 97155d2..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/UintUniform.cs +++ /dev/null @@ -1,15 +0,0 @@ -using OpenTK.Graphics.OpenGL4; - -namespace StoicGoose.Common.OpenGL.Uniforms -{ - public sealed class UintUniform : GenericUniform - { - public UintUniform(string name) : this(name, 0) { } - public UintUniform(string name, uint value) : base(name, value) { } - - protected override void SubmitUniform(int location) - { - GL.Uniform1(location, value); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/UintUniform.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/UintUniform.cs.meta deleted file mode 100644 index d1fd030..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/UintUniform.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 7f8ad0c178d3da54590b050a192b3278 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector2Uniform.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector2Uniform.cs deleted file mode 100644 index 448837d..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector2Uniform.cs +++ /dev/null @@ -1,16 +0,0 @@ -using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; - -namespace StoicGoose.Common.OpenGL.Uniforms -{ - public sealed class Vector2Uniform : GenericUniform - { - public Vector2Uniform(string name) : this(name, Vector2.Zero) { } - public Vector2Uniform(string name, Vector2 value) : base(name, value) { } - - protected override void SubmitUniform(int location) - { - GL.Uniform2(location, value); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector2Uniform.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector2Uniform.cs.meta deleted file mode 100644 index 0b635e9..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector2Uniform.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 20ad22abc90ef954b8cce3348210bbb4 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector3Uniform.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector3Uniform.cs deleted file mode 100644 index 308c3ef..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector3Uniform.cs +++ /dev/null @@ -1,16 +0,0 @@ -using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; - -namespace StoicGoose.Common.OpenGL.Uniforms -{ - public sealed class Vector3Uniform : GenericUniform - { - public Vector3Uniform(string name) : this(name, Vector3.Zero) { } - public Vector3Uniform(string name, Vector3 value) : base(name, value) { } - - protected override void SubmitUniform(int location) - { - GL.Uniform3(location, value); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector3Uniform.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector3Uniform.cs.meta deleted file mode 100644 index a5a9791..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector3Uniform.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: fbb5a6d3f29b9a44da578e67ac4e4100 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector4Uniform.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector4Uniform.cs deleted file mode 100644 index 6c27b02..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector4Uniform.cs +++ /dev/null @@ -1,16 +0,0 @@ -using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; - -namespace StoicGoose.Common.OpenGL.Uniforms -{ - public sealed class Vector4Uniform : GenericUniform - { - public Vector4Uniform(string name) : this(name, Vector4.Zero) { } - public Vector4Uniform(string name, Vector4 value) : base(name, value) { } - - protected override void SubmitUniform(int location) - { - GL.Uniform4(location, value); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector4Uniform.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector4Uniform.cs.meta deleted file mode 100644 index f8e2fe6..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms/Vector4Uniform.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: bf80a2f2d6662894793579d648d7bdce \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices.meta deleted file mode 100644 index ef0f750..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 65357137316d75b4f871a534339a4892 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/IVertexStruct.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/IVertexStruct.cs deleted file mode 100644 index 5684a9e..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/IVertexStruct.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace StoicGoose.Common.OpenGL.Vertices -{ - public interface IVertexStruct { } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/IVertexStruct.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/IVertexStruct.cs.meta deleted file mode 100644 index 89b9413..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/IVertexStruct.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: d7f1ee3812c5583429ba5077b21aa114 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/Vertex.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/Vertex.cs deleted file mode 100644 index 4f093dc..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/Vertex.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Runtime.InteropServices; - -using OpenTK.Mathematics; - -namespace StoicGoose.Common.OpenGL.Vertices -{ - [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct Vertex : IVertexStruct - { - public Vector2 Position; - public Vector2 TexCoord; - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/Vertex.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/Vertex.cs.meta deleted file mode 100644 index a85049c..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/Vertex.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: b58b069763f795d42a28445d38bf14ca \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexArray.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexArray.cs deleted file mode 100644 index a0fb75b..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexArray.cs +++ /dev/null @@ -1,213 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.InteropServices; - -using OpenTK.Graphics.OpenGL4; -using OpenTK.Mathematics; - -namespace StoicGoose.Common.OpenGL.Vertices -{ - public sealed class VertexArray : IDisposable - { - static readonly Dictionary methodTypeIdentifier = new() - { - { typeof(sbyte), VertexAttribMethodType.Integer }, - { typeof(byte), VertexAttribMethodType.Integer }, - { typeof(short), VertexAttribMethodType.Integer }, - { typeof(ushort), VertexAttribMethodType.Integer }, - { typeof(int), VertexAttribMethodType.Integer }, - { typeof(uint), VertexAttribMethodType.Integer }, - { typeof(float), VertexAttribMethodType.Pointer }, - { typeof(double), VertexAttribMethodType.Pointer }, - { typeof(Color4), VertexAttribMethodType.Pointer }, - { typeof(Vector2), VertexAttribMethodType.Pointer }, - { typeof(Vector3), VertexAttribMethodType.Pointer }, - { typeof(Vector4), VertexAttribMethodType.Pointer }, - { typeof(Vector2d), VertexAttribMethodType.Pointer }, - { typeof(Vector3d), VertexAttribMethodType.Pointer }, - { typeof(Vector4d), VertexAttribMethodType.Pointer }, - { typeof(Vector2i), VertexAttribMethodType.Integer }, - { typeof(Vector3i), VertexAttribMethodType.Integer }, - { typeof(Vector4i), VertexAttribMethodType.Integer } - }; - - static readonly Dictionary pointerTypeTranslator = new() - { - { typeof(sbyte), VertexAttribPointerType.Byte }, - { typeof(byte), VertexAttribPointerType.UnsignedByte }, - { typeof(short), VertexAttribPointerType.Short }, - { typeof(ushort), VertexAttribPointerType.UnsignedShort }, - { typeof(int), VertexAttribPointerType.Int }, - { typeof(uint), VertexAttribPointerType.UnsignedInt }, - { typeof(float), VertexAttribPointerType.Float }, - { typeof(double), VertexAttribPointerType.Double }, - { typeof(Color4), VertexAttribPointerType.Float }, - { typeof(Vector2), VertexAttribPointerType.Float }, - { typeof(Vector3), VertexAttribPointerType.Float }, - { typeof(Vector4), VertexAttribPointerType.Float }, - { typeof(Vector2d), VertexAttribPointerType.Double }, - { typeof(Vector3d), VertexAttribPointerType.Double }, - { typeof(Vector4d), VertexAttribPointerType.Double }, - { typeof(Vector2i), VertexAttribPointerType.Int }, - { typeof(Vector3i), VertexAttribPointerType.Int }, - { typeof(Vector4i), VertexAttribPointerType.Int } - }; - - static readonly Dictionary integerTypeTranslator = new() - { - { typeof(sbyte), VertexAttribIntegerType.Byte }, - { typeof(byte), VertexAttribIntegerType.UnsignedByte }, - { typeof(short), VertexAttribIntegerType.Short }, - { typeof(ushort), VertexAttribIntegerType.UnsignedShort }, - { typeof(int), VertexAttribIntegerType.Int }, - { typeof(uint), VertexAttribIntegerType.UnsignedInt }, - { typeof(Vector2i), VertexAttribIntegerType.Int }, - { typeof(Vector3i), VertexAttribIntegerType.Int }, - { typeof(Vector4i), VertexAttribIntegerType.Int } - }; - - static readonly Dictionary drawElementsTypeTranslator = new() - { - { typeof(byte), DrawElementsType.UnsignedByte }, - { typeof(ushort), DrawElementsType.UnsignedShort }, - { typeof(uint), DrawElementsType.UnsignedInt } - }; - - enum VertexAttribMethodType { Pointer, Integer } - - internal readonly Buffer vertexBuffer = default, indexBuffer = default; - - internal readonly int handle = 0; - internal readonly VertexAttribute[] attributes = default; - - public int NumVertices => vertexBuffer.count; - public int NumIndices => indexBuffer != null ? indexBuffer.count : 0; - - public VertexArray(Buffer vtxBuffer) : this(vtxBuffer, null) { } - - public VertexArray(Buffer vtxBuffer, Buffer idxBuffer) - { - vertexBuffer = vtxBuffer; - indexBuffer = idxBuffer; - - handle = GL.GenVertexArray(); - attributes = DeconstructVertexLayout(vtxBuffer.dataType); - - GL.BindVertexArray(handle); - vertexBuffer.Bind(); - - for (var i = 0; i < attributes.Length; i++) - { - var attribute = attributes[i]; - - if (!methodTypeIdentifier.ContainsKey(attribute.Type)) continue; - - GL.EnableVertexAttribArray(i); - switch (methodTypeIdentifier[attribute.Type]) - { - case VertexAttribMethodType.Pointer: - GL.VertexAttribPointer(i, attribute.Size, GetVertexAttribPointerType(attribute.Type), false, vtxBuffer.sizeInBytes, new IntPtr(attribute.Offset)); - break; - case VertexAttribMethodType.Integer: - GL.VertexAttribIPointer(i, attribute.Size, GetVertexAttribIntegerType(attribute.Type), vtxBuffer.sizeInBytes, new IntPtr(attribute.Offset)); - break; - } - } - - indexBuffer?.Bind(); - - GL.BindVertexArray(0); - } - - ~VertexArray() - { - Dispose(); - } - - public void Dispose() - { - if (GL.IsVertexArray(handle)) - GL.DeleteVertexArray(handle); - - vertexBuffer?.Dispose(); - indexBuffer?.Dispose(); - - GC.SuppressFinalize(this); - } - - private static VertexAttribute[] DeconstructVertexLayout(Type vertexType) - { - var attributes = new List(); - - foreach (var field in vertexType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) - { - if (!field.FieldType.IsArray) - { - var fieldSize = Marshal.SizeOf(field.FieldType); - - if (field.FieldType.IsValueType && !field.FieldType.IsEnum) - { - var structFields = field.FieldType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - if (structFields == null || structFields.Length < 1 || structFields.Length > 4) throw new Exception("Invalid number of fields in struct"); - fieldSize = structFields.Length; - } - - attributes.Add(new VertexAttribute() - { - Type = field.FieldType, - Size = fieldSize, - Offset = Marshal.OffsetOf(vertexType, field.Name).ToInt32(), - Name = field.Name - }); - } - else - throw new NotImplementedException("GLSL arrays not implemented"); - } - - return attributes.ToArray(); - } - - private static VertexAttribPointerType GetVertexAttribPointerType(Type type) - { - if (pointerTypeTranslator.ContainsKey(type)) - return pointerTypeTranslator[type]; - else - throw new ArgumentException("Unimplemented or unsupported vertex attribute pointer type"); - } - - private static VertexAttribIntegerType GetVertexAttribIntegerType(Type type) - { - if (integerTypeTranslator.ContainsKey(type)) - return integerTypeTranslator[type]; - else - throw new ArgumentException("Unimplemented or unsupported vertex attribute integer type"); - } - - private static DrawElementsType GetDrawElementsType(Type type) - { - if (drawElementsTypeTranslator.ContainsKey(type)) - return drawElementsTypeTranslator[type]; - else - throw new ArgumentException("Unsupported draw elements type"); - } - - public void Draw(PrimitiveType primitiveType) - { - GL.BindVertexArray(handle); - - if (indexBuffer != null) - GL.DrawElements(primitiveType, indexBuffer.count, GetDrawElementsType(indexBuffer.dataType), 0); - else - GL.DrawArrays(primitiveType, 0, vertexBuffer.count); - } - - public void DrawIndices(PrimitiveType primitiveType, int offset, int count) - { - if (indexBuffer == null) throw new NotImplementedException("Cannot use DrawIndices without an indexbuffer"); - - GL.BindVertexArray(handle); - GL.DrawElements(primitiveType, count, GetDrawElementsType(indexBuffer.dataType), offset * indexBuffer.sizeInBytes); - } - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexArray.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexArray.cs.meta deleted file mode 100644 index 440291d..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexArray.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: c89413b44ed365f4f8abc8587da9ba94 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexAttribute.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexAttribute.cs deleted file mode 100644 index d4960c7..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace StoicGoose.Common.OpenGL.Vertices -{ - public sealed class VertexAttribute - { - public Type Type { get; internal set; } = default; - public int Size { get; internal set; } = -1; - public int Offset { get; internal set; } = -1; - public string Name { get; internal set; } = string.Empty; - } -} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexAttribute.cs.meta b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexAttribute.cs.meta deleted file mode 100644 index 7909bd8..0000000 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Vertices/VertexAttribute.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: 8d8f3e1419988e144b05f78cdc6c73b5 \ No newline at end of file diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/Utilities/Log.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/Utilities/Log.cs index 7e42f42..c88aea4 100644 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/Utilities/Log.cs +++ b/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/Utilities/Log.cs @@ -1,31 +1,33 @@ using System; using System.Collections.Generic; using System.IO; - -using Serilog; -using Serilog.Core; -using Serilog.Events; -using Serilog.Formatting; -using Serilog.Formatting.Display; - using StoicGoose.Common.Extensions; namespace StoicGoose.Common.Utilities { public enum LogSeverity { Verbose, Debug, Information, Warning, Error, Fatal } + public enum LogType { Debug, Warning, Error } - public static class Log + public interface IStoicGooseLogger + { + public void Log(LogType logtype, string message); + public void Debug(string message); + public void Warning(string message); + public void Err(string message); + } + + public static class Log { const string defaultTemplate = "{Message}{NewLine}{Exception}"; - readonly static Dictionary severityToEventLevelMapping = new() + readonly static Dictionary severityToEventLevelMapping = new() { - { LogSeverity.Verbose, LogEventLevel.Verbose }, - { LogSeverity.Debug, LogEventLevel.Debug }, - { LogSeverity.Information, LogEventLevel.Information }, - { LogSeverity.Warning, LogEventLevel.Warning }, - { LogSeverity.Error, LogEventLevel.Error }, - { LogSeverity.Fatal, LogEventLevel.Fatal } + { LogSeverity.Verbose, LogType.Debug }, + { LogSeverity.Debug, LogType.Debug }, + { LogSeverity.Information, LogType.Debug }, + { LogSeverity.Warning, LogType.Warning }, + { LogSeverity.Error, LogType.Error }, + { LogSeverity.Fatal, LogType.Error } }; readonly static Dictionary logSeverityAnsiColors = new() @@ -38,75 +40,51 @@ namespace StoicGoose.Common.Utilities { LogSeverity.Fatal, Ansi.Red } }; - static Logger mainLogger = default; - static Logger fileLogger = default; + static IStoicGooseLogger mainLogger; - public static string LogPath { get; private set; } = string.Empty; - - public static void Initialize(string logPath) + public static void Initialize(IStoicGooseLogger logger) { - if (File.Exists(logPath)) File.Delete(logPath); - - mainLogger = new LoggerConfiguration() - .MinimumLevel.Verbose() - .WriteTo.Console(outputTemplate: defaultTemplate) - .CreateLogger(); - - fileLogger = new LoggerConfiguration() - .MinimumLevel.Verbose() - .WriteTo.File(LogPath = logPath, restrictedToMinimumLevel: LogEventLevel.Verbose) - .CreateLogger(); + mainLogger = logger; } - public static void AttachTextWriter(TextWriter writer) - { - mainLogger = new LoggerConfiguration() - .MinimumLevel.Verbose() - .WriteTo.Sink(mainLogger) - .WriteTo.Sink(new TextWriterSink(writer, new MessageTemplateTextFormatter(defaultTemplate))) - .CreateLogger(); - } - public static void WriteLine(string message) => Write(LogEventLevel.Information, message); - public static void WriteFatal(string message) => Write(LogEventLevel.Fatal, message); + public static void WriteLine(string message) => mainLogger.Debug(message); + //public static void WriteFatal(string message) => Write(LogEventLevel.Fatal, message); - private static void Write(LogEventLevel logEventLevel, string message) - { - mainLogger?.Write(logEventLevel, message); - fileLogger?.Write(logEventLevel, message.RemoveAnsi()); - } + //private static void Write(LogEventLevel logEventLevel, string message) + //{ + // mainLogger?.Write(logEventLevel, message); + // fileLogger?.Write(logEventLevel, message.RemoveAnsi()); + //} public static void WriteEvent(LogSeverity severity, object source, string message) { - if (mainLogger == null && fileLogger == null) return; - - var eventLevel = severityToEventLevelMapping.ContainsKey(severity) ? severityToEventLevelMapping[severity] : LogEventLevel.Verbose; + var eventLevel = severityToEventLevelMapping.ContainsKey(severity) ? severityToEventLevelMapping[severity] : LogType.Debug; var logMessage = $"{logSeverityAnsiColors[severity]}[{source?.GetType().Name ?? string.Empty}]{Ansi.Reset}: {message}"; - mainLogger?.Write(eventLevel, logMessage); - fileLogger?.Write(eventLevel, logMessage.RemoveAnsi()); + mainLogger.Log(eventLevel, logMessage); } } - class TextWriterSink : ILogEventSink - { - readonly TextWriter textWriter = default; - readonly ITextFormatter textFormatter = default; + //class TextWriterSink : ILogEventSink + //{ + // readonly TextWriter textWriter = default; + // readonly ITextFormatter textFormatter = default; - readonly object syncRoot = new(); + // readonly object syncRoot = new(); - public TextWriterSink(TextWriter writer, ITextFormatter formatter) - { - textWriter = writer; - textFormatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); - } + // //public TextWriterSink(TextWriter writer, ITextFormatter formatter) + // //{ + // // textWriter = writer; + // // textFormatter = formatter ?? throw new ArgumentNullException(nameof(formatter)); + // //} - public void Emit(LogEvent logEvent) - { - lock (syncRoot) - { - textFormatter.Format(logEvent ?? throw new ArgumentNullException(nameof(logEvent)), textWriter); - textWriter.Flush(); - } - } - } + // public void Emit(LogEvent logEvent) + // { + // lock (syncRoot) + // { + // textFormatter.Format(logEvent ?? throw new ArgumentNullException(nameof(logEvent)), textWriter); + // textWriter.Flush(); + // } + // } + //} } diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Core/Interfaces/IMachine.cs b/Assets/Plugins/StoicGooseUnity/StoicGoose.Core/Interfaces/IMachine.cs index 0d724a4..9c60613 100644 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Core/Interfaces/IMachine.cs +++ b/Assets/Plugins/StoicGooseUnity/StoicGoose.Core/Interfaces/IMachine.cs @@ -11,11 +11,20 @@ using StoicGoose.Core.Sound; namespace StoicGoose.Core.Interfaces { + public interface IMachine { - static IEnumerable GetMachineTypes() => Assembly.GetAssembly(typeof(IMachine)).GetTypes().Where(x => !x.IsInterface && !x.IsAbstract && x.IsAssignableTo(typeof(IMachine))); + //static IEnumerable GetMachineTypes() => Assembly.GetAssembly(typeof(IMachine)).GetTypes().Where(x => !x.IsInterface && !x.IsAbstract && x.IsAssignableTo(typeof(IMachine))); + static IEnumerable GetMachineTypes() + { + return Assembly.GetAssembly(typeof(IMachine)) + .GetTypes() + .Where(x => !x.IsInterface && + !x.IsAbstract && + typeof(IMachine).IsAssignableFrom(x)); + } - string Manufacturer { get; } + string Manufacturer { get; } string Model { get; } int ScreenWidth { get; } diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders.meta b/Assets/Script.meta similarity index 77% rename from Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders.meta rename to Assets/Script.meta index a2270a9..4952c79 100644 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders.meta +++ b/Assets/Script.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d26ef25f71ffd7a44aee2c51ca6f86e2 +guid: 95c03a05d1f914a4e8d52e1d4e852d27 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles.meta b/Assets/Script/AppMain.meta similarity index 77% rename from Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles.meta rename to Assets/Script/AppMain.meta index 27f19ca..a9095e1 100644 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Shaders/Bundles.meta +++ b/Assets/Script/AppMain.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 3875a4162fb861b4eaa9afae91a79970 +guid: c710e077fe5cc1544ba2dd05c4972558 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms.meta b/Assets/Script/AppMain/Emulator.meta similarity index 77% rename from Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms.meta rename to Assets/Script/AppMain/Emulator.meta index fba094f..0977fd9 100644 --- a/Assets/Plugins/StoicGooseUnity/StoicGoose.Common/OpenGL/Uniforms.meta +++ b/Assets/Script/AppMain/Emulator.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: a45b95df3f0085f46bbfafbc4238c75e +guid: 3e0f65346834a04458adcab39a439a13 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Script/AppMain/Emulator/RingBuffer.cs b/Assets/Script/AppMain/Emulator/RingBuffer.cs new file mode 100644 index 0000000..ff3727c --- /dev/null +++ b/Assets/Script/AppMain/Emulator/RingBuffer.cs @@ -0,0 +1,72 @@ +using System.Threading; + +public class RingBuffer +{ + private readonly T[] buffer; + private readonly int capacity; + private int writePos; + private int readPos; + private int count; + + public RingBuffer(int capacity) + { + this.capacity = capacity; + this.buffer = new T[capacity]; + this.writePos = 0; + this.readPos = 0; + this.count = 0; + } + + public void Write(T item) + { + int localWritePos; + int localReadPos; + + do + { + localWritePos = Volatile.Read(ref writePos); + localReadPos = Volatile.Read(ref readPos); + + int nextWritePos = (localWritePos + 1) % capacity; + + if (nextWritePos == localReadPos) + { + // ɵδ + Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos); + } + } + while (Interlocked.CompareExchange(ref writePos, (localWritePos + 1) % capacity, localWritePos) != localWritePos); + + buffer[localWritePos] = item; + Interlocked.Increment(ref count); + } + + public bool TryRead(out T item) + { + item = default(T); + + int localReadPos; + int localWritePos; + + do + { + localReadPos = Volatile.Read(ref readPos); + localWritePos = Volatile.Read(ref writePos); + + if (localReadPos == localWritePos) + { + return false; // Ϊ + } + } + while (Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos) != localReadPos); + + item = buffer[localReadPos]; + Interlocked.Decrement(ref count); + return true; + } + + public int Available() + { + return Volatile.Read(ref count); + } +} diff --git a/Assets/Script/AppMain/Emulator/RingBuffer.cs.meta b/Assets/Script/AppMain/Emulator/RingBuffer.cs.meta new file mode 100644 index 0000000..2ac09e6 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/RingBuffer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e5cf9b14d4d67664b9b13beeefc68423 \ No newline at end of file diff --git a/Assets/Script/AppMain/Emulator/StoicGooseEmulator.meta b/Assets/Script/AppMain/Emulator/StoicGooseEmulator.meta new file mode 100644 index 0000000..8d46363 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseEmulator.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 218c1e917c9305445b77d6ee8c43c78f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Configuration.cs b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Configuration.cs new file mode 100644 index 0000000..d1e0e30 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Configuration.cs @@ -0,0 +1,90 @@ +using StoicGoose.Common.Utilities; +using System.Collections.Generic; +using System.ComponentModel; + + +public sealed class Configuration : ConfigurationBase +{ + [DisplayName("General")] + [Description("General settings.")] + public GeneralConfiguration General { get; set; } = new GeneralConfiguration(); + [DisplayName("Video")] + [Description("Settings related to video output.")] + public VideoConfiguration Video { get; set; } = new VideoConfiguration(); + [DisplayName("Sound")] + [Description("Settings related to sound output.")] + public SoundConfiguration Sound { get; set; } = new SoundConfiguration(); + [DisplayName("Input")] + [Description("Settings related to emulation input.")] + public InputConfiguration Input { get; set; } = new InputConfiguration(); +} + +public sealed class GeneralConfiguration : ConfigurationBase +{ + [DisplayName("Prefer Original WS")] + [Description("Prefer emulation of the original non-Color system.")] + public bool PreferOriginalWS { get; set; } = false; + [DisplayName("Use Bootstrap ROM")] + [Description("Toggle using WonderSwan bootstrap ROM images.")] + public bool UseBootstrap { get; set; } = false; + [DisplayName("WS Bootstrap ROM Path")] + [Description("Path to the WonderSwan bootstrap ROM image to use.")] + public string BootstrapFile { get; set; } = string.Empty; + [DisplayName("WSC Bootstrap ROM Path")] + [Description("Path to the WonderSwan Color bootstrap ROM image to use.")] + public string BootstrapFileWSC { get; set; } = string.Empty; + [DisplayName("Limit FPS")] + [Description("Toggle limiting the framerate to the system's native ~75.47 Hz.")] + public bool LimitFps { get; set; } = true; + [DisplayName("Enable Cheats")] + [Description("Toggle using the cheat system.")] + public bool EnableCheats { get; set; } = true; + [DisplayName("Recent Files")] + [Description("List of recently loaded files.")] + public List RecentFiles { get; set; } = new List(15); +} + +public sealed class VideoConfiguration : ConfigurationBase +{ + [DisplayName("Screen Size")] + [Description("Size of the emulated screen, in times original display resolution.")] + public int ScreenSize { get; set; } = 3; + [DisplayName("Shader")] + [Description("Currently selected shader.")] + public string Shader { get; set; } = string.Empty; + [DisplayName("Brightness")] + [Description("Adjust the brightness of the emulated screen, in percent.")] + [Range(-100, 100)] + public int Brightness { get; set; } = 0; + [DisplayName("Contrast")] + [Description("Adjust the contrast of the emulated screen, in percent.")] + [Range(0, 200)] + public int Contrast { get; set; } = 100; + [DisplayName("Saturation")] + [Description("Adjust the saturation of the emulated screen, in percent.")] + [Range(0, 200)] + public int Saturation { get; set; } = 100; +} + +public sealed class SoundConfiguration : ConfigurationBase +{ + [DisplayName("Mute")] + [Description("Toggles muting all sound output.")] + public bool Mute { get; set; } = false; + [DisplayName("Low-Pass Filter")] + [Description("Toggles low-pass filter for all sound output.")] + public bool LowPassFilter { get; set; } = true; +} + +public sealed class InputConfiguration : ConfigurationBase +{ + [DisplayName("Automatic Remapping")] + [Description("Automatically remap X-/Y-pads with game orientation.")] + public bool AutoRemap { get; set; } = true; + [DisplayName("Game Controls")] + [Description("Controls related to game input, i.e. X-/Y-pads, etc.")] + public Dictionary> GameControls { get; set; } = new Dictionary>(); + [DisplayName("System Controls")] + [Description("Controls related to hardware functions, i.e. volume button.")] + public Dictionary> SystemControls { get; set; } = new Dictionary>(); +} diff --git a/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Configuration.cs.meta b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Configuration.cs.meta new file mode 100644 index 0000000..e43254f --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Configuration.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: ee0a5e22651983e479915e5429079d99 \ No newline at end of file diff --git a/Assets/Script/AppMain/Emulator/StoicGooseEmulator/GlobalVariables.cs b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/GlobalVariables.cs new file mode 100644 index 0000000..e493c9b --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/GlobalVariables.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using System.Reflection; + + +public static class GlobalVariables +{ + public static readonly bool IsAuthorsMachine = System.Environment.MachineName == "KAMIKO"; +#if DEBUG + public static readonly bool IsDebugBuild = true; +#else + public static readonly bool IsDebugBuild = false; +#endif + public static readonly bool EnableLocalDebugIO = IsAuthorsMachine; + + public static readonly bool EnableSuperVerbosity = false; + public static readonly bool EnableOpenGLDebug = false; + + public static readonly bool EnableSkipBootstrapIfFound = false; + + public static string[] Dump() + { + var vars = new List(); + foreach (var fieldInfo in typeof(GlobalVariables).GetFields(BindingFlags.Static | BindingFlags.Public)) + vars.Add($"{fieldInfo.Name} == {fieldInfo.GetValue(null)}"); + return vars.ToArray(); + } +} diff --git a/Assets/Script/AppMain/Emulator/StoicGooseEmulator/GlobalVariables.cs.meta b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/GlobalVariables.cs.meta new file mode 100644 index 0000000..b35cc90 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/GlobalVariables.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 043ec2227e850204faefe0ce10f2ae04 \ No newline at end of file diff --git a/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle.meta b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle.meta new file mode 100644 index 0000000..e67f73d --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cb360a28c0621034ea0d310e18e5a747 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/DatabaseHandler.cs b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/DatabaseHandler.cs new file mode 100644 index 0000000..8a1933b --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/DatabaseHandler.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml; +using System.Xml.Serialization; + +using StoicGoose.Common.Utilities; + + +public sealed class DatabaseHandler +{ + readonly Dictionary datFiles = new(); + + public DatabaseHandler(string directory) + { + foreach (var file in Directory.EnumerateFiles(directory, "*.dat").OrderBy(x => x.Length)) + { + var root = new XmlRootAttribute("datafile") { IsNullable = true }; + var serializer = new XmlSerializer(typeof(DatFile), root); + using FileStream stream = new(Path.Combine(directory, file), FileMode.Open); + var reader = XmlReader.Create(stream, new() { DtdProcessing = DtdProcessing.Ignore }); + datFiles.Add(Path.GetFileName(file), (DatFile)serializer.Deserialize(reader)); + } + + Log.WriteEvent(LogSeverity.Information, this, $"Loaded {datFiles.Count} .dat file(s) with {datFiles.Sum(x => x.Value.Game.Length)} known game(s)."); + foreach (var datFile in datFiles.Select(x => x.Value)) + Log.WriteLine($" '{datFile.Header.Name} ({datFile.Header.Version})' from {datFile.Header.Homepage}"); + } + + private DatGame GetGame(uint romCrc32, int romSize) + { + return datFiles.Select(x => x.Value.Game).Select(x => x.FirstOrDefault(x => x.Rom.Any(y => y.Crc.ToLowerInvariant() == $"{romCrc32:x8}" && y.Size.ToLowerInvariant() == $"{romSize:D}"))).FirstOrDefault(x => x != null); + } + + public string GetGameTitle(uint romCrc32, int romSize) + { + return GetGame(romCrc32, romSize)?.Name.Replace("&", "&&") ?? "unrecognized game"; + } + + public class DatHeader + { + [XmlElement("name")] + public string Name { get; set; } + [XmlElement("description")] + public string Description { get; set; } + [XmlElement("category")] + public string Category { get; set; } + [XmlElement("version")] + public string Version { get; set; } + [XmlElement("date")] + public string Date { get; set; } + [XmlElement("author")] + public string Author { get; set; } + [XmlElement("email")] + public string Email { get; set; } + [XmlElement("homepage")] + public string Homepage { get; set; } + [XmlElement("url")] + public string Url { get; set; } + [XmlElement("comment")] + public string Comment { get; set; } + } + + public class DatRelease + { + [XmlAttribute("name")] + public string Name { get; set; } + [XmlAttribute("region")] + public string Region { get; set; } + [XmlAttribute("language")] + public string Language { get; set; } + [XmlAttribute("date")] + public string Date { get; set; } + [XmlAttribute("default")] + public string Default { get; set; } + } + + public class DatBiosSet + { + [XmlAttribute("name")] + public string Name { get; set; } + [XmlAttribute("description")] + public string Description { get; set; } + [XmlAttribute("default")] + public string Default { get; set; } + } + + public class DatRom + { + [XmlAttribute("name")] + public string Name { get; set; } + [XmlAttribute("size")] + public string Size { get; set; } + [XmlAttribute("crc")] + public string Crc { get; set; } + [XmlAttribute("sha1")] + public string Sha1 { get; set; } + [XmlAttribute("md5")] + public string Md5 { get; set; } + [XmlAttribute("merge")] + public string Merge { get; set; } + [XmlAttribute("status")] + public string Status { get; set; } + [XmlAttribute("date")] + public string Date { get; set; } + } + + public class DatDisk + { + [XmlAttribute("name")] + public string Name { get; set; } + [XmlAttribute("sha1")] + public string Sha1 { get; set; } + [XmlAttribute("md5")] + public string Md5 { get; set; } + [XmlAttribute("merge")] + public string Merge { get; set; } + [XmlAttribute("status")] + public string Status { get; set; } + } + + public class DatSample + { + [XmlAttribute("name")] + public string Name { get; set; } + } + + public class DatArchive + { + [XmlAttribute("name")] + public string Name { get; set; } + } + + public class DatGame + { + [XmlAttribute("name")] + public string Name { get; set; } + [XmlAttribute("sourcefile")] + public string SourceFile { get; set; } + [XmlAttribute("isbios")] + public string IsBios { get; set; } + [XmlAttribute("cloneof")] + public string CloneOf { get; set; } + [XmlAttribute("romof")] + public string RomOf { get; set; } + [XmlAttribute("sampleof")] + public string SampleOf { get; set; } + [XmlAttribute("board")] + public string Board { get; set; } + [XmlAttribute("rebuildto")] + public string RebuildTo { get; set; } + + [XmlElement("year")] + public string Year { get; set; } + [XmlElement("manufacturer")] + public string Manufacturer { get; set; } + + [XmlElement("release")] + public DatRelease[] Release { get; set; } + + [XmlElement("biosset")] + public DatBiosSet[] BiosSet { get; set; } + + [XmlElement("rom")] + public DatRom[] Rom { get; set; } + + [XmlElement("disk")] + public DatDisk[] Disk { get; set; } + + [XmlElement("sample")] + public DatSample[] Sample { get; set; } + + [XmlElement("archive")] + public DatArchive[] Archive { get; set; } + } + + [Serializable()] + public class DatFile + { + [XmlElement("header")] + public DatHeader Header { get; set; } + + [XmlElement("game")] + public DatGame[] Game { get; set; } + } +} diff --git a/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/DatabaseHandler.cs.meta b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/DatabaseHandler.cs.meta new file mode 100644 index 0000000..8dcc409 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/DatabaseHandler.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 28105de94482c1643b7398d0bbb32af2 \ No newline at end of file diff --git a/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/EmulatorHandler.cs b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/EmulatorHandler.cs new file mode 100644 index 0000000..72b320f --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/EmulatorHandler.cs @@ -0,0 +1,121 @@ +using StoicGoose.Core.Interfaces; +using System; +using System.Diagnostics; +using System.Threading; + +public class EmulatorHandler +{ + readonly static string threadName = $"Unity_Emulation"; + + Thread thread = default; + volatile bool threadRunning = false, threadPaused = false; + + volatile bool isResetRequested = false; + volatile bool isPauseRequested = false, newPauseState = false; + volatile bool isFpsLimiterChangeRequested = false, limitFps = true, newLimitFps = false; + + public bool IsRunning => threadRunning; + public bool IsPaused => threadPaused; + + public IMachine Machine { get; } = default; + + public EmulatorHandler(Type machineType) + { + Machine = Activator.CreateInstance(machineType) as IMachine; + Machine.Initialize(); + } + + public void Startup() + { + Machine.Reset(); + + threadRunning = true; + threadPaused = false; + + thread = new Thread(ThreadMainLoop) { Name = threadName, Priority = ThreadPriority.AboveNormal, IsBackground = false }; + thread.Start(); + } + + public void Reset() + { + isResetRequested = true; + } + + public void Pause() + { + isPauseRequested = true; + newPauseState = true; + } + + public void Unpause() + { + isPauseRequested = true; + newPauseState = false; + } + + public void Shutdown() + { + threadRunning = false; + threadPaused = false; + + thread?.Join(); + + Machine.Shutdown(); + } + + public void SetFpsLimiter(bool value) + { + isFpsLimiterChangeRequested = true; + newLimitFps = value; + } + + private void ThreadMainLoop() + { + var stopWatch = Stopwatch.StartNew(); + var interval = 1000.0 / Machine.RefreshRate; + var lastTime = 0.0; + + while (true) + { + if (!threadRunning) break; + + if (isResetRequested) + { + Machine.Reset(); + stopWatch.Restart(); + lastTime = 0.0; + + isResetRequested = false; + } + + if (isPauseRequested) + { + threadPaused = newPauseState; + isPauseRequested = false; + } + + if (isFpsLimiterChangeRequested) + { + limitFps = newLimitFps; + isFpsLimiterChangeRequested = false; + } + + if (!threadPaused) + { + if (limitFps) + { + while ((stopWatch.Elapsed.TotalMilliseconds - lastTime) < interval) + Thread.Sleep(0); + + lastTime += interval; + } + else + lastTime = stopWatch.Elapsed.TotalMilliseconds; + + Machine.RunFrame(); + } + else + lastTime = stopWatch.Elapsed.TotalMilliseconds; + } + } +} diff --git a/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/EmulatorHandler.cs.meta b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/EmulatorHandler.cs.meta new file mode 100644 index 0000000..4aa9582 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseEmulator/Handle/EmulatorHandler.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: da891d0a5babf7649992f83861f6f33d \ No newline at end of file diff --git a/Assets/Script/AppMain/Emulator/StoicGooseInterface.meta b/Assets/Script/AppMain/Emulator/StoicGooseInterface.meta new file mode 100644 index 0000000..e736b36 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseInterface.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8193f4d4ec66bb441b59f6549e95e013 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGKeyboard.cs b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGKeyboard.cs new file mode 100644 index 0000000..ab89199 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGKeyboard.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +public class SGKeyboard : MonoBehaviour +{ + internal void PollInput(ref List buttonsPressed, ref List buttonsHeld) + { + throw new NotImplementedException(); + } + + internal void SetVerticalOrientation(bool isVerticalOrientation) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGKeyboard.cs.meta b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGKeyboard.cs.meta new file mode 100644 index 0000000..6d44ae0 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGKeyboard.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 54c184e653057e64da4b9be96f4d876d \ No newline at end of file diff --git a/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGSoundPlayer.cs b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGSoundPlayer.cs new file mode 100644 index 0000000..b16597f --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGSoundPlayer.cs @@ -0,0 +1,328 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using UnityEngine; + +public class SGSoundPlayer : MonoBehaviour//, ISoundPlayer +{ + [SerializeField] + private AudioSource m_as; + private RingBuffer _buffer = new RingBuffer(44100 * 2); + private TimeSpan lastElapsed; + public double audioFPS { get; private set; } + public bool IsRecording { get; private set; } + + void Awake() + { + // ȡǰƵ + AudioConfiguration config = AudioSettings.GetConfiguration(); + + // ĿƵ + config.sampleRate = 44100; // Ϊ 44100Hz + config.numRealVoices = 32; // ƵԴѡ + config.numVirtualVoices = 512; // ƵԴѡ + config.dspBufferSize = 1024; // DSP Сѡ + config.speakerMode = AudioSpeakerMode.Stereo; // Ϊ2 + + // ӦµƵ + if (AudioSettings.Reset(config)) + { + Debug.Log("Audio settings updated successfully."); + Debug.Log("Sample Rate: " + config.sampleRate + "Hz"); + Debug.Log("Speaker Mode: " + config.speakerMode); + } + else + { + Debug.LogError("Failed to update audio settings."); + } + + } + + private Queue sampleQueue = new Queue(); + + + // Unity Ƶ̻߳ص + void OnAudioFilterRead(float[] data, int channels) + { + for (int i = 0; i < data.Length; i++) + { + if (_buffer.TryRead(out float rawData)) + data[i] = rawData; + else + data[i] = 0; // ʱ + } + } + + + public void Initialize() + { + if (!m_as.isPlaying) + { + m_as.Play(); + } + } + + public void StopPlay() + { + if (m_as.isPlaying) + { + m_as.Stop(); + } + } + + public void SubmitSamples(short[] buffer, short[][] ChannelSamples, int samples_a) + { + var current = UStoicGoose.sw.Elapsed; + var delta = current - lastElapsed; + lastElapsed = current; + audioFPS = 1d / delta.TotalSeconds; + + for (int i = 0; i < samples_a; i += 1) + { + _buffer.Write(buffer[i] / 32767.0f); + + } + if (IsRecording) + { + dataChunk.AddSampleData(buffer, samples_a); + waveHeader.FileLength += (uint)samples_a; + } + } + public void BufferWirte(int Off, byte[] Data) + { + } + + public void GetCurrentPosition(out int play_position, out int write_position) + { + play_position = 0; + write_position = 0; + } + + public void SetVolume(int Vol) + { + //TODO + if (m_as) + return; + m_as.volume = Vol; + } + + + void Update() + { + if (Input.GetKeyDown(KeyCode.F3)) + { + BeginRecording(); + Debug.Log("¼"); + } + if (Input.GetKeyDown(KeyCode.F4)) + { + SaveRecording("D:/1.wav"); + Debug.Log(""); + } + } + WaveHeader waveHeader; + FormatChunk formatChunk; + DataChunk dataChunk; + public void BeginRecording() + { + waveHeader = new WaveHeader(); + formatChunk = new FormatChunk(44100, 2); + dataChunk = new DataChunk(); + waveHeader.FileLength += formatChunk.Length(); + + IsRecording = true; + + } + + + public void SaveRecording(string filename) + { + using (FileStream file = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) + { + file.Write(waveHeader.GetBytes(), 0, (int)waveHeader.Length()); + file.Write(formatChunk.GetBytes(), 0, (int)formatChunk.Length()); + file.Write(dataChunk.GetBytes(), 0, (int)dataChunk.Length()); + } + + IsRecording = false; + + } + + internal void EnqueueSamples(short[] s) + { + throw new NotImplementedException(); + } + + internal void Unpause() + { + throw new NotImplementedException(); + } + + internal void Pause() + { + throw new NotImplementedException(); + } + + class WaveHeader + { + const string fileTypeId = "RIFF"; + const string mediaTypeId = "WAVE"; + + public string FileTypeId { get; private set; } + public uint FileLength { get; set; } + public string MediaTypeId { get; private set; } + + public WaveHeader() + { + FileTypeId = fileTypeId; + MediaTypeId = mediaTypeId; + FileLength = 4; /* Minimum size is always 4 bytes */ + } + + public byte[] GetBytes() + { + List chunkData = new List(); + + chunkData.AddRange(Encoding.ASCII.GetBytes(FileTypeId)); + chunkData.AddRange(BitConverter.GetBytes(FileLength)); + chunkData.AddRange(Encoding.ASCII.GetBytes(MediaTypeId)); + + return chunkData.ToArray(); + } + + public uint Length() + { + return (uint)GetBytes().Length; + } + } + + class FormatChunk + { + const string chunkId = "fmt "; + + ushort bitsPerSample, channels; + uint frequency; + + public string ChunkId { get; private set; } + public uint ChunkSize { get; private set; } + public ushort FormatTag { get; private set; } + + public ushort Channels + { + get { return channels; } + set { channels = value; RecalcBlockSizes(); } + } + + public uint Frequency + { + get { return frequency; } + set { frequency = value; RecalcBlockSizes(); } + } + + public uint AverageBytesPerSec { get; private set; } + public ushort BlockAlign { get; private set; } + + public ushort BitsPerSample + { + get { return bitsPerSample; } + set { bitsPerSample = value; RecalcBlockSizes(); } + } + + public FormatChunk() + { + ChunkId = chunkId; + ChunkSize = 16; + FormatTag = 1; /* MS PCM (Uncompressed wave file) */ + Channels = 2; /* Default to stereo */ + Frequency = 44100; /* Default to 44100hz */ + BitsPerSample = 16; /* Default to 16bits */ + RecalcBlockSizes(); + } + + public FormatChunk(int frequency, int channels) : this() + { + Channels = (ushort)channels; + Frequency = (ushort)frequency; + RecalcBlockSizes(); + } + + private void RecalcBlockSizes() + { + BlockAlign = (ushort)(channels * (bitsPerSample / 8)); + AverageBytesPerSec = frequency * BlockAlign; + } + + public byte[] GetBytes() + { + List chunkBytes = new List(); + + chunkBytes.AddRange(Encoding.ASCII.GetBytes(ChunkId)); + chunkBytes.AddRange(BitConverter.GetBytes(ChunkSize)); + chunkBytes.AddRange(BitConverter.GetBytes(FormatTag)); + chunkBytes.AddRange(BitConverter.GetBytes(Channels)); + chunkBytes.AddRange(BitConverter.GetBytes(Frequency)); + chunkBytes.AddRange(BitConverter.GetBytes(AverageBytesPerSec)); + chunkBytes.AddRange(BitConverter.GetBytes(BlockAlign)); + chunkBytes.AddRange(BitConverter.GetBytes(BitsPerSample)); + + return chunkBytes.ToArray(); + } + + public uint Length() + { + return (uint)GetBytes().Length; + } + } + + class DataChunk + { + const string chunkId = "data"; + + public string ChunkId { get; private set; } + public uint ChunkSize { get; set; } + public List WaveData { get; private set; } + + public DataChunk() + { + ChunkId = chunkId; + ChunkSize = 0; + WaveData = new List(); + } + + public byte[] GetBytes() + { + List chunkBytes = new List(); + + chunkBytes.AddRange(Encoding.ASCII.GetBytes(ChunkId)); + chunkBytes.AddRange(BitConverter.GetBytes(ChunkSize)); + byte[] bufferBytes = new byte[WaveData.Count * 2]; + Buffer.BlockCopy(WaveData.ToArray(), 0, bufferBytes, 0, bufferBytes.Length); + chunkBytes.AddRange(bufferBytes.ToList()); + + return chunkBytes.ToArray(); + } + + public uint Length() + { + return (uint)GetBytes().Length; + } + + public void AddSampleData(short[] stereoBuffer) + { + WaveData.AddRange(stereoBuffer); + + ChunkSize += (uint)(stereoBuffer.Length * 2); + } + //public unsafe void AddSampleData(short* stereoBuffer, int lenght) + //{ + // for (int i = 0; i < lenght; i++) + // { + // WaveData.Add(stereoBuffer[i]); + // } + + // ChunkSize += (uint)(lenght * 2); + //} + } +} diff --git a/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGSoundPlayer.cs.meta b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGSoundPlayer.cs.meta new file mode 100644 index 0000000..f4fa8e1 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGSoundPlayer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 925771571ae9709429297d42587ce36d \ No newline at end of file diff --git a/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGVideoPlayer.cs b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGVideoPlayer.cs new file mode 100644 index 0000000..8047959 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGVideoPlayer.cs @@ -0,0 +1,12 @@ +using System; +using UnityEngine; + +public class SGVideoPlayer : MonoBehaviour//, ISoundPlayer +{ + public bool IsVerticalOrientation { get; internal set; } + + internal void UpdateScreen(byte[] obj) + { + throw new NotImplementedException(); + } +} diff --git a/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGVideoPlayer.cs.meta b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGVideoPlayer.cs.meta new file mode 100644 index 0000000..519fd5e --- /dev/null +++ b/Assets/Script/AppMain/Emulator/StoicGooseInterface/SGVideoPlayer.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e8778828cf820b640b9d26ae977cdaba \ No newline at end of file diff --git a/Assets/Script/AppMain/Emulator/UStoicGoose.cs b/Assets/Script/AppMain/Emulator/UStoicGoose.cs new file mode 100644 index 0000000..56b2ca2 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/UStoicGoose.cs @@ -0,0 +1,577 @@ +using StoicGoose.Common.Extensions; +using StoicGoose.Common.Utilities; +using StoicGoose.Core.Machines; +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Linq; +using UnityEngine; +using CartridgeMetadata = StoicGoose.Core.Cartridges.Metadata; + +public class UStoicGoose : MonoBehaviour +{ + public static UStoicGoose instance; + public static System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew(); + void Awake() + { + instance = this; + Program.InitPath(Application.persistentDataPath); + Init(); + LoadAndRunCartridge(""); + } + + private void OnDestroy() + { + EmuClose(); + } + + /* Constants */ + readonly static int maxScreenSizeFactor = 5; + readonly static int maxRecentFiles = 15; + readonly static int statusIconSize = 12; + + readonly static List<(string description, string extension, Func streamReadFunc)> supportedFileInformation = new() + { + ("WonderSwan ROMs", ".ws", GetStreamFromFile), + ("WonderSwan Color ROMs", ".wsc", GetStreamFromFile), + ("Zip Archives", ".zip", GetStreamFromFirstZippedFile) + }; + + /* Various handlers */ + DatabaseHandler databaseHandler = default; + SGVideoPlayer graphicsHandler = default; + SGSoundPlayer soundHandler = default; + SGKeyboard inputHandler = default; + EmulatorHandler emulatorHandler = default; + + /* Misc. windows */ + //SoundRecorderForm soundRecorderForm = default; + //CheatsForm cheatsForm = default; + + /* Misc. runtime variables */ + Type machineType = default; + bool isVerticalOrientation = false; + string internalEepromPath = string.Empty; + //Cheat[] cheats = default; + + + private void Init() + { + Log.WriteEvent(LogSeverity.Information, this, "Initializing emulator and UI..."); + + machineType = Program.Configuration.General.PreferOriginalWS ? typeof(WonderSwan) : typeof(WonderSwanColor); + + InitializeEmulatorHandler(); + VerifyConfiguration(); + InitializeOtherHandlers(); + //InitializeWindows(); + + SizeAndPositionWindow(); + SetWindowTitleAndStatus(); + Log.WriteEvent(LogSeverity.Information, this, "Initialization done!"); + } + + + private void EmuClose() + { + SaveAllData(); + emulatorHandler.Shutdown(); + + Program.SaveConfiguration(); + } + + + private void InitializeEmulatorHandler() + { + emulatorHandler = new EmulatorHandler(machineType); + emulatorHandler.SetFpsLimiter(Program.Configuration.General.LimitFps); + } + + private void VerifyConfiguration() + { + foreach (var button in emulatorHandler.Machine.GameControls.Replace(" ", "").Split(',')) + { + if (!Program.Configuration.Input.GameControls.ContainsKey(button)) + Program.Configuration.Input.GameControls[button] = new(); + } + + foreach (var button in emulatorHandler.Machine.HardwareControls.Replace(" ", "").Split(',')) + { + if (!Program.Configuration.Input.SystemControls.ContainsKey(button)) + Program.Configuration.Input.SystemControls[button] = new(); + } + + if (Program.Configuration.Video.ScreenSize < 2 || Program.Configuration.Video.ScreenSize > maxScreenSizeFactor) + Program.Configuration.Video.ResetToDefault(nameof(Program.Configuration.Video.ScreenSize)); + + //if (string.IsNullOrEmpty(Program.Configuration.Video.Shader) || (graphicsHandler != null && !graphicsHandler.AvailableShaders.Contains(Program.Configuration.Video.Shader))) + // Program.Configuration.Video.Shader = GraphicsHandler.DefaultShaderName; + } + + private void InitializeOtherHandlers() + { + databaseHandler = new DatabaseHandler(Program.NoIntroDatPath); + + //statusIconsLocation = machineType == typeof(WonderSwan) ? new(0, DisplayControllerCommon.ScreenHeight) : new(DisplayControllerCommon.ScreenWidth, 0); + graphicsHandler = this.gameObject.GetComponent(); + //TODO graphicsHandler基本参数,可能需要补上 + //graphicsHandler = new GraphicsHandler(machineType, new(emulatorHandler.Machine.ScreenWidth, emulatorHandler.Machine.ScreenHeight), statusIconsLocation, statusIconSize, machineType != typeof(WonderSwan), Program.Configuration.Video.Shader) + //{ + // IsVerticalOrientation = isVerticalOrientation + //}; + + soundHandler = this.gameObject.GetComponent(); + //TODO 声音基本参数,可能需要补上 + //soundHandler = new SoundHandler(44100, 2); + //soundHandler.SetVolume(1.0f); + //soundHandler.SetMute(Program.Configuration.Sound.Mute); + //soundHandler.SetLowPassFilter(Program.Configuration.Sound.LowPassFilter); + + inputHandler = this.gameObject.GetComponent(); + + //TODO Input基本参数,可能需要补上 + //inputHandler = new InputHandler(renderControl); + //inputHandler.SetKeyMapping(Program.Configuration.Input.GameControls, Program.Configuration.Input.SystemControls); + //inputHandler.SetVerticalOrientation(isVerticalOrientation); + //inputHandler.SetEnableRemapping(Program.Configuration.Input.AutoRemap); + //inputHandler.SetVerticalRemapping(emulatorHandler.Machine.VerticalControlRemap + // .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) + // .Select(x => x.Split('=', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)) + // .ToDictionary(x => x[0], x => x[1])); + + emulatorHandler.Machine.DisplayController.SendFramebuffer = graphicsHandler.UpdateScreen; + emulatorHandler.Machine.SoundController.SendSamples = (s) => + { + soundHandler.EnqueueSamples(s); + //soundRecorderForm.EnqueueSamples(s); + }; + + emulatorHandler.Machine.ReceiveInput += () => + { + var buttonsPressed = new List(); + var buttonsHeld = new List(); + + inputHandler.PollInput(ref buttonsPressed, ref buttonsHeld); + + if (buttonsPressed.Contains("Volume")) + emulatorHandler.Machine.SoundController.ChangeMasterVolume(); + + return (buttonsPressed, buttonsHeld); + }; + + //renderControl.Resize += (s, e) => { if (s is Control control) graphicsHandler.Resize(control.ClientRectangle); }; + //renderControl.Paint += (s, e) => + //{ + // graphicsHandler.SetClearColor(Color.Black); + + // graphicsHandler.ClearFrame(); + + // if (emulatorHandler.Machine is MachineCommon machine) + // { + // var activeIcons = new List() { "Power" }; + + // if (machine.BuiltInSelfTestOk) activeIcons.Add("Initialized"); + + // if (machine.DisplayController.IconSleep) activeIcons.Add("Sleep"); + // if (machine.DisplayController.IconVertical) activeIcons.Add("Vertical"); + // if (machine.DisplayController.IconHorizontal) activeIcons.Add("Horizontal"); + // if (machine.DisplayController.IconAux1) activeIcons.Add("Aux1"); + // if (machine.DisplayController.IconAux2) activeIcons.Add("Aux2"); + // if (machine.DisplayController.IconAux3) activeIcons.Add("Aux3"); + + // if (machine.SoundController.HeadphonesConnected) activeIcons.Add("Headphones"); + // if (machine.SoundController.MasterVolume == 0) activeIcons.Add("Volume0"); + // if (machine.SoundController.MasterVolume == 1) activeIcons.Add("Volume1"); + // if (machine.SoundController.MasterVolume == 2) activeIcons.Add("Volume2"); + // if (machine.SoundController.MasterVolume == 3 && machine is WonderSwanColor) activeIcons.Add("Volume3"); + + // graphicsHandler.UpdateStatusIcons(activeIcons); + // } + // graphicsHandler.DrawFrame(); + //}; + + internalEepromPath = Path.Combine(Program.InternalDataPath, $"{machineType.Name}.eep"); + } + + //private void InitializeWindows() + //{ + // soundRecorderForm = new(soundHandler.SampleRate, soundHandler.NumChannels); + // cheatsForm = new() + // { + // Callback = (c) => + // { + // if (emulatorHandler.IsRunning) + // cheats = (Cheat[])c.Clone(); + // } + // }; + //} + + private void SizeAndPositionWindow() + { + //if (WindowState == FormWindowState.Maximized) + // WindowState = FormWindowState.Normal; + + //MinimumSize = SizeFromClientSize(CalculateRequiredClientSize(2)); + //Size = SizeFromClientSize(CalculateRequiredClientSize(Program.Configuration.Video.ScreenSize)); + + //var screen = Screen.FromControl(this); + //var workingArea = screen.WorkingArea; + //Location = new Point() + //{ + // X = Math.Max(workingArea.X, workingArea.X + (workingArea.Width - Width) / 2), + // Y = Math.Max(workingArea.Y, workingArea.Y + (workingArea.Height - Height) / 2) + //}; + } + + //TODO 设置屏幕宽高 看是否需要 + //private Size CalculateRequiredClientSize(int screenSize) + //{ + // if (emulatorHandler == null || graphicsHandler == null) + // return ClientSize; + + // var statusIconsOnRight = statusIconsLocation.X > statusIconsLocation.Y; + + // int screenWidth, screenHeight; + + // if (!isVerticalOrientation) + // { + // screenWidth = emulatorHandler.Machine.ScreenWidth; + // screenHeight = emulatorHandler.Machine.ScreenHeight; + // if (statusIconsOnRight) screenWidth += statusIconSize; + // if (!statusIconsOnRight) screenHeight += statusIconSize; + // } + // else + // { + // screenWidth = emulatorHandler.Machine.ScreenHeight; + // screenHeight = emulatorHandler.Machine.ScreenWidth; + // if (!statusIconsOnRight) screenWidth += statusIconSize; + // if (statusIconsOnRight) screenHeight += statusIconSize; + // } + + // return new(screenWidth * screenSize, (screenHeight * screenSize) + menuStrip.Height + statusStrip.Height); + //} + + private void SetWindowTitleAndStatus() + { + //TODO 修改为状态字符串,显示在某个地方 + + //var titleStringBuilder = new StringBuilder(); + + //titleStringBuilder.Append($"{Application.ProductName} {Program.GetVersionString(false)}"); + + //if (emulatorHandler.Machine.Cartridge.IsLoaded) + //{ + // titleStringBuilder.Append($" - [{Path.GetFileName(Program.Configuration.General.RecentFiles.First())}]"); + + // var statusStringBuilder = new StringBuilder(); + // statusStringBuilder.Append($"Emulating {emulatorHandler.Machine.Manufacturer} {emulatorHandler.Machine.Model}, "); + // statusStringBuilder.Append($"playing {databaseHandler.GetGameTitle(emulatorHandler.Machine.Cartridge.Crc32, emulatorHandler.Machine.Cartridge.SizeInBytes)} ({emulatorHandler.Machine.Cartridge.Metadata.GameIdString})"); + + // tsslStatus.Text = statusStringBuilder.ToString(); + // tsslEmulationStatus.Text = emulatorHandler.IsRunning ? (emulatorHandler.IsPaused ? "Paused" : "Running") : "Stopped"; + //} + //else + //{ + // tsslStatus.Text = "Ready"; + // tsslEmulationStatus.Text = "Stopped"; + //} + + //Text = titleStringBuilder.ToString(); + } + + private void LoadBootstrap(string filename) + { + if (GlobalVariables.EnableSkipBootstrapIfFound) return; + + if (!emulatorHandler.IsRunning) + { + if (File.Exists(filename)) + { + using var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + var data = new byte[stream.Length]; + stream.Read(data, 0, data.Length); + emulatorHandler.Machine.LoadBootstrap(data); + } + emulatorHandler.Machine.UseBootstrap = Program.Configuration.General.UseBootstrap; + } + } + + private void LoadInternalEeprom() + { + if (!emulatorHandler.IsRunning && File.Exists(internalEepromPath)) + { + using var stream = new FileStream(internalEepromPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + var data = new byte[stream.Length]; + stream.Read(data, 0, data.Length); + emulatorHandler.Machine.LoadInternalEeprom(data); + } + } + + private static Stream GetStreamFromFile(string filename) + { + return new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + } + + private static Stream GetStreamFromFirstZippedFile(string filename) + { + return new ZipArchive(new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)).Entries.FirstOrDefault()?.Open(); + } + + private void LoadAndRunCartridge(string filename) + { + if (emulatorHandler.IsRunning) + { + SaveAllData(); + emulatorHandler.Shutdown(); + } + + using var inputStream = supportedFileInformation.FirstOrDefault(x => x.extension == Path.GetExtension(filename)).streamReadFunc(filename) ?? GetStreamFromFile(filename); + using var stream = new MemoryStream(); + inputStream.CopyTo(stream); + stream.Position = 0; + + var data = new byte[stream.Length]; + stream.Read(data, 0, data.Length); + emulatorHandler.Machine.LoadRom(data); + + graphicsHandler.IsVerticalOrientation = isVerticalOrientation = emulatorHandler.Machine.Cartridge.Metadata.Orientation == CartridgeMetadata.Orientations.Vertical; + inputHandler.SetVerticalOrientation(isVerticalOrientation); + + LoadRam(); + + LoadBootstrap(emulatorHandler.Machine is WonderSwan ? Program.Configuration.General.BootstrapFile : Program.Configuration.General.BootstrapFileWSC); + LoadInternalEeprom(); + + emulatorHandler.Startup(); + + SizeAndPositionWindow(); + SetWindowTitleAndStatus(); + + Program.SaveConfiguration(); + } + + private void LoadRam() + { + var path = Path.Combine(Program.SaveDataPath, $"{Path.GetFileNameWithoutExtension(Program.Configuration.General.RecentFiles.First())}.sav"); + if (!File.Exists(path)) return; + + using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + var data = new byte[stream.Length]; + stream.Read(data, 0, data.Length); + if (data.Length != 0) + emulatorHandler.Machine.LoadSaveData(data); + } + + private void SaveAllData() + { + SaveInternalEeprom(); + SaveRam(); + } + + private void SaveInternalEeprom() + { + var data = emulatorHandler.Machine.GetInternalEeprom(); + if (data.Length == 0) return; + + using var stream = new FileStream(internalEepromPath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); + stream.Write(data, 0, data.Length); + } + + private void SaveRam() + { + var data = emulatorHandler.Machine.GetSaveData(); + if (data.Length == 0) return; + + var path = Path.Combine(Program.SaveDataPath, $"{Path.GetFileNameWithoutExtension(Program.Configuration.General.RecentFiles.First())}.sav"); + + using var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite); + stream.Write(data, 0, data.Length); + } + + + private void PauseEmulation() + { + if (!emulatorHandler.IsRunning) return; + + emulatorHandler.Pause(); + soundHandler.Pause(); + + SetWindowTitleAndStatus(); + } + + private void UnpauseEmulation() + { + if (!emulatorHandler.IsRunning) return; + + emulatorHandler.Unpause(); + soundHandler.Unpause(); + + SetWindowTitleAndStatus(); + } + + private void ResetEmulation() + { + SaveAllData(); + emulatorHandler.Reset(); + + Program.SaveConfiguration(); + } + +} + +static class Program +{ + static string jsonConfigFileName;//= "Config.json"; + static string logFileName;//= "Log.txt"; + static string internalDataDirectoryName;//= "Internal"; + static string saveDataDirectoryName;//= "Saves"; + static string cheatDataDirectoryName;//= "Cheats"; + static string debuggingDataDirectoryName;//= "Debugging"; + static string assetsDirectoryName;//= "Assets"; + static string shaderDirectoryName;//= "Shaders"; + static string noIntroDatDirectoryName;//= "No-Intro"; + static string mutexName;//= $"Unity_{GetVersionDetails()}"; + static string programDataDirectory;//= Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Application.ProductName); + static string programConfigPath;//= Path.Combine(programDataDirectory, jsonConfigFileName); + + public static Configuration Configuration { get; private set; } = LoadConfiguration(programConfigPath); + + public static string DataPath;//{ get; } = string.Empty; + public static string InternalDataPath;//{ get; } = string.Empty; + public static string SaveDataPath;//{ get; } = string.Empty; + public static string CheatsDataPath;//{ get; } = string.Empty; + public static string DebuggingDataPath;//{ get; } = string.Empty; + + readonly static string programApplicationDirectory = AppDomain.CurrentDomain.BaseDirectory; + readonly static string programAssetsDirectory = Path.Combine(programApplicationDirectory, assetsDirectoryName); + + //public static string ShaderPath { get; } = string.Empty; + public static string NoIntroDatPath;// { get; } = string.Empty; + + //static MainForm mainForm = default; + + public static void InitPath(string CustonDataDir) + { + try + { + + jsonConfigFileName = "Config.json"; + logFileName = "Log.txt"; + internalDataDirectoryName = "Internal"; + saveDataDirectoryName = "Saves"; + cheatDataDirectoryName = "Cheats"; + debuggingDataDirectoryName = "Debugging"; + assetsDirectoryName = "Assets"; + shaderDirectoryName = "Shaders"; + noIntroDatDirectoryName = "No-Intro"; + mutexName = $"Unity_{GetVersionDetails()}"; + programDataDirectory = Path.Combine(CustonDataDir, "AxibugEmu"); + programConfigPath = Path.Combine(programDataDirectory, jsonConfigFileName); + + Log.WriteLine(Path.Combine(programDataDirectory, logFileName)); + + Directory.CreateDirectory(DataPath = programDataDirectory); + Directory.CreateDirectory(InternalDataPath = Path.Combine(programDataDirectory, internalDataDirectoryName)); + Directory.CreateDirectory(SaveDataPath = Path.Combine(programDataDirectory, saveDataDirectoryName)); + Directory.CreateDirectory(CheatsDataPath = Path.Combine(programDataDirectory, cheatDataDirectoryName)); + Directory.CreateDirectory(DebuggingDataPath = Path.Combine(programDataDirectory, debuggingDataDirectoryName)); + + //if (!Directory.Exists(ShaderPath = Path.Combine(programAssetsDirectory, shaderDirectoryName))) + // throw new DirectoryNotFoundException("Shader directory missing"); + + if (!Directory.Exists(NoIntroDatPath = Path.Combine(programAssetsDirectory, noIntroDatDirectoryName))) + throw new DirectoryNotFoundException("No-Intro .dat directory missing"); + } + catch (DirectoryNotFoundException e) + { + } + } + + //[STAThread] + //static void Main() + //{ + // using var mutex = new Mutex(true, mutexName, out bool newInstance); + // if (!newInstance) + // { + // MessageBox.Show($"Another instance of {Application.ProductName} is already running.\n\nThis instance will now shut down.", + // $"{Application.ProductName} Startup Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + // Environment.Exit(-1); + // } + + // Application.SetHighDpiMode(HighDpiMode.SystemAware); + // Application.EnableVisualStyles(); + // Application.SetCompatibleTextRenderingDefault(false); + + // if (!Debugger.IsAttached) + // { + // Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); + // Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); + // AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); + // } + + // Application.Run(mainForm = new MainForm()); + //} + + //static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) + //{ + // if (e.Exception is GLFWException glEx) + // { + // var renderControl = mainForm.Controls["renderControl"] as OpenGL.RenderControl; + // MessageBox.Show($"{glEx.Message.EnsureEndsWithPeriod()}\n\n{Application.ProductName} requires GPU and drivers supporting OpenGL {renderControl.APIVersion.Major}.{renderControl.APIVersion.Minor}.", $"{Application.ProductName} Startup Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + // } + // else + // { + // MessageBox.Show(e.Exception.Message.EnsureEndsWithPeriod(), $"{Application.ProductName} Startup Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + // } + + // Environment.Exit(-1); + //} + + //static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + //{ + // MessageBox.Show((e.ExceptionObject as Exception).Message, $"{Application.ProductName} Startup Error"); + // Environment.Exit(-1); + //} + + private static Configuration LoadConfiguration(string filename) + { + Directory.CreateDirectory(Path.GetDirectoryName(filename)); + + Configuration configuration; + if (!File.Exists(filename) || (configuration = filename.DeserializeFromFile()) == null) + { + configuration = new Configuration(); + configuration.SerializeToFile(filename); + } + + return configuration; + } + + public static void ReplaceConfiguration(Configuration newConfig) + { + ConfigurationBase.CopyConfiguration(newConfig, Configuration); + SaveConfiguration(); + } + + public static void SaveConfiguration() + { + Configuration?.SerializeToFile(programConfigPath); + } + + private static string GetVersionDetails() + { + //return $"{ThisAssembly.Git.Branch}-{ThisAssembly.Git.Commit}{(ThisAssembly.Git.IsDirty ? "-dirty" : string.Empty)}{(GlobalVariables.IsDebugBuild ? "+debug" : string.Empty)}"; + return $"{(GlobalVariables.IsDebugBuild ? "+debug" : string.Empty)}"; + } + + //public static string GetVersionString(bool detailed) + //{ + // var version = new Version(Application.ProductVersion); + // var stringBuilder = new StringBuilder(); + // stringBuilder.Append($"v{version.Major:D3}{(version.Minor != 0 ? $".{version.Minor}" : string.Empty)}"); + // if (detailed) stringBuilder.Append($" ({GetVersionDetails()})"); + // return stringBuilder.ToString(); + //} +} + diff --git a/Assets/Script/AppMain/Emulator/UStoicGoose.cs.meta b/Assets/Script/AppMain/Emulator/UStoicGoose.cs.meta new file mode 100644 index 0000000..4d5d949 --- /dev/null +++ b/Assets/Script/AppMain/Emulator/UStoicGoose.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: b7e1a8282bc4d764c81f63e62fd7aec8 \ No newline at end of file