diff --git a/Capy64/.editorconfig b/Capy64/.editorconfig index 05f18fb..be3a6e8 100644 --- a/Capy64/.editorconfig +++ b/Capy64/.editorconfig @@ -1,6 +1,6 @@ [*.{cs,vb,lua}] #### Top of file license comment -file_header_template = This file is part of Capy64 - https://github.com/Capy64/Capy64\nCopyright 2023 Alessandro "AlexDevs" Proto\n\nLicensed under the Apache License, Version 2.0 (the "License").\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an "AS IS" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License. +file_header_template = This file is part of Capy64 - https://github.com/Ale32bit/Capy64\nCopyright 2023 Alessandro "AlexDevs" Proto\n\nLicensed under the Apache License, Version 2.0 (the "License").\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an "AS IS" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License. [*.cs] #### Stili di denominazione #### diff --git a/Capy64/API/IPlugin.cs b/Capy64/API/IComponent.cs similarity index 88% rename from Capy64/API/IPlugin.cs rename to Capy64/API/IComponent.cs index f2fceef..ab21111 100644 --- a/Capy64/API/IPlugin.cs +++ b/Capy64/API/IComponent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -18,7 +18,7 @@ using Microsoft.Extensions.DependencyInjection; namespace Capy64.API; -public interface IPlugin +public interface IComponent { void ConfigureServices(IServiceCollection services) { } void LuaInit(Lua L) { } diff --git a/Capy64/Assets/bios.lua b/Capy64/Assets/bios.lua index cfd81c3..69b421c 100644 --- a/Capy64/Assets/bios.lua +++ b/Capy64/Assets/bios.lua @@ -23,8 +23,8 @@ local http = require("http") local event = require("event") -local INDEX_URL = "https://raw.github.com/Capy64/CapyOS/deploy/index.json" -local JSON_URL = "https://raw.github.com/Capy64/CapyOS/main/lib/json.lua" +local INDEX_URL = "https://raw.github.com/Ale32bit/CapyOS/deploy/index.json" +local JSON_URL = "https://raw.github.com/Ale32bit/CapyOS/main/lib/json.lua" local bootSleep = 2000 local bg = 0x0 @@ -264,4 +264,4 @@ end bootScreen() -term.clear() \ No newline at end of file +term.clear() diff --git a/Capy64/Capy64.cs b/Capy64/Capy64.cs index 986d881..6a26dcf 100644 --- a/Capy64/Capy64.cs +++ b/Capy64/Capy64.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -17,8 +17,9 @@ using Capy64.API; using Capy64.Core; using Capy64.Eventing; using Capy64.Extensions; -using Capy64.Runtime; +using Capy64.Integrations; using Capy64.PluginManager; +using Capy64.Runtime; using Microsoft.Extensions.DependencyInjection; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -27,7 +28,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using static Capy64.Utils; -using Capy64.Integrations; namespace Capy64; @@ -41,8 +41,8 @@ public class Capy64 : Game, IGame "Capy64"); public static Capy64 Instance { get; private set; } public Capy64 Game => this; - public IList NativePlugins { get; private set; } - public IList Plugins { get; private set; } + public IList NativePlugins { get; private set; } + public IList Plugins { get; private set; } public int Width { get; set; } = 400; public int Height { get; set; } = 300; public float Scale { get; set; } = 2f; @@ -121,8 +121,8 @@ public class Capy64 : Game, IGame if (Window.IsMaximized()) { - var vertical = bounds.Height - Height * Scale; - var horizontal = bounds.Width - Width * Scale; + var vertical = bounds.Height - (Height * Scale); + var horizontal = bounds.Width - (Width * Scale); Borders.Top = (int)Math.Floor(vertical / 2d); Borders.Bottom = (int)Math.Ceiling(vertical / 2d); @@ -159,18 +159,18 @@ public class Capy64 : Game, IGame base.Initialize(); } - private List GetNativePlugins() + private List GetNativePlugins() { - var iType = typeof(IPlugin); + var iType = typeof(IComponent); var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(p => iType.IsAssignableFrom(p) && !p.IsInterface); - var plugins = new List(); + var plugins = new List(); foreach (var type in types) { - var instance = (IPlugin)ActivatorUtilities.CreateInstance(_serviceProvider, type)!; + var instance = (IComponent)ActivatorUtilities.CreateInstance(_serviceProvider, type)!; plugins.Add(instance); } return plugins; diff --git a/Capy64/Capy64.csproj b/Capy64/Capy64.csproj index 50f7ebb..7632668 100644 --- a/Capy64/Capy64.csproj +++ b/Capy64/Capy64.csproj @@ -35,7 +35,6 @@ True \ - diff --git a/Capy64/Core/Audio.cs b/Capy64/Core/Audio.cs index 10c358a..1fd4bee 100644 --- a/Capy64/Core/Audio.cs +++ b/Capy64/Core/Audio.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -14,16 +14,7 @@ // limitations under the License. using Microsoft.Xna.Framework.Audio; -using Microsoft.Xna.Framework.Graphics; using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; namespace Capy64.Core; @@ -38,25 +29,111 @@ public class Audio : IDisposable Noise } - public const int SampleRate = 48000; - public const AudioChannels Channels = AudioChannels.Mono; - public readonly DynamicSoundEffectInstance Sound; + public const int SampleRate = 16000; + public const int HQSampleRate = 48000; + public const AudioChannels AudioChannel = AudioChannels.Mono; + public const int ChannelsCount = 5; + public readonly DynamicSoundEffectInstance[] Channels = new DynamicSoundEffectInstance[ChannelsCount]; + private bool[] freeChannels = new bool[ChannelsCount]; + + public readonly DynamicSoundEffectInstance HQChannel = new(HQSampleRate, AudioChannel); private static readonly Random rng = new(); public Audio() { - Sound = new DynamicSoundEffectInstance(SampleRate, Channels); + for (int i = 0; i < ChannelsCount; i++) + { + Channels[i] = new DynamicSoundEffectInstance(SampleRate, AudioChannel); + freeChannels[i] = true; + Channels[i].BufferNeeded += Audio_BufferNeeded; + } + + HQChannel.BufferNeeded += HQChannel_BufferNeeded; } - public TimeSpan Submit(byte[] buffer) + private void HQChannel_BufferNeeded(object sender, EventArgs e) { - Sound.SubmitBuffer(buffer); - return Sound.GetSampleDuration(buffer.Length); + var pending = HQChannel.PendingBufferCount; + Capy64.Instance.LuaRuntime.QueueEvent("audio_need", LK => + { + LK.PushInteger(-1); + LK.PushInteger(pending); + return 2; + }); } - public byte[] GenerateWave(Waveform form, double frequency, TimeSpan time) + private void Audio_BufferNeeded(object sender, EventArgs e) { - var size = Sound.GetSampleSizeInBytes(time); + for (int i = 0; i < ChannelsCount; i++) + { + if (Channels[i] == sender) + { + freeChannels[i] = true; + var pending = Channels[i].PendingBufferCount; + Capy64.Instance.LuaRuntime.QueueEvent("audio_need", LK => + { + LK.PushInteger(i); + LK.PushInteger(pending); + return 2; + }); + } + } + + } + + public int GetChannelId(int inp) + { + if (inp >= 0) + return inp; + + if (inp == -1) + return -1; + + if (inp == -2) + { + for (int i = 0; i < ChannelsCount; i++) + { + if (freeChannels[i]) + return i; + } + } + + return -3; + } + + public bool TryGetChannel(int id, out DynamicSoundEffectInstance channel, out int resolvedId) + { + resolvedId = GetChannelId(id); + + if (resolvedId >= 0) + channel = Channels[resolvedId]; + else if (resolvedId == -1) + channel = HQChannel; + else + channel = null; + + return channel != null; + } + + public TimeSpan Submit(int id, byte[] buffer) + { + if (!TryGetChannel(id, out var channel, out var rId)) + return TimeSpan.Zero; + + channel.SubmitBuffer(buffer); + freeChannels[rId] = false; + return channel.GetSampleDuration(buffer.Length); + } + + public TimeSpan SubmitHQ(byte[] buffer) + { + HQChannel.SubmitBuffer(buffer); + return HQChannel.GetSampleDuration(buffer.Length); + } + + public static byte[] GenerateWave(DynamicSoundEffectInstance channel, Waveform form, double frequency, TimeSpan time, float volume = 1f) + { + var size = channel.GetSampleSizeInBytes(time); var buffer = new byte[size]; var step = 1d / SampleRate; @@ -69,12 +146,12 @@ public class Audio : IDisposable Waveform.Square => GetSquarePoint(frequency, x), Waveform.Triangle => GetTrianglePoint(frequency, x), Waveform.Sawtooth => GetSawtoothPoint(frequency, x), - Waveform.Noise => rng.NextDouble() * 2 - 1, + Waveform.Noise => (rng.NextDouble() * 2) - 1, _ => throw new NotImplementedException(), }; - Console.WriteLine(value); + value = Math.Clamp(value, -1, 1); - var sample = (short)(value >= 0.0f ? value * short.MaxValue : value * short.MinValue * -1); + var sample = (short)((value >= 0.0f ? value * short.MaxValue : value * short.MinValue * -1) * volume); if (!BitConverter.IsLittleEndian) { buffer[i] = (byte)(sample >> 8); @@ -107,8 +184,8 @@ public class Audio : IDisposable double v = 0; for (int k = 1; k <= 25; k++) { - v += (Math.Pow(-1, k) / Math.Pow(2 * k - 1, 2)) - * Math.Sin(frequency * 2 * Math.PI * (2 * k - 1) * x); + v += Math.Pow(-1, k) / Math.Pow((2 * k) - 1, 2) + * Math.Sin(frequency * 2 * Math.PI * ((2 * k) - 1) * x); } return -(8 / Math.Pow(Math.PI, 2)) * v; } @@ -118,7 +195,7 @@ public class Audio : IDisposable double v = 0; for (int k = 1; k <= 50; k++) { - v += (Math.Pow(-1, k) / k) * Math.Sin(frequency * 2 * Math.PI * k * x); + v += Math.Pow(-1, k) / k * Math.Sin(frequency * 2 * Math.PI * k * x); } return -(2 / Math.PI) * v; } @@ -126,6 +203,9 @@ public class Audio : IDisposable public void Dispose() { GC.SuppressFinalize(this); - Sound.Dispose(); + for (int i = 0; i < ChannelsCount; i++) + { + Channels[i]?.Dispose(); + } } } diff --git a/Capy64/Core/Drawing.cs b/Capy64/Core/Drawing.cs index 18632b7..ce4e6ec 100644 --- a/Capy64/Core/Drawing.cs +++ b/Capy64/Core/Drawing.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -154,9 +154,10 @@ public class Drawing : IDisposable _spriteBatch.DrawPoint(point, color, size); } - public void DrawCircle(Vector2 pos, int radius, Color color, int thickness = 1) + public void DrawCircle(Vector2 pos, int radius, Color color, int thickness = 1, int sides = -1) { - _spriteBatch.DrawCircle(pos, radius, radius * 4, color, thickness); + sides = sides < 0 ? radius * 4 : sides; + _spriteBatch.DrawCircle(pos, radius, sides, color, thickness); } public void DrawLine(Vector2 start, Vector2 end, Color color, float thickness = 1) @@ -199,17 +200,22 @@ public class Drawing : IDisposable _spriteBatch.Draw(_whitePixel, position3, null, color, rotation, Vector2.Zero, scale, SpriteEffects.None, layerDepth); } - public void DrawTexture(Texture2D texture, Vector2 pos) - { - _spriteBatch.Draw(texture, pos, null, Color.White, 0f, Vector2.Zero, 1, SpriteEffects.None, 0f); - } - - public void DrawBuffer(uint[] buffer, Rectangle rect) + public void DrawBuffer(uint[] buffer, Rectangle rect, Rectangle? source = null, Color? color = null, float rotation = 0f, Vector2? origin = null, float scale = 1f, SpriteEffects spriteEffects = 0) { var texture = new Texture2D(_graphicsDevice, rect.Width, rect.Height, false, SurfaceFormat.Color); texture.SetData(buffer); - DrawTexture(texture, new(rect.X, rect.Y)); + _spriteBatch.Draw( + texture, // Texture + rect.Location.ToVector2(), // Position + source, // source + color ?? Color.White, // Color + rotation, // Rotation + origin ?? Vector2.Zero, // Origin + scale, // Scale + spriteEffects, // Flip effects + 0f // layer depth + ); _disposeTextures.Add(texture); } diff --git a/Capy64/Core/SDL.cs b/Capy64/Core/SDL.cs index 9e074c9..25306f1 100644 --- a/Capy64/Core/SDL.cs +++ b/Capy64/Core/SDL.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -14,11 +14,6 @@ // limitations under the License. using Capy64.Extensions.Bindings; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Capy64.Core; diff --git a/Capy64/Eventing/EventEmitter.cs b/Capy64/Eventing/EventEmitter.cs index aba260b..8e10917 100644 --- a/Capy64/Eventing/EventEmitter.cs +++ b/Capy64/Eventing/EventEmitter.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -163,7 +163,8 @@ public class EventEmitter public void RaiseOverlay(OverlayEvent ev) { - if(OnOverlay is not null) { + if (OnOverlay is not null) + { OnOverlay(this, ev); } } diff --git a/Capy64/Eventing/Events/CharEvent.cs b/Capy64/Eventing/Events/CharEvent.cs index 2ff9e47..34c9405 100644 --- a/Capy64/Eventing/Events/CharEvent.cs +++ b/Capy64/Eventing/Events/CharEvent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Eventing/Events/GamePadButtonEvent.cs b/Capy64/Eventing/Events/GamePadButtonEvent.cs index 916011e..ca409cd 100644 --- a/Capy64/Eventing/Events/GamePadButtonEvent.cs +++ b/Capy64/Eventing/Events/GamePadButtonEvent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Eventing/Events/GamePadThumbstickEvent.cs b/Capy64/Eventing/Events/GamePadThumbstickEvent.cs index ca828c1..34beda8 100644 --- a/Capy64/Eventing/Events/GamePadThumbstickEvent.cs +++ b/Capy64/Eventing/Events/GamePadThumbstickEvent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -14,7 +14,6 @@ // limitations under the License. using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Input; using System; namespace Capy64.Eventing.Events; diff --git a/Capy64/Eventing/Events/GamePadTriggerEvent.cs b/Capy64/Eventing/Events/GamePadTriggerEvent.cs index 5afcbcc..152e4b0 100644 --- a/Capy64/Eventing/Events/GamePadTriggerEvent.cs +++ b/Capy64/Eventing/Events/GamePadTriggerEvent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -13,7 +13,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Microsoft.Xna.Framework.Input; using System; namespace Capy64.Eventing.Events; diff --git a/Capy64/Eventing/Events/KeyEvent.cs b/Capy64/Eventing/Events/KeyEvent.cs index e203931..a8ce550 100644 --- a/Capy64/Eventing/Events/KeyEvent.cs +++ b/Capy64/Eventing/Events/KeyEvent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Eventing/Events/MouseButtonEvent.cs b/Capy64/Eventing/Events/MouseButtonEvent.cs index c610345..cea5330 100644 --- a/Capy64/Eventing/Events/MouseButtonEvent.cs +++ b/Capy64/Eventing/Events/MouseButtonEvent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Eventing/Events/MouseMoveEvent.cs b/Capy64/Eventing/Events/MouseMoveEvent.cs index 9d364e4..61a3efa 100644 --- a/Capy64/Eventing/Events/MouseMoveEvent.cs +++ b/Capy64/Eventing/Events/MouseMoveEvent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Eventing/Events/MouseWheelEvent.cs b/Capy64/Eventing/Events/MouseWheelEvent.cs index fc49061..d95579f 100644 --- a/Capy64/Eventing/Events/MouseWheelEvent.cs +++ b/Capy64/Eventing/Events/MouseWheelEvent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Eventing/Events/OverlayEvent.cs b/Capy64/Eventing/Events/OverlayEvent.cs index 7787c96..a0d026c 100644 --- a/Capy64/Eventing/Events/OverlayEvent.cs +++ b/Capy64/Eventing/Events/OverlayEvent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -14,7 +14,6 @@ // limitations under the License. using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; using System; namespace Capy64.Eventing.Events; diff --git a/Capy64/Eventing/Events/TickEvent.cs b/Capy64/Eventing/Events/TickEvent.cs index bd08ce3..a554f76 100644 --- a/Capy64/Eventing/Events/TickEvent.cs +++ b/Capy64/Eventing/Events/TickEvent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Eventing/InputManager.cs b/Capy64/Eventing/InputManager.cs index e850d43..11c2afc 100644 --- a/Capy64/Eventing/InputManager.cs +++ b/Capy64/Eventing/InputManager.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -423,7 +423,7 @@ public class InputManager // D-PAD var od = oldGamePadState.DPad; var d = state.DPad; - + if (od.Left != d.Left) { _eventEmitter.RaiseGamePadButton(new() @@ -466,7 +466,7 @@ public class InputManager if (ot.Left != t.Left) { - + _eventEmitter.RaiseGamePadTrigger(new() { Trigger = 1, // left diff --git a/Capy64/Extensions/Bindings/Common.cs b/Capy64/Extensions/Bindings/Common.cs index f8dc827..7a26a5c 100644 --- a/Capy64/Extensions/Bindings/Common.cs +++ b/Capy64/Extensions/Bindings/Common.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -14,11 +14,7 @@ // limitations under the License. using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; namespace Capy64.Extensions.Bindings; diff --git a/Capy64/Extensions/Bindings/SDL2.cs b/Capy64/Extensions/Bindings/SDL2.cs index a19c5b1..2ce642e 100644 --- a/Capy64/Extensions/Bindings/SDL2.cs +++ b/Capy64/Extensions/Bindings/SDL2.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Extensions/GameWindowExtensions.cs b/Capy64/Extensions/GameWindowExtensions.cs index ee903d8..bf4e8d4 100644 --- a/Capy64/Extensions/GameWindowExtensions.cs +++ b/Capy64/Extensions/GameWindowExtensions.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/IGame.cs b/Capy64/IGame.cs index 858bad1..9a63019 100644 --- a/Capy64/IGame.cs +++ b/Capy64/IGame.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -15,7 +15,6 @@ using Capy64.API; using Capy64.Core; -using Capy64.Eventing; using Capy64.Integrations; using Capy64.Runtime; using Microsoft.Xna.Framework; @@ -27,8 +26,8 @@ namespace Capy64; public interface IGame { Capy64 Game { get; } - IList NativePlugins { get; } - IList Plugins { get; } + IList NativePlugins { get; } + IList Plugins { get; } GameWindow Window { get; } Drawing Drawing { get; } Audio Audio { get; } diff --git a/Capy64/Integrations/DiscordIntegration.cs b/Capy64/Integrations/DiscordIntegration.cs index 1d141b3..1afcc86 100644 --- a/Capy64/Integrations/DiscordIntegration.cs +++ b/Capy64/Integrations/DiscordIntegration.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -18,16 +18,11 @@ using DiscordRPC; using DiscordRPC.Logging; using DiscordRPC.Message; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Capy64.Integrations; -public class DiscordIntegration : IPlugin +public class DiscordIntegration : IComponent { public DiscordRpcClient Client { get; private set; } private readonly IConfiguration _configuration; diff --git a/Capy64/PluginManager/PluginLoadContext.cs b/Capy64/PluginManager/PluginLoadContext.cs index e8b676e..28b444f 100644 --- a/Capy64/PluginManager/PluginLoadContext.cs +++ b/Capy64/PluginManager/PluginLoadContext.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/PluginManager/PluginLoader.cs b/Capy64/PluginManager/PluginLoader.cs index df3b1e1..dc2268d 100644 --- a/Capy64/PluginManager/PluginLoader.cs +++ b/Capy64/PluginManager/PluginLoader.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -33,21 +33,21 @@ internal class PluginLoader return loadContext.LoadFromAssemblyName(new AssemblyName(Path.GetFileNameWithoutExtension(path))); } - public static List LoadAllPlugins(string pluginsPath, IServiceProvider provider) + public static List LoadAllPlugins(string pluginsPath, IServiceProvider provider) { if (!Directory.Exists(pluginsPath)) Directory.CreateDirectory(pluginsPath); - var plugins = new List(); + var plugins = new List(); foreach (var fileName in Directory.GetFiles(pluginsPath).Where(q => q.EndsWith(".dll"))) { var assembly = LoadPlugin(fileName); foreach (Type type in assembly.GetTypes()) { - if (typeof(IPlugin).IsAssignableFrom(type)) + if (typeof(IComponent).IsAssignableFrom(type)) { - IPlugin result = ActivatorUtilities.CreateInstance(provider, type) as IPlugin; + IComponent result = ActivatorUtilities.CreateInstance(provider, type) as IComponent; plugins.Add(result); } } diff --git a/Capy64/Program.cs b/Capy64/Program.cs index 7689467..6b78a4f 100644 --- a/Capy64/Program.cs +++ b/Capy64/Program.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -24,7 +24,7 @@ using IHost host = Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((context, c) => { var settingsPath = Path.Combine(Capy64.Capy64.AppDataPath, "settings.json"); - if(!Directory.Exists(Capy64.Capy64.AppDataPath)) + if (!Directory.Exists(Capy64.Capy64.AppDataPath)) { Directory.CreateDirectory(Capy64.Capy64.AppDataPath); } diff --git a/Capy64/Runtime/Constants.cs b/Capy64/Runtime/Constants.cs index 964758a..e182fbe 100644 --- a/Capy64/Runtime/Constants.cs +++ b/Capy64/Runtime/Constants.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Runtime/EventEmitter.cs b/Capy64/Runtime/EventEmitter.cs index 6b63f96..c171a72 100644 --- a/Capy64/Runtime/EventEmitter.cs +++ b/Capy64/Runtime/EventEmitter.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -15,12 +15,10 @@ using Capy64.Core; using Capy64.Eventing.Events; -using Capy64.Eventing; using Microsoft.Xna.Framework.Input; using System; using System.Linq; using static Capy64.Eventing.InputManager; -using Capy64.Runtime.Extensions; namespace Capy64.Runtime; @@ -187,7 +185,8 @@ internal class EventEmitter if (SDL.HasClipboardText()) { var text = SDL.GetClipboardText(); - _runtime.QueueEvent("paste", LK => { + _runtime.QueueEvent("paste", LK => + { LK.PushString(text); return 1; @@ -199,7 +198,8 @@ internal class EventEmitter private void OnChar(object sender, CharEvent e) { - _runtime.QueueEvent("char", LK => { + _runtime.QueueEvent("char", LK => + { LK.PushString(e.Character.ToString()); return 1; diff --git a/Capy64/Runtime/Extensions/Libraries.cs b/Capy64/Runtime/Extensions/Libraries.cs index 5341e0b..13727f4 100644 --- a/Capy64/Runtime/Extensions/Libraries.cs +++ b/Capy64/Runtime/Extensions/Libraries.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Runtime/Extensions/NativeLibraries.cs b/Capy64/Runtime/Extensions/NativeLibraries.cs index 7c12a0c..5202585 100644 --- a/Capy64/Runtime/Extensions/NativeLibraries.cs +++ b/Capy64/Runtime/Extensions/NativeLibraries.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Runtime/Extensions/Utils.cs b/Capy64/Runtime/Extensions/Utils.cs index cd401bf..ca08b85 100644 --- a/Capy64/Runtime/Extensions/Utils.cs +++ b/Capy64/Runtime/Extensions/Utils.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Runtime/Libraries/Audio.cs b/Capy64/Runtime/Libraries/Audio.cs index 90156a0..b09ac74 100644 --- a/Capy64/Runtime/Libraries/Audio.cs +++ b/Capy64/Runtime/Libraries/Audio.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -17,12 +17,11 @@ using Capy64.API; using KeraLua; using Microsoft.Xna.Framework.Audio; using System; -using System.Threading.Tasks; using static Capy64.Core.Audio; namespace Capy64.Runtime.Libraries; -public class Audio : IPlugin +public class Audio : IComponent { private const int queueLimit = 8; @@ -90,19 +89,6 @@ public class Audio : IPlugin return 1; } - private static async Task DelayEmit(TimeSpan time) - { - var waitTime = time - TimeSpan.FromMilliseconds(1000 / 60); - if (waitTime.TotalMilliseconds < 0) - waitTime = time; - await Task.Delay(waitTime); - _game.LuaRuntime.QueueEvent("audio_end", LK => - { - LK.PushInteger(_game.Audio.Sound.PendingBufferCount); - return 1; - }); - } - private static int L_Play(IntPtr state) { var L = Lua.FromIntPtr(state); @@ -127,7 +113,7 @@ public class Audio : IPlugin } } - if (_game.Audio.Sound.PendingBufferCount > queueLimit) + if (_game.Audio.HQChannel.PendingBufferCount > queueLimit) { L.PushBoolean(false); L.PushString("queue is full"); @@ -137,11 +123,10 @@ public class Audio : IPlugin try { - var ts = _game.Audio.Submit(buffer); - DelayEmit(ts); + var ts = _game.Audio.SubmitHQ(buffer); - if (_game.Audio.Sound.State != SoundState.Playing) - _game.Audio.Sound.Play(); + if (_game.Audio.HQChannel.State != SoundState.Playing) + _game.Audio.HQChannel.Play(); } catch (Exception ex) { @@ -157,11 +142,11 @@ public class Audio : IPlugin var freq = L.OptNumber(1, 440); var time = L.OptNumber(2, 1); - var volume = L.OptNumber(3, 1); - volume = Math.Clamp(volume, 0, 1); - var timespan = TimeSpan.FromSeconds(time); + var volume = (float)L.OptNumber(3, 1); + volume = Math.Clamp(volume, 0, 1); + var form = L.CheckOption(4, "sine", new string[] { "sine", @@ -172,37 +157,70 @@ public class Audio : IPlugin null, }); - var buffer = _game.Audio.GenerateWave((Waveform)form, freq, timespan); + var id = (int)L.OptInteger(5, -2); + + if (!_game.Audio.TryGetChannel(id, out var channel, out var rid)) + { + L.PushBoolean(false); + return 1; + } + + var buffer = GenerateWave(channel, (Waveform)form, freq, timespan, volume); try { - var ts = _game.Audio.Submit(buffer); - DelayEmit(ts); + var ts = _game.Audio.Submit(rid, buffer); - if (_game.Audio.Sound.State != SoundState.Playing) - _game.Audio.Sound.Play(); + if (channel.State != SoundState.Playing) + channel.Play(); + + L.PushBoolean(true); } catch (Exception ex) { L.Error(ex.Message); } - return 0; + return 1; } private static int L_Resume(IntPtr state) { - _game.Audio.Sound.Resume(); + var L = Lua.FromIntPtr(state); + var id = (int)L.CheckInteger(1); + if (!_game.Audio.TryGetChannel(id, out var channel, out var rid)) + { + L.ArgumentError(1, "channel id not found"); + return 0; + } + + channel.Resume(); return 0; } private static int L_Pause(IntPtr state) { - _game.Audio.Sound.Pause(); + var L = Lua.FromIntPtr(state); + var id = (int)L.CheckInteger(1); + if (!_game.Audio.TryGetChannel(id, out var channel, out var rid)) + { + L.ArgumentError(1, "channel id not found"); + return 0; + } + + channel.Pause(); return 0; } private static int L_Stop(IntPtr state) { - _game.Audio.Sound.Stop(); + var L = Lua.FromIntPtr(state); + var id = (int)L.CheckInteger(1); + if (!_game.Audio.TryGetChannel(id, out var channel, out var rid)) + { + L.ArgumentError(1, "channel id not found"); + return 0; + } + + channel.Stop(); return 0; } @@ -211,7 +229,14 @@ public class Audio : IPlugin { var L = Lua.FromIntPtr(state); - L.PushNumber(_game.Audio.Sound.Volume); + var id = (int)L.CheckInteger(1); + if (!_game.Audio.TryGetChannel(id, out var channel, out var rid)) + { + L.ArgumentError(1, "channel id not found"); + return 0; + } + + L.PushNumber(channel.Volume); return 1; } @@ -219,10 +244,17 @@ public class Audio : IPlugin { var L = Lua.FromIntPtr(state); - var volume = (float)L.CheckNumber(1); + var id = (int)L.CheckInteger(1); + if (!_game.Audio.TryGetChannel(id, out var channel, out var rid)) + { + L.ArgumentError(1, "channel id not found"); + return 0; + } + + var volume = (float)L.CheckNumber(2); volume = Math.Clamp(volume, 0, 1); - _game.Audio.Sound.Volume = volume; + channel.Volume = volume; return 0; } @@ -231,7 +263,14 @@ public class Audio : IPlugin { var L = Lua.FromIntPtr(state); - var status = _game.Audio.Sound.State switch + var id = (int)L.CheckInteger(1); + if (!_game.Audio.TryGetChannel(id, out var channel, out var rid)) + { + L.ArgumentError(1, "channel id not found"); + return 0; + } + + var status = channel.State switch { SoundState.Playing => "playing", SoundState.Paused => "paused", @@ -246,6 +285,9 @@ public class Audio : IPlugin private void OnClose(object sender, EventArgs e) { - _game.Audio.Sound.Stop(true); + foreach (var channel in _game.Audio.Channels) + { + channel.Stop(); + } } } diff --git a/Capy64/Runtime/Libraries/Event.cs b/Capy64/Runtime/Libraries/Event.cs index 985f208..02f3514 100644 --- a/Capy64/Runtime/Libraries/Event.cs +++ b/Capy64/Runtime/Libraries/Event.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -16,14 +16,10 @@ using Capy64.API; using KeraLua; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Capy64.Runtime.Libraries; -public class Event : IPlugin +public class Event : IComponent { private static IGame _game; public Event(IGame game) diff --git a/Capy64/Runtime/Libraries/FileSystem.cs b/Capy64/Runtime/Libraries/FileSystem.cs index 862aadb..e70f38b 100644 --- a/Capy64/Runtime/Libraries/FileSystem.cs +++ b/Capy64/Runtime/Libraries/FileSystem.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -15,17 +15,16 @@ using Capy64.API; using Capy64.Runtime.Extensions; +using Capy64.Runtime.Objects; using KeraLua; using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; -using Capy64.Runtime.Objects; namespace Capy64.Runtime.Libraries; -public class FileSystem : IPlugin +public class FileSystem : IComponent { public static string DataPath = Path.Combine(Capy64.AppDataPath, "data"); @@ -430,7 +429,7 @@ public class FileSystem : IPlugin var attr = File.GetAttributes(path); if (attr.HasFlag(FileAttributes.Directory)) { - if(!recursive && Directory.GetFileSystemEntries(path).Any()) + if (!recursive && Directory.GetFileSystemEntries(path).Any()) { L.Error("directory not empty"); return 0; diff --git a/Capy64/Runtime/Libraries/GPU.cs b/Capy64/Runtime/Libraries/GPU.cs index d31873b..ddf6241 100644 --- a/Capy64/Runtime/Libraries/GPU.cs +++ b/Capy64/Runtime/Libraries/GPU.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -24,7 +24,7 @@ using System.IO; namespace Capy64.Runtime.Libraries; -public class GPU : IPlugin +public class GPU : IComponent { private static IGame _game; @@ -281,10 +281,11 @@ public class GPU : IPlugin var y = (int)L.CheckNumber(2) - 1; var rad = (int)L.CheckNumber(3); var c = L.CheckInteger(4); - var s = (int)L.OptNumber(5, 1); + var t = (int)L.OptNumber(5, 1); + var s = (int)L.OptInteger(6, -1); Utils.UnpackRGB((uint)c, out var r, out var g, out var b); - _game.Drawing.DrawCircle(new(x, y), rad, new Color(r, g, b), s); + _game.Drawing.DrawCircle(new(x, y), rad, new Color(r, g, b), t, s); return 0; } @@ -386,7 +387,14 @@ public class GPU : IPlugin var t = L.CheckString(4); Utils.UnpackRGB((uint)c, out var r, out var g, out var b); - _game.Drawing.DrawString(new Vector2(x, y), t, new Color(r, g, b)); + try + { + _game.Drawing.DrawString(new Vector2(x, y), t, new Color(r, g, b)); + } + catch (ArgumentException ex) // UTF-16 fuckery + { + L.Error(ex.Message); + } return 0; } @@ -456,7 +464,7 @@ public class GPU : IPlugin var w = (int)L.CheckInteger(4); var h = (int)L.CheckInteger(5); - if(w * h != buffer.Length) + if (w * h != buffer.Length) { L.Error("width and height do not match buffer size"); } diff --git a/Capy64/Runtime/Libraries/HTTP.cs b/Capy64/Runtime/Libraries/HTTP.cs index d4044d7..c45575c 100644 --- a/Capy64/Runtime/Libraries/HTTP.cs +++ b/Capy64/Runtime/Libraries/HTTP.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -28,7 +28,7 @@ using System.Threading; namespace Capy64.Runtime.Libraries; #nullable enable -public class HTTP : IPlugin +public class HTTP : IComponent { private static IGame _game; private static HttpClient _httpClient; diff --git a/Capy64/Runtime/Libraries/Machine.cs b/Capy64/Runtime/Libraries/Machine.cs index 94742f5..a245181 100644 --- a/Capy64/Runtime/Libraries/Machine.cs +++ b/Capy64/Runtime/Libraries/Machine.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -19,14 +19,10 @@ using KeraLua; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Capy64.Runtime.Libraries; -public class Machine : IPlugin +public class Machine : IComponent { private static IGame _game; public Machine(IGame game) diff --git a/Capy64/Runtime/Libraries/OS.cs b/Capy64/Runtime/Libraries/OS.cs deleted file mode 100644 index 173deae..0000000 --- a/Capy64/Runtime/Libraries/OS.cs +++ /dev/null @@ -1,34 +0,0 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 -// Copyright 2023 Alessandro "AlexDevs" Proto -// -// Licensed under the Apache License, Version 2.0 (the "License"). -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using Capy64.API; -using KeraLua; -using System; - -namespace Capy64.Runtime.Libraries; - -public class OS : IPlugin -{ - private static IGame _game; - public OS(IGame game) - { - _game = game; - } - - public void LuaInit(Lua state) - { - state.GetGlobal("os"); - } -} diff --git a/Capy64/Runtime/Libraries/Term.cs b/Capy64/Runtime/Libraries/Term.cs index 3fb0251..0036e7e 100644 --- a/Capy64/Runtime/Libraries/Term.cs +++ b/Capy64/Runtime/Libraries/Term.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -18,15 +18,12 @@ using Capy64.Eventing.Events; using KeraLua; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; -using MonoGame.Extended; -using Newtonsoft.Json.Linq; using System; using static Capy64.Utils; -using static System.Formats.Asn1.AsnWriter; namespace Capy64.Runtime.Libraries; -internal class Term : IPlugin +internal class Term : IComponent { private struct Char { @@ -292,7 +289,7 @@ internal class Term : IPlugin if (cursorState) { var realpos = ToRealPos(CursorPosition - Vector2.One); - var charpos = realpos * _game.Scale + CharOffset; + var charpos = (realpos * _game.Scale) + CharOffset; _game.Game.SpriteBatch.Draw(cursorTexture, charpos, null, ForegroundColor, 0f, Vector2.Zero, _game.Scale, SpriteEffects.None, 0); } } @@ -319,7 +316,14 @@ internal class Term : IPlugin if (!L.IsNone(1)) str = L.ToString(1); - Write(str); + try + { + Write(str); + } + catch (ArgumentException ex) // UTF-16 fuckery + { + L.Error(ex.Message); + } return 0; } @@ -623,15 +627,15 @@ internal class Term : IPlugin // RGB to ABGR fgv = - (fgv & 0x00_FF_00_00U) >> 16 | // move R + ((fgv & 0x00_FF_00_00U) >> 16) | // move R (fgv & 0x00_00_FF_00U) | // move G - (fgv & 0x00_00_00_FFU) << 16 | // move B + ((fgv & 0x00_00_00_FFU) << 16) | // move B 0xFF_00_00_00U; bgv = - (bgv & 0x00_FF_00_00U) >> 16 | // move R + ((bgv & 0x00_FF_00_00U) >> 16) | // move R (bgv & 0x00_00_FF_00U) | // move G - (bgv & 0x00_00_00_FFU) << 16 | // move B + ((bgv & 0x00_00_00_FFU) << 16) | // move B 0xFF_00_00_00U; diff --git a/Capy64/Runtime/Libraries/Timer.cs b/Capy64/Runtime/Libraries/Timer.cs index 3c9162b..a687d93 100644 --- a/Capy64/Runtime/Libraries/Timer.cs +++ b/Capy64/Runtime/Libraries/Timer.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -17,11 +17,10 @@ using Capy64.API; using KeraLua; using System; using System.Collections.Concurrent; -using System.Collections.Generic; namespace Capy64.Runtime.Libraries; -class Timer : IPlugin +class Timer : IComponent { private LuaRegister[] TimerLib = new LuaRegister[] { diff --git a/Capy64/Runtime/LuaEvent.cs b/Capy64/Runtime/LuaEvent.cs index 8adb1e3..873db83 100644 --- a/Capy64/Runtime/LuaEvent.cs +++ b/Capy64/Runtime/LuaEvent.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -15,10 +15,6 @@ using KeraLua; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Capy64.Runtime; diff --git a/Capy64/Runtime/LuaException.cs b/Capy64/Runtime/LuaException.cs index 2d04d96..3075d88 100644 --- a/Capy64/Runtime/LuaException.cs +++ b/Capy64/Runtime/LuaException.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/Capy64/Runtime/LuaState.cs b/Capy64/Runtime/LuaState.cs index 654a228..e2b603d 100644 --- a/Capy64/Runtime/LuaState.cs +++ b/Capy64/Runtime/LuaState.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -19,9 +19,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; using System.Text; -using System.Threading.Tasks; namespace Capy64.Runtime; @@ -43,9 +41,6 @@ public class LuaState : IDisposable Encoding = Encoding.UTF8, }; - _parent.PushString("Capy64 " + Capy64.Version); - _parent.SetGlobal("_HOST"); - Sandbox.OpenLibraries(_parent); Sandbox.Patch(_parent); @@ -75,7 +70,7 @@ public class LuaState : IDisposable private void InitPlugins() { - var allPlugins = new List(Capy64.Instance.NativePlugins); + var allPlugins = new List(Capy64.Instance.NativePlugins); allPlugins.AddRange(Capy64.Instance.Plugins); foreach (var plugin in allPlugins) { diff --git a/Capy64/Runtime/ObjectManager.cs b/Capy64/Runtime/ObjectManager.cs index 1a70697..7b708b8 100644 --- a/Capy64/Runtime/ObjectManager.cs +++ b/Capy64/Runtime/ObjectManager.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -18,15 +18,10 @@ using KeraLua; using System; using System.Collections.Concurrent; using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; namespace Capy64.Runtime; -public class ObjectManager : IPlugin +public class ObjectManager : IComponent { private static ConcurrentDictionary _objects = new(); diff --git a/Capy64/Runtime/Objects/FileHandle.cs b/Capy64/Runtime/Objects/FileHandle.cs index a3a0440..f5b3de0 100644 --- a/Capy64/Runtime/Objects/FileHandle.cs +++ b/Capy64/Runtime/Objects/FileHandle.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -16,15 +16,11 @@ using Capy64.API; using KeraLua; using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Capy64.Runtime.Objects; -public class FileHandle : IPlugin +public class FileHandle : IComponent { public const string ObjectType = "file"; @@ -107,12 +103,13 @@ public class FileHandle : IPlugin { var modes = "nlLa"; mode = mode.TrimStart('*'); - if(string.IsNullOrEmpty(mode)) { + if (string.IsNullOrEmpty(mode)) + { return '\0'; } var i = modes.IndexOf(mode[0]); - if(i == -1) + if (i == -1) return '\0'; return modes[i]; @@ -274,7 +271,7 @@ public class FileHandle : IPlugin var n = L.GetTop() - 1; var stream = CheckStream(L, false); L.ArgumentCheck(n <= maxargn, maxargn + 2, "too many arguments"); - L.PushCopy(1); + L.PushCopy(1); L.PushInteger(n); L.PushBoolean(false); L.Rotate(2, 3); diff --git a/Capy64/Runtime/Objects/GPUBuffer.cs b/Capy64/Runtime/Objects/GPUBuffer.cs index a57e37f..7b5540f 100644 --- a/Capy64/Runtime/Objects/GPUBuffer.cs +++ b/Capy64/Runtime/Objects/GPUBuffer.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -16,11 +16,10 @@ using Capy64.API; using KeraLua; using System; -using System.IO; namespace Capy64.Runtime.Objects; -public class GPUBuffer : IPlugin +public class GPUBuffer : IComponent { public const string ObjectType = "GPUBuffer"; @@ -111,9 +110,9 @@ public class GPUBuffer : IPlugin // ABGR to RGB value = - (value & 0x00_00_00_FFU) << 16 | // move R + ((value & 0x00_00_00_FFU) << 16) | // move R (value & 0x00_00_FF_00U) | // move G - (value & 0x00_FF_00_00U) >> 16; // move B + ((value & 0x00_FF_00_00U) >> 16); // move B L.PushInteger(value); @@ -146,11 +145,11 @@ public class GPUBuffer : IPlugin // RGB to ABGR value = - (value & 0x00_FF_00_00U) >> 16 | // move R + ((value & 0x00_FF_00_00U) >> 16) | // move R (value & 0x00_00_FF_00U) | // move G - (value & 0x00_00_00_FFU) << 16 | // move B + ((value & 0x00_00_00_FFU) << 16) | // move B 0xFF_00_00_00U; - + buffer[key] = value; diff --git a/Capy64/Runtime/Objects/WebSocketClient.cs b/Capy64/Runtime/Objects/WebSocketClient.cs index 030d86e..f8fb5e7 100644 --- a/Capy64/Runtime/Objects/WebSocketClient.cs +++ b/Capy64/Runtime/Objects/WebSocketClient.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -23,7 +23,7 @@ using System.Threading; namespace Capy64.Runtime.Objects; -public class WebSocketClient : IPlugin +public class WebSocketClient : IComponent { public const string ObjectType = "WebSocketClient"; diff --git a/Capy64/Runtime/PanicScreen.cs b/Capy64/Runtime/PanicScreen.cs index 8cc1739..ff146c4 100644 --- a/Capy64/Runtime/PanicScreen.cs +++ b/Capy64/Runtime/PanicScreen.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -13,14 +13,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Capy64.Core; using Capy64.Runtime.Libraries; using Microsoft.Xna.Framework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Capy64.Runtime; diff --git a/Capy64/Runtime/RuntimeManager.cs b/Capy64/Runtime/RuntimeManager.cs index 0767ea0..54cfca9 100644 --- a/Capy64/Runtime/RuntimeManager.cs +++ b/Capy64/Runtime/RuntimeManager.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -19,18 +19,12 @@ using Capy64.Extensions; using Capy64.Runtime.Libraries; using KeraLua; using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Diagnostics.Tracing; using System.IO; -using System.Linq; -using System.Text; -using System.Threading; -using System.Threading.Tasks; namespace Capy64.Runtime; -internal class RuntimeManager : IPlugin +internal class RuntimeManager : IComponent { private LuaState luaState; private EventEmitter emitter; diff --git a/Capy64/Runtime/Sandbox.cs b/Capy64/Runtime/Sandbox.cs index 86b0c9f..87f2db1 100644 --- a/Capy64/Runtime/Sandbox.cs +++ b/Capy64/Runtime/Sandbox.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -37,6 +37,8 @@ internal class Sandbox L.OpenOS(); L.OpenPackage(); + + L.SetTop(0); } internal static void Patch(Lua L) { @@ -70,10 +72,11 @@ internal class Sandbox L.PushString("config"); L.PushString(packageConfig); L.SetTable(-4); + L.Pop(1); // delete 3 and 4 searchers L.PushString("searchers"); - L.GetTable(-3); + L.GetTable(-2); L.PushNil(); L.SetInteger(-2, 3); @@ -84,7 +87,7 @@ internal class Sandbox L.PushCFunction(L_Searcher); L.SetInteger(-2, 2); - L.Pop(L.GetTop()); + L.Pop(2); // Replace loadfile with sandboxed one L.PushCFunction(L_Loadfile); @@ -94,8 +97,6 @@ internal class Sandbox L.PushCFunction(L_Dofile); L.SetGlobal("dofile"); - L.Pop(L.GetTop()); - // yeet dangerous os functions L.GetGlobal("os"); @@ -118,6 +119,8 @@ internal class Sandbox L.PushString("getenv"); L.PushNil(); L.SetTable(-3); + + L.Pop(1); } internal static int L_Searcher(IntPtr state) diff --git a/Capy64/Utils.cs b/Capy64/Utils.cs index f94f090..d011545 100644 --- a/Capy64/Utils.cs +++ b/Capy64/Utils.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). @@ -33,7 +33,7 @@ public static class Utils return (color.R << 16) + (color.G << 8) + - (color.B); + color.B; } public static void UnpackRGB(uint packed, out byte r, out byte g, out byte b) diff --git a/Capy64/Worker.cs b/Capy64/Worker.cs index cd67d20..5600877 100644 --- a/Capy64/Worker.cs +++ b/Capy64/Worker.cs @@ -1,4 +1,4 @@ -// This file is part of Capy64 - https://github.com/Capy64/Capy64 +// This file is part of Capy64 - https://github.com/Ale32bit/Capy64 // Copyright 2023 Alessandro "AlexDevs" Proto // // Licensed under the Apache License, Version 2.0 (the "License"). diff --git a/ExamplePlugin/MyPlugin.cs b/ExamplePlugin/MyPlugin.cs index 05eb4bf..d5e4b28 100644 --- a/ExamplePlugin/MyPlugin.cs +++ b/ExamplePlugin/MyPlugin.cs @@ -4,7 +4,7 @@ using KeraLua; namespace ExamplePlugin; -public class MyPlugin : IPlugin +public class MyPlugin : IComponent { private static IGame _game; public MyPlugin(IGame game) diff --git a/README.md b/README.md index b13bf47..168664f 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,23 @@ - - Capy64 Logo + + Capy64 Logo # Capy64 -[![.NET](https://github.com/Capy64/Capy64/actions/workflows/dotnet.yml/badge.svg)](https://github.com/Capy64/Capy64/actions/workflows/dotnet.yml) -[![License](https://img.shields.io/github/license/Capy64/Capy64)](https://github.com/Capy64/Capy64/blob/main/LICENSE) -[![Release](https://img.shields.io/github/v/release/Capy64/Capy64?include_prereleases)](https://github.com/Capy64/Capy64/releases) - +[![.NET](https://github.com/Ale32bit/Capy64/actions/workflows/dotnet.yml/badge.svg)](https://github.com/Ale32bit/Capy64/actions/workflows/dotnet.yml) +[![License](https://img.shields.io/github/license/Ale32bit/Capy64)](https://github.com/Ale32bit/Capy64/blob/main/LICENSE) +[![Release](https://img.shields.io/github/v/release/Ale32bit/Capy64?include_prereleases)](https://github.com/Ale32bit/Capy64/releases) + ## About Capy64 Capy64 is a fantasy console that runs sandbox Lua 5.4. Create anything, from Hello Worlds to games! +## Requirements + +* [.NET 7 Runtime](https://dotnet.microsoft.com/en-us/download/dotnet/7.0) + ## Building ### Requirements @@ -26,6 +30,6 @@ Create anything, from Hello Worlds to games! ### Steps -1. Clone the repository with `git clone https://github.com/Capy64/Capy64.git`. +1. Clone the repository with `git clone https://github.com/Ale32bit/Capy64.git`. 2. Open the file Capy64.sln with the .NET IDE. 3. Build project