mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-01-18 10:36:44 +00:00
So many small changes
This commit is contained in:
parent
59bbf10e78
commit
4880fea8e3
14 changed files with 193 additions and 55 deletions
|
@ -29,7 +29,9 @@ term.setForeground(fg)
|
|||
term.setBackground(bg)
|
||||
term.clear()
|
||||
|
||||
if term.isResizable() then
|
||||
term.setSize(53, 20)
|
||||
end
|
||||
|
||||
local w, h = term.getSize()
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ public class Audio : IDisposable
|
|||
Noise
|
||||
}
|
||||
|
||||
public const int SampleRate = 16000;
|
||||
public const int SampleRate = 24000;
|
||||
public const int HQSampleRate = 48000;
|
||||
public const AudioChannels AudioChannel = AudioChannels.Mono;
|
||||
public const int ChannelsCount = 8;
|
||||
|
@ -126,6 +126,7 @@ public class Audio : IDisposable
|
|||
|
||||
public TimeSpan SubmitHQ(byte[] buffer)
|
||||
{
|
||||
|
||||
HQChannel.SubmitBuffer(buffer);
|
||||
return HQChannel.GetSampleDuration(buffer.Length);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace Capy64.Integrations;
|
|||
public class DiscordIntegration : IComponent
|
||||
{
|
||||
public DiscordRpcClient Client { get; private set; }
|
||||
public readonly bool Enabled;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public DiscordIntegration(IConfiguration configuration)
|
||||
|
@ -32,6 +33,8 @@ public class DiscordIntegration : IComponent
|
|||
_configuration = configuration;
|
||||
|
||||
var discordConfig = _configuration.GetSection("Integrations:Discord");
|
||||
Enabled = discordConfig.GetValue("Enable", false);
|
||||
|
||||
Client = new(discordConfig["ApplicationId"])
|
||||
{
|
||||
Logger = new ConsoleLogger() { Level = LogLevel.Warning }
|
||||
|
@ -41,15 +44,16 @@ public class DiscordIntegration : IComponent
|
|||
|
||||
Capy64.Instance.Discord = this;
|
||||
|
||||
if (discordConfig.GetValue("Enable", false))
|
||||
{
|
||||
if (Enabled)
|
||||
Client.Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
public void SetPresence(string details, string? state = null)
|
||||
{
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
Client.SetPresence(new RichPresence()
|
||||
{
|
||||
Details = details,
|
||||
|
|
|
@ -97,17 +97,4 @@ public static class Utils
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
[Obsolete("This method does not work as intended and requires more research")]
|
||||
public static void PushManagedObject<T>(this Lua L, T obj)
|
||||
{
|
||||
var type = obj.GetType();
|
||||
var members = type.GetMembers().Where(m => m.MemberType == MemberTypes.Method);
|
||||
L.CreateTable(0, members.Count());
|
||||
foreach (var m in members)
|
||||
{
|
||||
L.PushCFunction(L => (int)type.InvokeMember(m.Name, BindingFlags.InvokeMethod, null, obj, new object[] { L }));
|
||||
L.SetField(-2, m.Name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -103,12 +103,14 @@ public class AudioLib : IComponent
|
|||
{
|
||||
L.CheckType(1, LuaType.Table);
|
||||
var len = L.RawLen(1);
|
||||
buffer = new byte[len];
|
||||
buffer = new byte[len * 2];
|
||||
for (int i = 1; i <= len; i++)
|
||||
{
|
||||
L.GetInteger(1, i);
|
||||
var value = L.CheckInteger(-1);
|
||||
buffer[i - 1] = (byte)value;
|
||||
// Convert 8bit PCM to 16bit PCM
|
||||
var value = (short)(L.CheckNumber(-1) / sbyte.MaxValue * short.MaxValue);
|
||||
buffer[2 * i - 2] = (byte)(value & 0xff);
|
||||
buffer[2 * i - 1] = (byte)(value >> 8);
|
||||
L.Pop(1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,7 +138,11 @@ public class EventLib : IComponent
|
|||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = TaskMeta.CheckTask(L, false);
|
||||
L.CheckType(1, LuaType.Table);
|
||||
|
||||
L.GetField(1, "task");
|
||||
|
||||
var task = TaskMeta.CheckTask(L, -1, false);
|
||||
L.CheckAny(2);
|
||||
L.ArgumentCheck(!L.IsNil(2), 2, "value cannot be nil");
|
||||
|
||||
|
@ -164,7 +168,11 @@ public class EventLib : IComponent
|
|||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = TaskMeta.CheckTask(L, false);
|
||||
L.CheckType(1, LuaType.Table);
|
||||
|
||||
L.GetField(1, "task");
|
||||
|
||||
var task = TaskMeta.CheckTask(L, -1, false);
|
||||
var error = L.CheckString(2);
|
||||
|
||||
if (!task.UserTask)
|
||||
|
|
|
@ -46,6 +46,11 @@ public class GPULib : IComponent
|
|||
function = L_SetSize,
|
||||
},
|
||||
new()
|
||||
{
|
||||
name = "isResizable",
|
||||
function = L_IsResizable,
|
||||
},
|
||||
new()
|
||||
{
|
||||
name = "getPixel",
|
||||
function = L_GetPixel,
|
||||
|
@ -116,6 +121,11 @@ public class GPULib : IComponent
|
|||
function = L_NewBuffer,
|
||||
},
|
||||
new()
|
||||
{
|
||||
name = "bufferFrom",
|
||||
function = L_BufferFrom,
|
||||
},
|
||||
new()
|
||||
{
|
||||
name = "drawBuffer",
|
||||
function = L_DrawBuffer,
|
||||
|
@ -168,8 +178,7 @@ public class GPULib : IComponent
|
|||
|
||||
if (_game.EngineMode == EngineMode.Classic)
|
||||
{
|
||||
L.PushBoolean(false);
|
||||
return 1;
|
||||
return L.Error("Screen is not resizable");
|
||||
}
|
||||
|
||||
var w = L.CheckInteger(1);
|
||||
|
@ -185,6 +194,15 @@ public class GPULib : IComponent
|
|||
return 1;
|
||||
}
|
||||
|
||||
private static int L_IsResizable(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
L.PushBoolean(_game.EngineMode != EngineMode.Classic);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int L_GetPixel(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
@ -457,6 +475,57 @@ public class GPULib : IComponent
|
|||
return 1;
|
||||
}
|
||||
|
||||
private static int L_BufferFrom(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
L.CheckType(1, LuaType.Table);
|
||||
var width = (int)L.CheckInteger(2);
|
||||
var height = (int)L.CheckInteger(3);
|
||||
|
||||
if (width <= 0)
|
||||
{
|
||||
return L.ArgumentError(2, "width must be a positive integer.");
|
||||
}
|
||||
|
||||
if (height <= 0)
|
||||
{
|
||||
return L.ArgumentError(3, "height must be a positive integer.");
|
||||
}
|
||||
|
||||
var buffer = new uint[width * height];
|
||||
|
||||
var tableSize = L.RawLen(1);
|
||||
L.ArgumentCheck(tableSize == buffer.Length, 1, "table length does not match buffer size");
|
||||
|
||||
for (int i = 1; i <= tableSize; i++)
|
||||
{
|
||||
L.GetInteger(1, i);
|
||||
var value = (uint)L.CheckInteger(-1);
|
||||
L.Pop(1);
|
||||
// ARGB to ABGR
|
||||
value =
|
||||
(value & 0xFF_00_00_00U) |
|
||||
((value & 0x00_FF_00_00U) >> 16) | // move R
|
||||
(value & 0x00_00_FF_00U) | // move G
|
||||
((value & 0x00_00_00_FFU) << 16); // move B
|
||||
|
||||
buffer[i - 1] = value;
|
||||
}
|
||||
|
||||
var gpuBuffer = new GPUBufferMeta.GPUBuffer
|
||||
{
|
||||
Buffer = buffer,
|
||||
Width = width,
|
||||
Height = height,
|
||||
};
|
||||
|
||||
ObjectManager.PushObject(L, gpuBuffer);
|
||||
L.SetMetaTable(GPUBufferMeta.ObjectType);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int L_DrawBuffer(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
|
|
@ -30,14 +30,14 @@ namespace Capy64.Runtime.Libraries;
|
|||
#nullable enable
|
||||
public class HTTPLib : IComponent
|
||||
{
|
||||
private static IGame _game;
|
||||
private static HttpClient _httpClient;
|
||||
private static IGame _game = null!;
|
||||
private static HttpClient _httpClient = null!;
|
||||
private static long _requestId;
|
||||
public static readonly HashSet<WebSocketClient.Client> WebSocketConnections = new();
|
||||
|
||||
public static readonly string UserAgent = $"Capy64/{Capy64.Version}";
|
||||
|
||||
private static IConfiguration _configuration;
|
||||
private static IConfiguration _configuration = null!;
|
||||
private readonly LuaRegister[] Library = new LuaRegister[]
|
||||
{
|
||||
new()
|
||||
|
|
|
@ -99,6 +99,10 @@ internal class TermLib : IComponent
|
|||
name = "setSize",
|
||||
function = L_SetSize,
|
||||
},
|
||||
new() {
|
||||
name = "isResizable",
|
||||
function = L_IsResizable,
|
||||
},
|
||||
new()
|
||||
{
|
||||
name = "getForeground",
|
||||
|
@ -397,8 +401,7 @@ internal class TermLib : IComponent
|
|||
|
||||
if (_game.EngineMode == EngineMode.Classic)
|
||||
{
|
||||
L.PushBoolean(false);
|
||||
return 1;
|
||||
return L.Error("Terminal is not resizable");
|
||||
}
|
||||
|
||||
var w = (int)L.CheckNumber(1);
|
||||
|
@ -419,6 +422,15 @@ internal class TermLib : IComponent
|
|||
return 1;
|
||||
}
|
||||
|
||||
private static int L_IsResizable(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
L.PushBoolean(_game.EngineMode != EngineMode.Classic);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int L_GetForegroundColor(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
|
|
@ -26,7 +26,7 @@ class TimerLib : IComponent
|
|||
public class Timer
|
||||
{
|
||||
public int RemainingTicks = 0;
|
||||
public TaskMeta.RuntimeTask? Task;
|
||||
public TaskMeta.RuntimeTask Task = null!;
|
||||
}
|
||||
|
||||
private readonly LuaRegister[] Library = new LuaRegister[]
|
||||
|
|
|
@ -60,7 +60,6 @@ public class LuaState : IDisposable
|
|||
if (yieldTimedOut)
|
||||
{
|
||||
L.Error("no yield timeout");
|
||||
Console.WriteLine("tick");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,16 +32,30 @@ public class ObjectManager : IComponent
|
|||
_game.EventEmitter.OnClose += OnClose;
|
||||
}
|
||||
|
||||
public static void PushObject<T>(Lua L, T obj)
|
||||
public static nint PushObject<T>(Lua L, T obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
L.PushNil();
|
||||
return;
|
||||
return nint.Zero;
|
||||
}
|
||||
|
||||
var p = L.NewUserData(1);
|
||||
_objects[p] = obj;
|
||||
return p;
|
||||
}
|
||||
|
||||
public static T GetObject<T>(nint address, bool freeGCHandle = false)
|
||||
{
|
||||
if (!_objects.ContainsKey(address))
|
||||
return default(T);
|
||||
|
||||
var reference = (T)_objects[address];
|
||||
|
||||
if (freeGCHandle)
|
||||
_objects.Remove(address, out _);
|
||||
|
||||
return reference;
|
||||
}
|
||||
|
||||
public static T ToObject<T>(Lua L, int index, bool freeGCHandle = true)
|
||||
|
|
|
@ -29,10 +29,10 @@ public class Socket : IDisposable
|
|||
|
||||
public class SocketLib : IComponent
|
||||
{
|
||||
private static readonly IGame _game;
|
||||
private static IGame _game = null!;
|
||||
public SocketLib(IGame game)
|
||||
{
|
||||
|
||||
_game = game;
|
||||
}
|
||||
|
||||
private static readonly LuaRegister[] Methods = new LuaRegister[] {
|
||||
|
|
|
@ -43,6 +43,7 @@ public class TaskMeta : IComponent
|
|||
}
|
||||
|
||||
public Guid Guid { get; set; } = Guid.NewGuid();
|
||||
public nint Pointer { get; set; } = nint.Zero;
|
||||
public string Name { get; set; }
|
||||
public TaskStatus Status { get; set; } = TaskStatus.Running;
|
||||
public string Error { get; private set; }
|
||||
|
@ -79,7 +80,6 @@ public class TaskMeta : IComponent
|
|||
DataIndex = tasks.GetTop();
|
||||
}
|
||||
|
||||
|
||||
_game.LuaRuntime.QueueEvent("task_finish", LK =>
|
||||
{
|
||||
LK.PushString(Guid.ToString());
|
||||
|
@ -203,26 +203,58 @@ public class TaskMeta : IComponent
|
|||
|
||||
var task = new RuntimeTask(typeName);
|
||||
|
||||
ObjectManager.PushObject(L, task);
|
||||
L.NewTable();
|
||||
task.Pointer = ObjectManager.PushObject(L, task);
|
||||
L.SetMetaTable(ObjectType);
|
||||
L.SetField(-2, "task");
|
||||
|
||||
L.SetMetaTable(ObjectType);
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
public static RuntimeTask ToTask(Lua L, bool gc = false)
|
||||
public static RuntimeTask ToTask(Lua L, int index = 1, bool gc = false)
|
||||
{
|
||||
return ObjectManager.ToObject<RuntimeTask>(L, 1, gc);
|
||||
RuntimeTask task;
|
||||
if (L.Type(index) != LuaType.Table)
|
||||
{
|
||||
if (L.TestUserData(index, ObjectType) == nint.Zero)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
task = ObjectManager.ToObject<RuntimeTask>(L, index, gc);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
L.GetField(index, "task");
|
||||
task = task = ObjectManager.ToObject<RuntimeTask>(L, -1, gc);
|
||||
}
|
||||
return task;
|
||||
}
|
||||
|
||||
public static RuntimeTask CheckTask(Lua L, bool gc = false)
|
||||
public static RuntimeTask CheckTask(Lua L, int index = 1, bool gc = false)
|
||||
{
|
||||
var obj = ObjectManager.CheckObject<RuntimeTask>(L, 1, ObjectType, gc);
|
||||
if (obj is null)
|
||||
RuntimeTask task;
|
||||
if (L.Type(index) != LuaType.Table)
|
||||
{
|
||||
task = ObjectManager.CheckObject<RuntimeTask>(L, index, ObjectType, gc);
|
||||
}
|
||||
else
|
||||
{
|
||||
L.GetField(index, "task");
|
||||
task = ObjectManager.CheckObject<RuntimeTask>(L, -1, ObjectType, gc);
|
||||
}
|
||||
|
||||
if (task is null)
|
||||
{
|
||||
L.Error("attempt to use a closed task");
|
||||
return null;
|
||||
}
|
||||
return obj;
|
||||
return task;
|
||||
}
|
||||
|
||||
private static int FindSpot()
|
||||
|
@ -268,7 +300,7 @@ public class TaskMeta : IComponent
|
|||
|
||||
L.Warning("Native task awaiter should be avoided", false);
|
||||
|
||||
var task = CheckTask(L, false);
|
||||
var task = CheckTask(L, 1, false);
|
||||
|
||||
if (task.Status == TaskStatus.Succeeded)
|
||||
{
|
||||
|
@ -295,7 +327,9 @@ public class TaskMeta : IComponent
|
|||
private static int LK_Await(IntPtr state, int status, nint ctx)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
var task = CheckTask(L, false);
|
||||
|
||||
var task = CheckTask(L, 1, false);
|
||||
|
||||
var taskId = L.CheckString(3);
|
||||
|
||||
if (task.Guid.ToString() != taskId)
|
||||
|
@ -311,7 +345,7 @@ public class TaskMeta : IComponent
|
|||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = CheckTask(L, false);
|
||||
var task = CheckTask(L, 1, false);
|
||||
|
||||
L.PushString(task.Guid.ToString());
|
||||
|
||||
|
@ -322,7 +356,7 @@ public class TaskMeta : IComponent
|
|||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = CheckTask(L, false);
|
||||
var task = CheckTask(L, 1, false);
|
||||
|
||||
L.PushString(task.Name);
|
||||
|
||||
|
@ -333,7 +367,7 @@ public class TaskMeta : IComponent
|
|||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = CheckTask(L, false);
|
||||
var task = CheckTask(L, 1, false);
|
||||
|
||||
L.PushString(task.Status.ToString().ToLower());
|
||||
|
||||
|
@ -344,7 +378,7 @@ public class TaskMeta : IComponent
|
|||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = CheckTask(L, false);
|
||||
var task = CheckTask(L, 1, false);
|
||||
|
||||
if (task.Status == TaskStatus.Succeeded)
|
||||
{
|
||||
|
@ -364,7 +398,7 @@ public class TaskMeta : IComponent
|
|||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = CheckTask(L, false);
|
||||
var task = CheckTask(L, 1, false);
|
||||
|
||||
if (task.Status == TaskStatus.Failed)
|
||||
{
|
||||
|
@ -382,7 +416,11 @@ public class TaskMeta : IComponent
|
|||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = ToTask(L, true);
|
||||
L.CheckType(1, LuaType.Table);
|
||||
|
||||
L.GetField(1, "task");
|
||||
|
||||
var task = CheckTask(L, -1, true);
|
||||
if (task is null)
|
||||
return 0;
|
||||
|
||||
|
@ -400,7 +438,9 @@ public class TaskMeta : IComponent
|
|||
private static int LM_ToString(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = ToTask(L);
|
||||
|
||||
L.PushString("Task<{0}>: {1} ({2})", task?.Name, task?.Guid, task?.Status);
|
||||
|
||||
return 1;
|
||||
|
|
Loading…
Reference in a new issue