So many small changes

This commit is contained in:
Ale32bit 2023-06-28 16:22:38 +02:00
parent 59bbf10e78
commit 4880fea8e3
14 changed files with 193 additions and 55 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -60,7 +60,6 @@ public class LuaState : IDisposable
if (yieldTimedOut)
{
L.Error("no yield timeout");
Console.WriteLine("tick");
}
}

View file

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

View file

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

View file

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