Merge branch 'main' into main

This commit is contained in:
Apache 2023-02-18 12:03:54 -06:00 committed by GitHub
commit dcab42e5b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
56 changed files with 349 additions and 294 deletions

View file

@ -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 ####

View file

@ -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) { }

View file

@ -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()
term.clear()

View file

@ -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<IPlugin> NativePlugins { get; private set; }
public IList<IPlugin> Plugins { get; private set; }
public IList<IComponent> NativePlugins { get; private set; }
public IList<IComponent> 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<IPlugin> GetNativePlugins()
private List<IComponent> 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<IPlugin>();
var plugins = new List<IComponent>();
foreach (var type in types)
{
var instance = (IPlugin)ActivatorUtilities.CreateInstance(_serviceProvider, type)!;
var instance = (IComponent)ActivatorUtilities.CreateInstance(_serviceProvider, type)!;
plugins.Add(instance);
}
return plugins;

View file

@ -35,7 +35,6 @@
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<None Include="C:\Users\Alex\source\repos\Capy64\Capy64\Capy64\.editorconfig" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="DiscordRichPresence" Version="1.1.3.18" />

View file

@ -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();
}
}
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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").

View file

@ -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").

View file

@ -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;

View file

@ -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;

View file

@ -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").

View file

@ -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").

View file

@ -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").

View file

@ -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").

View file

@ -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;

View file

@ -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").

View file

@ -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

View file

@ -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;

View file

@ -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").

View file

@ -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").

View file

@ -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<IPlugin> NativePlugins { get; }
IList<IPlugin> Plugins { get; }
IList<IComponent> NativePlugins { get; }
IList<IComponent> Plugins { get; }
GameWindow Window { get; }
Drawing Drawing { get; }
Audio Audio { get; }

View file

@ -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;

View file

@ -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").

View file

@ -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<IPlugin> LoadAllPlugins(string pluginsPath, IServiceProvider provider)
public static List<IComponent> LoadAllPlugins(string pluginsPath, IServiceProvider provider)
{
if (!Directory.Exists(pluginsPath))
Directory.CreateDirectory(pluginsPath);
var plugins = new List<IPlugin>();
var plugins = new List<IComponent>();
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);
}
}

View file

@ -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);
}

View file

@ -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").

View file

@ -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;

View file

@ -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").

View file

@ -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").

View file

@ -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").

View file

@ -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();
}
}
}

View file

@ -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)

View file

@ -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;

View file

@ -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");
}

View file

@ -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;

View file

@ -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)

View file

@ -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");
}
}

View file

@ -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;

View file

@ -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[]
{

View file

@ -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;

View file

@ -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").

View file

@ -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<IPlugin>(Capy64.Instance.NativePlugins);
var allPlugins = new List<IComponent>(Capy64.Instance.NativePlugins);
allPlugins.AddRange(Capy64.Instance.Plugins);
foreach (var plugin in allPlugins)
{

View file

@ -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<nint, object> _objects = new();

View file

@ -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);

View file

@ -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;

View file

@ -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";

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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)

View file

@ -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").

View file

@ -4,7 +4,7 @@ using KeraLua;
namespace ExamplePlugin;
public class MyPlugin : IPlugin
public class MyPlugin : IComponent
{
private static IGame _game;
public MyPlugin(IGame game)

View file

@ -1,19 +1,23 @@
<a href="https://capy64.github.io">
<img src="https://raw.githubusercontent.com/Capy64/capy64.github.io/main/docs/assets/logo.png" alt="Capy64 Logo" title="Capy64" align="right" height="60" />
<a href="https://capy64.alexdevs.me">
<img src="https://raw.githubusercontent.com/Ale32bit/Capy64-docs/main/docs/assets/logo.png" alt="Capy64 Logo" title="Capy64" align="right" height="60" />
</a>
# 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