mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-01-18 18:46:43 +00:00
Classic mode (#10)
This commit is contained in:
parent
341ed38897
commit
0e4d3c135a
14 changed files with 892 additions and 135 deletions
|
@ -35,7 +35,6 @@ term.setBackground(bg)
|
||||||
term.clear()
|
term.clear()
|
||||||
|
|
||||||
term.setSize(53, 20)
|
term.setSize(53, 20)
|
||||||
gpu.setScale(2)
|
|
||||||
|
|
||||||
local w, h = term.getSize()
|
local w, h = term.getSize()
|
||||||
|
|
||||||
|
@ -63,13 +62,14 @@ local function drawVendorImage()
|
||||||
|
|
||||||
local w, h = gpu.getSize()
|
local w, h = gpu.getSize()
|
||||||
local ok, err = pcall(function()
|
local ok, err = pcall(function()
|
||||||
local buffer<close>, width, height = gpu.loadImage("/boot/vendor.bmp")
|
local task<close> = gpu.loadImageAsync("/boot/vendor.bmp")
|
||||||
|
local buffer<close> = task:await()
|
||||||
|
|
||||||
local x, y =
|
local x, y =
|
||||||
math.ceil((w / 2) - (width / 2)),
|
math.ceil((w / 2) - (buffer.width / 2)),
|
||||||
math.ceil((h / 2) - (height / 2))
|
math.ceil((h / 2) - (buffer.height / 2))
|
||||||
|
|
||||||
gpu.drawBuffer(buffer, x, y, width, height)
|
gpu.drawBuffer(buffer, x, y)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if not ok then
|
if not ok then
|
||||||
|
@ -157,11 +157,6 @@ local function installOS()
|
||||||
promptKey()
|
promptKey()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function toggleConsole()
|
|
||||||
local status = getConsole()
|
|
||||||
setConsole(not status)
|
|
||||||
end
|
|
||||||
|
|
||||||
term.setBlink(false)
|
term.setBlink(false)
|
||||||
|
|
||||||
local function setupScreen()
|
local function setupScreen()
|
||||||
|
@ -170,10 +165,6 @@ local function setupScreen()
|
||||||
"Open data folder",
|
"Open data folder",
|
||||||
openDataFolder,
|
openDataFolder,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"Toggle console window",
|
|
||||||
toggleConsole,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"Install default OS",
|
"Install default OS",
|
||||||
installOS,
|
installOS,
|
||||||
|
|
|
@ -1,4 +1,8 @@
|
||||||
{
|
{
|
||||||
|
"EngineMode": 0,
|
||||||
|
"Window": {
|
||||||
|
"Scale": 2
|
||||||
|
},
|
||||||
"HTTP": {
|
"HTTP": {
|
||||||
"Enable": true,
|
"Enable": true,
|
||||||
"Blacklist": [],
|
"Blacklist": [],
|
||||||
|
|
|
@ -20,6 +20,7 @@ using Capy64.Extensions;
|
||||||
using Capy64.Integrations;
|
using Capy64.Integrations;
|
||||||
using Capy64.PluginManager;
|
using Capy64.PluginManager;
|
||||||
using Capy64.Runtime;
|
using Capy64.Runtime;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
@ -33,9 +34,29 @@ using static Capy64.Utils;
|
||||||
|
|
||||||
namespace Capy64;
|
namespace Capy64;
|
||||||
|
|
||||||
|
public enum EngineMode
|
||||||
|
{
|
||||||
|
Classic,
|
||||||
|
Free
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public class Capy64 : Game, IGame
|
public class Capy64 : Game, IGame
|
||||||
{
|
{
|
||||||
public const string Version = "0.0.9-alpha";
|
public const string Version = "0.0.10-alpha";
|
||||||
|
|
||||||
|
public static class DefaultParameters
|
||||||
|
{
|
||||||
|
public const int Width = 318;
|
||||||
|
public const int Height = 240;
|
||||||
|
public const float Scale = 2f;
|
||||||
|
public const float BorderMultiplier = 1.5f;
|
||||||
|
public readonly static EngineMode EngineMode = EngineMode.Classic;
|
||||||
|
|
||||||
|
public const int ClassicTickrate = 20;
|
||||||
|
public const int FreeTickrate = 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static string AppDataPath
|
public static string AppDataPath
|
||||||
{
|
{
|
||||||
|
@ -56,11 +77,12 @@ public class Capy64 : Game, IGame
|
||||||
|
|
||||||
public static Capy64 Instance { get; private set; }
|
public static Capy64 Instance { get; private set; }
|
||||||
public Capy64 Game => this;
|
public Capy64 Game => this;
|
||||||
|
public EngineMode EngineMode { get; private set; } = EngineMode.Classic;
|
||||||
public IList<IComponent> NativePlugins { get; private set; }
|
public IList<IComponent> NativePlugins { get; private set; }
|
||||||
public IList<IComponent> Plugins { get; private set; }
|
public IList<IComponent> Plugins { get; private set; }
|
||||||
public int Width { get; set; } = 320;
|
public int Width { get; set; } = DefaultParameters.Width;
|
||||||
public int Height { get; set; } = 240;
|
public int Height { get; set; } = DefaultParameters.Height;
|
||||||
public float Scale { get; set; } = 2f;
|
public float Scale { get; set; } = DefaultParameters.Scale;
|
||||||
public Drawing Drawing { get; private set; }
|
public Drawing Drawing { get; private set; }
|
||||||
public Audio Audio { get; private set; }
|
public Audio Audio { get; private set; }
|
||||||
public LuaState LuaRuntime { get; set; }
|
public LuaState LuaRuntime { get; set; }
|
||||||
|
@ -83,6 +105,7 @@ public class Capy64 : Game, IGame
|
||||||
private readonly GraphicsDeviceManager _graphics;
|
private readonly GraphicsDeviceManager _graphics;
|
||||||
private IServiceProvider _serviceProvider;
|
private IServiceProvider _serviceProvider;
|
||||||
private ulong _totalTicks = 0;
|
private ulong _totalTicks = 0;
|
||||||
|
private ulong tickrate = 0;
|
||||||
|
|
||||||
public Capy64()
|
public Capy64()
|
||||||
{
|
{
|
||||||
|
@ -103,6 +126,27 @@ public class Capy64 : Game, IGame
|
||||||
_serviceProvider = serviceProvider;
|
_serviceProvider = serviceProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetEngineMode(EngineMode mode)
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case EngineMode.Classic:
|
||||||
|
tickrate = DefaultParameters.ClassicTickrate;
|
||||||
|
Width = DefaultParameters.Width;
|
||||||
|
Height = DefaultParameters.Height;
|
||||||
|
Window.AllowUserResizing = false;
|
||||||
|
ResetBorder();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EngineMode.Free:
|
||||||
|
tickrate = DefaultParameters.FreeTickrate;
|
||||||
|
Window.AllowUserResizing = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
UpdateSize(true);
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateSize(bool resize = true)
|
public void UpdateSize(bool resize = true)
|
||||||
{
|
{
|
||||||
if (resize)
|
if (resize)
|
||||||
|
@ -157,7 +201,7 @@ public class Capy64 : Game, IGame
|
||||||
|
|
||||||
private void ResetBorder()
|
private void ResetBorder()
|
||||||
{
|
{
|
||||||
var size = (int)(Scale * 1.5);
|
var size = (int)(Scale * DefaultParameters.BorderMultiplier);
|
||||||
Borders = new Borders
|
Borders = new Borders
|
||||||
{
|
{
|
||||||
Top = size,
|
Top = size,
|
||||||
|
@ -169,8 +213,12 @@ public class Capy64 : Game, IGame
|
||||||
|
|
||||||
protected override void Initialize()
|
protected override void Initialize()
|
||||||
{
|
{
|
||||||
|
var configuration = _serviceProvider.GetService<IConfiguration>();
|
||||||
|
|
||||||
Window.Title = "Capy64 " + Version;
|
Window.Title = "Capy64 " + Version;
|
||||||
|
|
||||||
|
Scale = configuration.GetValue("Window:Scale", DefaultParameters.Scale);
|
||||||
|
|
||||||
ResetBorder();
|
ResetBorder();
|
||||||
UpdateSize();
|
UpdateSize();
|
||||||
|
|
||||||
|
@ -179,6 +227,8 @@ public class Capy64 : Game, IGame
|
||||||
|
|
||||||
InactiveSleepTime = new TimeSpan(0);
|
InactiveSleepTime = new TimeSpan(0);
|
||||||
|
|
||||||
|
SetEngineMode(configuration.GetValue<EngineMode>("EngineMode", DefaultParameters.EngineMode));
|
||||||
|
|
||||||
Audio = new Audio();
|
Audio = new Audio();
|
||||||
|
|
||||||
NativePlugins = GetNativePlugins();
|
NativePlugins = GetNativePlugins();
|
||||||
|
@ -222,7 +272,8 @@ public class Capy64 : Game, IGame
|
||||||
EventEmitter.RaiseTick(new()
|
EventEmitter.RaiseTick(new()
|
||||||
{
|
{
|
||||||
GameTime = gameTime,
|
GameTime = gameTime,
|
||||||
TotalTicks = _totalTicks
|
TotalTicks = _totalTicks,
|
||||||
|
IsActiveTick = _totalTicks % (60 / tickrate) == 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
Drawing.End();
|
Drawing.End();
|
||||||
|
|
321
Capy64/Core/ColorPalette.cs
Normal file
321
Capy64/Core/ColorPalette.cs
Normal file
|
@ -0,0 +1,321 @@
|
||||||
|
// 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").
|
||||||
|
// 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 Microsoft.Xna.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Capy64.Core;
|
||||||
|
|
||||||
|
public class ColorPalette
|
||||||
|
{
|
||||||
|
public static int GetIndex(int r, int g, int b)
|
||||||
|
{
|
||||||
|
r /= 51;
|
||||||
|
g /= 51;
|
||||||
|
b /= 51;
|
||||||
|
return 16 + (36 * r) + (6 * g) + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetIndex(Color color)
|
||||||
|
{
|
||||||
|
return GetIndex(color.R, color.G, color.B);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetIndex(uint packed)
|
||||||
|
{
|
||||||
|
var b = (byte)(packed & 0xff);
|
||||||
|
var g = (byte)((packed >> 8) & 0xff);
|
||||||
|
var r = (byte)((packed >> 16) & 0xff);
|
||||||
|
return GetIndex(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint GetColor(int r, int g, int b)
|
||||||
|
{
|
||||||
|
return Palette[GetIndex(r, g, b)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint GetColor(Color color)
|
||||||
|
{
|
||||||
|
return Palette[GetIndex(color)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint GetColor(uint packed)
|
||||||
|
{
|
||||||
|
return Palette[GetIndex(packed)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly uint[] Palette = new uint[] {
|
||||||
|
0x000000,
|
||||||
|
0x800000,
|
||||||
|
0x008000,
|
||||||
|
0x808000,
|
||||||
|
0x000080,
|
||||||
|
0x800080,
|
||||||
|
0x008080,
|
||||||
|
0xC0C0C0,
|
||||||
|
0x808080,
|
||||||
|
0xFF0000,
|
||||||
|
0x00FF00,
|
||||||
|
0xFFFF00,
|
||||||
|
0x0000FF,
|
||||||
|
0xFF00FF,
|
||||||
|
0x00FFFF,
|
||||||
|
0xFFFFFF,
|
||||||
|
0x000000,
|
||||||
|
0x00005F,
|
||||||
|
0x000087,
|
||||||
|
0x0000AF,
|
||||||
|
0x0000D7,
|
||||||
|
0x0000FF,
|
||||||
|
0x005F00,
|
||||||
|
0x005F5F,
|
||||||
|
0x005F87,
|
||||||
|
0x005FAF,
|
||||||
|
0x005FD7,
|
||||||
|
0x005FFF,
|
||||||
|
0x008700,
|
||||||
|
0x00875F,
|
||||||
|
0x008787,
|
||||||
|
0x0087AF,
|
||||||
|
0x0087D7,
|
||||||
|
0x0087FF,
|
||||||
|
0x00AF00,
|
||||||
|
0x00AF5F,
|
||||||
|
0x00AF87,
|
||||||
|
0x00AFAF,
|
||||||
|
0x00AFD7,
|
||||||
|
0x00AFFF,
|
||||||
|
0x00D700,
|
||||||
|
0x00D75F,
|
||||||
|
0x00D787,
|
||||||
|
0x00D7AF,
|
||||||
|
0x00D7D7,
|
||||||
|
0x00D7FF,
|
||||||
|
0x00FF00,
|
||||||
|
0x00FF5F,
|
||||||
|
0x00FF87,
|
||||||
|
0x00FFAF,
|
||||||
|
0x00FFD7,
|
||||||
|
0x00FFFF,
|
||||||
|
0x5F0000,
|
||||||
|
0x5F005F,
|
||||||
|
0x5F0087,
|
||||||
|
0x5F00AF,
|
||||||
|
0x5F00D7,
|
||||||
|
0x5F00FF,
|
||||||
|
0x5F5F00,
|
||||||
|
0x5F5F5F,
|
||||||
|
0x5F5F87,
|
||||||
|
0x5F5FAF,
|
||||||
|
0x5F5FD7,
|
||||||
|
0x5F5FFF,
|
||||||
|
0x5F8700,
|
||||||
|
0x5F875F,
|
||||||
|
0x5F8787,
|
||||||
|
0x5F87AF,
|
||||||
|
0x5F87D7,
|
||||||
|
0x5F87FF,
|
||||||
|
0x5FAF00,
|
||||||
|
0x5FAF5F,
|
||||||
|
0x5FAF87,
|
||||||
|
0x5FAFAF,
|
||||||
|
0x5FAFD7,
|
||||||
|
0x5FAFFF,
|
||||||
|
0x5FD700,
|
||||||
|
0x5FD75F,
|
||||||
|
0x5FD787,
|
||||||
|
0x5FD7AF,
|
||||||
|
0x5FD7D7,
|
||||||
|
0x5FD7FF,
|
||||||
|
0x5FFF00,
|
||||||
|
0x5FFF5F,
|
||||||
|
0x5FFF87,
|
||||||
|
0x5FFFAF,
|
||||||
|
0x5FFFD7,
|
||||||
|
0x5FFFFF,
|
||||||
|
0x870000,
|
||||||
|
0x87005F,
|
||||||
|
0x870087,
|
||||||
|
0x8700AF,
|
||||||
|
0x8700D7,
|
||||||
|
0x8700FF,
|
||||||
|
0x875F00,
|
||||||
|
0x875F5F,
|
||||||
|
0x875F87,
|
||||||
|
0x875FAF,
|
||||||
|
0x875FD7,
|
||||||
|
0x875FFF,
|
||||||
|
0x878700,
|
||||||
|
0x87875F,
|
||||||
|
0x878787,
|
||||||
|
0x8787AF,
|
||||||
|
0x8787D7,
|
||||||
|
0x8787FF,
|
||||||
|
0x87AF00,
|
||||||
|
0x87AF5F,
|
||||||
|
0x87AF87,
|
||||||
|
0x87AFAF,
|
||||||
|
0x87AFD7,
|
||||||
|
0x87AFFF,
|
||||||
|
0x87D700,
|
||||||
|
0x87D75F,
|
||||||
|
0x87D787,
|
||||||
|
0x87D7AF,
|
||||||
|
0x87D7D7,
|
||||||
|
0x87D7FF,
|
||||||
|
0x87FF00,
|
||||||
|
0x87FF5F,
|
||||||
|
0x87FF87,
|
||||||
|
0x87FFAF,
|
||||||
|
0x87FFD7,
|
||||||
|
0x87FFFF,
|
||||||
|
0xAF0000,
|
||||||
|
0xAF005F,
|
||||||
|
0xAF0087,
|
||||||
|
0xAF00AF,
|
||||||
|
0xAF00D7,
|
||||||
|
0xAF00FF,
|
||||||
|
0xAF5F00,
|
||||||
|
0xAF5F5F,
|
||||||
|
0xAF5F87,
|
||||||
|
0xAF5FAF,
|
||||||
|
0xAF5FD7,
|
||||||
|
0xAF5FFF,
|
||||||
|
0xAF8700,
|
||||||
|
0xAF875F,
|
||||||
|
0xAF8787,
|
||||||
|
0xAF87AF,
|
||||||
|
0xAF87D7,
|
||||||
|
0xAF87FF,
|
||||||
|
0xAFAF00,
|
||||||
|
0xAFAF5F,
|
||||||
|
0xAFAF87,
|
||||||
|
0xAFAFAF,
|
||||||
|
0xAFAFD7,
|
||||||
|
0xAFAFFF,
|
||||||
|
0xAFD700,
|
||||||
|
0xAFD75F,
|
||||||
|
0xAFD787,
|
||||||
|
0xAFD7AF,
|
||||||
|
0xAFD7D7,
|
||||||
|
0xAFD7FF,
|
||||||
|
0xAFFF00,
|
||||||
|
0xAFFF5F,
|
||||||
|
0xAFFF87,
|
||||||
|
0xAFFFAF,
|
||||||
|
0xAFFFD7,
|
||||||
|
0xAFFFFF,
|
||||||
|
0xD70000,
|
||||||
|
0xD7005F,
|
||||||
|
0xD70087,
|
||||||
|
0xD700AF,
|
||||||
|
0xD700D7,
|
||||||
|
0xD700FF,
|
||||||
|
0xD75F00,
|
||||||
|
0xD75F5F,
|
||||||
|
0xD75F87,
|
||||||
|
0xD75FAF,
|
||||||
|
0xD75FD7,
|
||||||
|
0xD75FFF,
|
||||||
|
0xD78700,
|
||||||
|
0xD7875F,
|
||||||
|
0xD78787,
|
||||||
|
0xD787AF,
|
||||||
|
0xD787D7,
|
||||||
|
0xD787FF,
|
||||||
|
0xD7AF00,
|
||||||
|
0xD7AF5F,
|
||||||
|
0xD7AF87,
|
||||||
|
0xD7AFAF,
|
||||||
|
0xD7AFD7,
|
||||||
|
0xD7AFFF,
|
||||||
|
0xD7D700,
|
||||||
|
0xD7D75F,
|
||||||
|
0xD7D787,
|
||||||
|
0xD7D7AF,
|
||||||
|
0xD7D7D7,
|
||||||
|
0xD7D7FF,
|
||||||
|
0xD7FF00,
|
||||||
|
0xD7FF5F,
|
||||||
|
0xD7FF87,
|
||||||
|
0xD7FFAF,
|
||||||
|
0xD7FFD7,
|
||||||
|
0xD7FFFF,
|
||||||
|
0xFF0000,
|
||||||
|
0xFF005F,
|
||||||
|
0xFF0087,
|
||||||
|
0xFF00AF,
|
||||||
|
0xFF00D7,
|
||||||
|
0xFF00FF,
|
||||||
|
0xFF5F00,
|
||||||
|
0xFF5F5F,
|
||||||
|
0xFF5F87,
|
||||||
|
0xFF5FAF,
|
||||||
|
0xFF5FD7,
|
||||||
|
0xFF5FFF,
|
||||||
|
0xFF8700,
|
||||||
|
0xFF875F,
|
||||||
|
0xFF8787,
|
||||||
|
0xFF87AF,
|
||||||
|
0xFF87D7,
|
||||||
|
0xFF87FF,
|
||||||
|
0xFFAF00,
|
||||||
|
0xFFAF5F,
|
||||||
|
0xFFAF87,
|
||||||
|
0xFFAFAF,
|
||||||
|
0xFFAFD7,
|
||||||
|
0xFFAFFF,
|
||||||
|
0xFFD700,
|
||||||
|
0xFFD75F,
|
||||||
|
0xFFD787,
|
||||||
|
0xFFD7AF,
|
||||||
|
0xFFD7D7,
|
||||||
|
0xFFD7FF,
|
||||||
|
0xFFFF00,
|
||||||
|
0xFFFF5F,
|
||||||
|
0xFFFF87,
|
||||||
|
0xFFFFAF,
|
||||||
|
0xFFFFD7,
|
||||||
|
0xFFFFFF,
|
||||||
|
0x080808,
|
||||||
|
0x121212,
|
||||||
|
0x1C1C1C,
|
||||||
|
0x262626,
|
||||||
|
0x303030,
|
||||||
|
0x3A3A3A,
|
||||||
|
0x444444,
|
||||||
|
0x4E4E4E,
|
||||||
|
0x585858,
|
||||||
|
0x626262,
|
||||||
|
0x6C6C6C,
|
||||||
|
0x767676,
|
||||||
|
0x808080,
|
||||||
|
0x8A8A8A,
|
||||||
|
0x949494,
|
||||||
|
0x9E9E9E,
|
||||||
|
0xA8A8A8,
|
||||||
|
0xB2B2B2,
|
||||||
|
0xBCBCBC,
|
||||||
|
0xC6C6C6,
|
||||||
|
0xD0D0D0,
|
||||||
|
0xDADADA,
|
||||||
|
0xE4E4E4,
|
||||||
|
0xEEEEEE,
|
||||||
|
};
|
||||||
|
}
|
|
@ -22,4 +22,5 @@ public class TickEvent : EventArgs
|
||||||
{
|
{
|
||||||
public GameTime GameTime { get; set; }
|
public GameTime GameTime { get; set; }
|
||||||
public ulong TotalTicks { get; set; }
|
public ulong TotalTicks { get; set; }
|
||||||
|
public bool IsActiveTick { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace Capy64;
|
||||||
public interface IGame
|
public interface IGame
|
||||||
{
|
{
|
||||||
Capy64 Game { get; }
|
Capy64 Game { get; }
|
||||||
|
EngineMode EngineMode { get; }
|
||||||
IList<IComponent> NativePlugins { get; }
|
IList<IComponent> NativePlugins { get; }
|
||||||
IList<IComponent> Plugins { get; }
|
IList<IComponent> Plugins { get; }
|
||||||
GameWindow Window { get; }
|
GameWindow Window { get; }
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class Event : IComponent
|
||||||
return nargs;
|
return nargs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int L_Pull(IntPtr state)
|
public static int L_Pull(IntPtr state)
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,16 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
using Capy64.API;
|
using Capy64.API;
|
||||||
|
using Capy64.Core;
|
||||||
using Capy64.Runtime.Objects;
|
using Capy64.Runtime.Objects;
|
||||||
using KeraLua;
|
using KeraLua;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using Microsoft.Xna.Framework.Input;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Capy64.Runtime.Libraries;
|
namespace Capy64.Runtime.Libraries;
|
||||||
|
|
||||||
|
@ -45,16 +48,6 @@ public class GPU : IComponent
|
||||||
function = L_SetSize,
|
function = L_SetSize,
|
||||||
},
|
},
|
||||||
new()
|
new()
|
||||||
{
|
|
||||||
name = "getScale",
|
|
||||||
function = L_GetScale,
|
|
||||||
},
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
name = "setScale",
|
|
||||||
function = L_SetScale,
|
|
||||||
},
|
|
||||||
new()
|
|
||||||
{
|
{
|
||||||
name = "getPixel",
|
name = "getPixel",
|
||||||
function = L_GetPixel,
|
function = L_GetPixel,
|
||||||
|
@ -131,8 +124,8 @@ public class GPU : IComponent
|
||||||
},
|
},
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
name = "loadImage",
|
name = "loadImageAsync",
|
||||||
function = L_LoadImage,
|
function = L_LoadImageAsync,
|
||||||
},
|
},
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
|
@ -153,6 +146,14 @@ public class GPU : IComponent
|
||||||
l.NewLib(gpuLib);
|
l.NewLib(gpuLib);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void GetColor(uint c, out byte r, out byte g, out byte b)
|
||||||
|
{
|
||||||
|
if (_game.EngineMode == EngineMode.Classic)
|
||||||
|
c = ColorPalette.GetColor(c);
|
||||||
|
Utils.UnpackRGB(c, out r, out g, out b);
|
||||||
|
}
|
||||||
|
|
||||||
private static int L_GetSize(IntPtr state)
|
private static int L_GetSize(IntPtr state)
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
@ -167,6 +168,12 @@ public class GPU : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
if (_game.EngineMode == EngineMode.Classic)
|
||||||
|
{
|
||||||
|
L.PushBoolean(false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
var w = L.CheckInteger(1);
|
var w = L.CheckInteger(1);
|
||||||
var h = L.CheckInteger(2);
|
var h = L.CheckInteger(2);
|
||||||
|
|
||||||
|
@ -175,31 +182,11 @@ public class GPU : IComponent
|
||||||
|
|
||||||
_game.UpdateSize();
|
_game.UpdateSize();
|
||||||
|
|
||||||
return 0;
|
L.PushBoolean(true);
|
||||||
}
|
|
||||||
|
|
||||||
private static int L_GetScale(IntPtr state)
|
|
||||||
{
|
|
||||||
var L = Lua.FromIntPtr(state);
|
|
||||||
|
|
||||||
L.PushNumber(_game.Scale);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int L_SetScale(IntPtr state)
|
|
||||||
{
|
|
||||||
var L = Lua.FromIntPtr(state);
|
|
||||||
|
|
||||||
var s = L.CheckNumber(1);
|
|
||||||
|
|
||||||
_game.Scale = (float)s;
|
|
||||||
|
|
||||||
_game.UpdateSize();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int L_GetPixel(IntPtr state)
|
private static int L_GetPixel(IntPtr state)
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
@ -222,7 +209,7 @@ public class GPU : IComponent
|
||||||
var y = (int)L.CheckNumber(2) - 1;
|
var y = (int)L.CheckNumber(2) - 1;
|
||||||
var c = L.CheckInteger(3);
|
var c = L.CheckInteger(3);
|
||||||
|
|
||||||
Utils.UnpackRGB((uint)c, out var r, out var g, out var b);
|
GetColor((uint)c, out var r, out var g, out var b);
|
||||||
_game.Drawing.Plot(new Point(x, y), new Color(r, g, b));
|
_game.Drawing.Plot(new Point(x, y), new Color(r, g, b));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -257,7 +244,7 @@ public class GPU : IComponent
|
||||||
pts.Add(new Point(x, y));
|
pts.Add(new Point(x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils.UnpackRGB((uint)c, out var r, out var g, out var b);
|
GetColor((uint)c, out var r, out var g, out var b);
|
||||||
_game.Drawing.Plot(pts, new(r, g, b));
|
_game.Drawing.Plot(pts, new(r, g, b));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -272,7 +259,7 @@ public class GPU : IComponent
|
||||||
var c = L.CheckInteger(3);
|
var c = L.CheckInteger(3);
|
||||||
var s = (int)L.OptNumber(4, 1);
|
var s = (int)L.OptNumber(4, 1);
|
||||||
|
|
||||||
Utils.UnpackRGB((uint)c, out var r, out var g, out var b);
|
GetColor((uint)c, out var r, out var g, out var b);
|
||||||
_game.Drawing.DrawPoint(new(x, y), new Color(r, g, b), s);
|
_game.Drawing.DrawPoint(new(x, y), new Color(r, g, b), s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -289,7 +276,7 @@ public class GPU : IComponent
|
||||||
var t = (int)L.OptNumber(5, 1);
|
var t = (int)L.OptNumber(5, 1);
|
||||||
var s = (int)L.OptInteger(6, -1);
|
var s = (int)L.OptInteger(6, -1);
|
||||||
|
|
||||||
Utils.UnpackRGB((uint)c, out var r, out var g, out var b);
|
GetColor((uint)c, out var r, out var g, out var b);
|
||||||
_game.Drawing.DrawCircle(new(x, y), rad, new Color(r, g, b), t, s);
|
_game.Drawing.DrawCircle(new(x, y), rad, new Color(r, g, b), t, s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -306,7 +293,7 @@ public class GPU : IComponent
|
||||||
var c = L.CheckInteger(5);
|
var c = L.CheckInteger(5);
|
||||||
var s = (int)L.OptNumber(6, 1);
|
var s = (int)L.OptNumber(6, 1);
|
||||||
|
|
||||||
Utils.UnpackRGB((uint)c, out var r, out var g, out var b);
|
GetColor((uint)c, out var r, out var g, out var b);
|
||||||
_game.Drawing.DrawLine(new(x1, y1), new(x2, y2), new Color(r, g, b), s);
|
_game.Drawing.DrawLine(new(x1, y1), new(x2, y2), new Color(r, g, b), s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -323,7 +310,7 @@ public class GPU : IComponent
|
||||||
var c = L.CheckInteger(5);
|
var c = L.CheckInteger(5);
|
||||||
var s = (int)L.OptNumber(6, 1);
|
var s = (int)L.OptNumber(6, 1);
|
||||||
|
|
||||||
Utils.UnpackRGB((uint)c, out var r, out var g, out var b);
|
GetColor((uint)c, out var r, out var g, out var b);
|
||||||
_game.Drawing.DrawRectangle(new(x, y), new(w, h), new Color(r, g, b), s);
|
_game.Drawing.DrawRectangle(new(x, y), new(w, h), new Color(r, g, b), s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -359,7 +346,7 @@ public class GPU : IComponent
|
||||||
pts.Add(new(xp, yp));
|
pts.Add(new(xp, yp));
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils.UnpackRGB((uint)c, out var r, out var g, out var b);
|
GetColor((uint)c, out var r, out var g, out var b);
|
||||||
_game.Drawing.DrawPolygon(new(x, y), pts.ToArray(), new(r, g, b), s);
|
_game.Drawing.DrawPolygon(new(x, y), pts.ToArray(), new(r, g, b), s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -376,7 +363,7 @@ public class GPU : IComponent
|
||||||
var c = L.CheckInteger(5);
|
var c = L.CheckInteger(5);
|
||||||
var s = (int)L.OptNumber(6, 1);
|
var s = (int)L.OptNumber(6, 1);
|
||||||
|
|
||||||
Utils.UnpackRGB((uint)c, out var r, out var g, out var b);
|
GetColor((uint)c, out var r, out var g, out var b);
|
||||||
_game.Drawing.DrawEllipse(new(x, y), new(rx, ry), new Color(r, g, b), s);
|
_game.Drawing.DrawEllipse(new(x, y), new(rx, ry), new Color(r, g, b), s);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -391,7 +378,7 @@ public class GPU : IComponent
|
||||||
var c = L.CheckInteger(3);
|
var c = L.CheckInteger(3);
|
||||||
var t = L.CheckString(4);
|
var t = L.CheckString(4);
|
||||||
|
|
||||||
Utils.UnpackRGB((uint)c, out var r, out var g, out var b);
|
GetColor((uint)c, out var r, out var g, out var b);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_game.Drawing.DrawString(new Vector2(x, y), t, new Color(r, g, b));
|
_game.Drawing.DrawString(new Vector2(x, y), t, new Color(r, g, b));
|
||||||
|
@ -426,8 +413,7 @@ public class GPU : IComponent
|
||||||
_game.Drawing.Canvas.GetData(buffer);
|
_game.Drawing.Canvas.GetData(buffer);
|
||||||
|
|
||||||
ObjectManager.PushObject(L, buffer);
|
ObjectManager.PushObject(L, buffer);
|
||||||
//L.PushObject(buffer);
|
L.SetMetaTable(GPUBufferMeta.ObjectType);
|
||||||
L.SetMetaTable(GPUBuffer.ObjectType);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -436,9 +422,9 @@ public class GPU : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
var buffer = GPUBuffer.CheckBuffer(L, false);
|
var buffer = GPUBufferMeta.CheckBuffer(L, false);
|
||||||
|
|
||||||
_game.Drawing.Canvas.SetData(buffer);
|
_game.Drawing.Canvas.SetData(buffer.Buffer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -453,7 +439,7 @@ public class GPU : IComponent
|
||||||
var buffer = new uint[width * height];
|
var buffer = new uint[width * height];
|
||||||
|
|
||||||
ObjectManager.PushObject(L, buffer);
|
ObjectManager.PushObject(L, buffer);
|
||||||
L.SetMetaTable(GPUBuffer.ObjectType);
|
L.SetMetaTable(GPUBufferMeta.ObjectType);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -462,30 +448,23 @@ public class GPU : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
var buffer = GPUBuffer.CheckBuffer(L, false);
|
var buffer = GPUBufferMeta.CheckBuffer(L, false);
|
||||||
|
|
||||||
var x = (int)L.CheckInteger(2) - 1;
|
var x = (int)L.CheckInteger(2) - 1;
|
||||||
var y = (int)L.CheckInteger(3) - 1;
|
var y = (int)L.CheckInteger(3) - 1;
|
||||||
var w = (int)L.CheckInteger(4);
|
|
||||||
var h = (int)L.CheckInteger(5);
|
|
||||||
|
|
||||||
if (w * h != buffer.Length)
|
_game.Drawing.DrawBuffer(buffer.Buffer, new()
|
||||||
{
|
|
||||||
L.Error("width and height do not match buffer size");
|
|
||||||
}
|
|
||||||
|
|
||||||
_game.Drawing.DrawBuffer(buffer, new()
|
|
||||||
{
|
{
|
||||||
X = x,
|
X = x,
|
||||||
Y = y,
|
Y = y,
|
||||||
Width = w,
|
Width = buffer.Width,
|
||||||
Height = h,
|
Height = buffer.Height,
|
||||||
});
|
});
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int L_LoadImage(IntPtr state)
|
private static int L_LoadImageAsync(IntPtr state)
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
@ -499,6 +478,8 @@ public class GPU : IComponent
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var task = TaskMeta.Push(L, GPUBufferMeta.ObjectType);
|
||||||
|
|
||||||
Texture2D texture;
|
Texture2D texture;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -506,21 +487,52 @@ public class GPU : IComponent
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
L.Error(e.Message);
|
task.Reject(e.Message);
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = new uint[texture.Width * texture.Height];
|
var data = new uint[texture.Width * texture.Height];
|
||||||
texture.GetData(data);
|
texture.GetData(data);
|
||||||
|
|
||||||
ObjectManager.PushObject(L, data);
|
Task.Run(() =>
|
||||||
L.SetMetaTable(GPUBuffer.ObjectType);
|
{
|
||||||
L.PushInteger(texture.Width);
|
if (_game.EngineMode == EngineMode.Classic)
|
||||||
L.PushInteger(texture.Height);
|
{
|
||||||
|
for (int i = 0; i < data.Length; i++)
|
||||||
|
{
|
||||||
|
var value = data[i];
|
||||||
|
|
||||||
texture.Dispose();
|
// ABGR to RGB
|
||||||
|
value =
|
||||||
|
((value & 0x00_00_00_FFU) << 16) | // move R
|
||||||
|
(value & 0x00_00_FF_00U) | // move G
|
||||||
|
((value & 0x00_FF_00_00U) >> 16); // move B
|
||||||
|
|
||||||
return 3;
|
value = ColorPalette.GetColor(value);
|
||||||
|
|
||||||
|
// RGB to ABGR
|
||||||
|
value =
|
||||||
|
((value & 0x00_FF_00_00U) >> 16) | // move R
|
||||||
|
(value & 0x00_00_FF_00U) | // move G
|
||||||
|
((value & 0x00_00_00_FFU) << 16) | // move B
|
||||||
|
0xFF_00_00_00U;
|
||||||
|
|
||||||
|
data[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var buffer = new GPUBufferMeta.GPUBuffer
|
||||||
|
{
|
||||||
|
Buffer = data,
|
||||||
|
Height = texture.Height,
|
||||||
|
Width = texture.Width,
|
||||||
|
};
|
||||||
|
task.Fulfill(buffer);
|
||||||
|
|
||||||
|
texture.Dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int L_Clear(IntPtr state)
|
private static int L_Clear(IntPtr state)
|
||||||
|
@ -529,7 +541,7 @@ public class GPU : IComponent
|
||||||
|
|
||||||
var c = L.OptInteger(1, 0x000000);
|
var c = L.OptInteger(1, 0x000000);
|
||||||
|
|
||||||
Utils.UnpackRGB((uint)c, out var r, out var g, out var b);
|
GetColor((uint)c, out var r, out var g, out var b);
|
||||||
_game.Drawing.Clear(new Color(r, g, b));
|
_game.Drawing.Clear(new Color(r, g, b));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -72,6 +72,11 @@ public class Machine : IComponent
|
||||||
name = "getClipboard",
|
name = "getClipboard",
|
||||||
function = L_GetClipboard,
|
function = L_GetClipboard,
|
||||||
},
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "task",
|
||||||
|
function = L_Task,
|
||||||
|
},
|
||||||
new(),
|
new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -87,6 +92,18 @@ public class Machine : IComponent
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int L_Task(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
var task = new Objects.TaskMeta.RuntimeTask("test");
|
||||||
|
|
||||||
|
ObjectManager.PushObject(L, task);
|
||||||
|
L.SetMetaTable(Objects.TaskMeta.ObjectType);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
private static int L_Shutdown(IntPtr _)
|
private static int L_Shutdown(IntPtr _)
|
||||||
{
|
{
|
||||||
RuntimeManager.Shutdown();
|
RuntimeManager.Shutdown();
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
using Capy64.API;
|
using Capy64.API;
|
||||||
|
using Capy64.Core;
|
||||||
using Capy64.Eventing.Events;
|
using Capy64.Eventing.Events;
|
||||||
using KeraLua;
|
using KeraLua;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
|
@ -174,6 +175,13 @@ internal class Term : IComponent
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void GetColor(uint c, out byte r, out byte g, out byte b)
|
||||||
|
{
|
||||||
|
if (_game.EngineMode == EngineMode.Classic)
|
||||||
|
c = ColorPalette.GetColor(c);
|
||||||
|
UnpackRGB(c, out r, out g, out b);
|
||||||
|
}
|
||||||
|
|
||||||
public static void UpdateSize(bool resize = true)
|
public static void UpdateSize(bool resize = true)
|
||||||
{
|
{
|
||||||
Array.Resize(ref CharGrid, Width * Height);
|
Array.Resize(ref CharGrid, Width * Height);
|
||||||
|
@ -388,6 +396,12 @@ internal class Term : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
if(_game.EngineMode == EngineMode.Classic)
|
||||||
|
{
|
||||||
|
L.PushBoolean(false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
var w = (int)L.CheckNumber(1);
|
var w = (int)L.CheckNumber(1);
|
||||||
var h = (int)L.CheckNumber(2);
|
var h = (int)L.CheckNumber(2);
|
||||||
|
|
||||||
|
@ -402,7 +416,8 @@ internal class Term : IComponent
|
||||||
|
|
||||||
SetSize(w, h);
|
SetSize(w, h);
|
||||||
|
|
||||||
return 0;
|
L.PushBoolean(true);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int L_GetForegroundColor(IntPtr state)
|
private static int L_GetForegroundColor(IntPtr state)
|
||||||
|
@ -427,12 +442,14 @@ internal class Term : IComponent
|
||||||
r = (byte)L.CheckNumber(1);
|
r = (byte)L.CheckNumber(1);
|
||||||
g = (byte)L.CheckNumber(2);
|
g = (byte)L.CheckNumber(2);
|
||||||
b = (byte)L.CheckNumber(3);
|
b = (byte)L.CheckNumber(3);
|
||||||
|
UnpackRGB(ColorPalette.GetColor(r, g, b), out r, out g, out b);
|
||||||
|
|
||||||
}
|
}
|
||||||
// packed RGB value
|
// packed RGB value
|
||||||
else if (argsn == 1)
|
else if (argsn == 1)
|
||||||
{
|
{
|
||||||
var c = (uint)L.CheckInteger(1);
|
var c = (uint)L.CheckInteger(1);
|
||||||
UnpackRGB(c, out r, out g, out b);
|
GetColor(c, out r, out g, out b);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -467,12 +484,13 @@ internal class Term : IComponent
|
||||||
r = (byte)L.CheckNumber(1);
|
r = (byte)L.CheckNumber(1);
|
||||||
g = (byte)L.CheckNumber(2);
|
g = (byte)L.CheckNumber(2);
|
||||||
b = (byte)L.CheckNumber(3);
|
b = (byte)L.CheckNumber(3);
|
||||||
|
UnpackRGB(ColorPalette.GetColor(r, g, b), out r, out g, out b);
|
||||||
}
|
}
|
||||||
// packed RGB value
|
// packed RGB value
|
||||||
else if (argsn == 1)
|
else if (argsn == 1)
|
||||||
{
|
{
|
||||||
var c = (uint)L.CheckInteger(1);
|
var c = (uint)L.CheckInteger(1);
|
||||||
UnpackRGB(c, out r, out g, out b);
|
GetColor(c, out r, out g, out b);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,15 +14,23 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
using Capy64.API;
|
using Capy64.API;
|
||||||
|
using Capy64.Core;
|
||||||
using KeraLua;
|
using KeraLua;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Capy64.Runtime.Objects;
|
namespace Capy64.Runtime.Objects;
|
||||||
|
|
||||||
public class GPUBuffer : IComponent
|
public class GPUBufferMeta : IComponent
|
||||||
{
|
{
|
||||||
public const string ObjectType = "GPUBuffer";
|
public const string ObjectType = "GPUBuffer";
|
||||||
|
|
||||||
|
public struct GPUBuffer
|
||||||
|
{
|
||||||
|
public uint[] Buffer { get; set; }
|
||||||
|
public int Width { get; set; }
|
||||||
|
public int Height { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
private static LuaRegister[] MetaMethods = new LuaRegister[]
|
private static LuaRegister[] MetaMethods = new LuaRegister[]
|
||||||
{
|
{
|
||||||
new()
|
new()
|
||||||
|
@ -59,29 +67,43 @@ public class GPUBuffer : IComponent
|
||||||
new(),
|
new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static IGame _game;
|
||||||
|
public GPUBufferMeta(IGame game)
|
||||||
|
{
|
||||||
|
_game = game;
|
||||||
|
}
|
||||||
|
|
||||||
public void LuaInit(Lua L)
|
public void LuaInit(Lua L)
|
||||||
{
|
{
|
||||||
CreateMeta(L);
|
CreateMeta(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static uint GetColor(uint color)
|
||||||
|
{
|
||||||
|
if (_game.EngineMode == EngineMode.Classic)
|
||||||
|
return ColorPalette.GetColor(color);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
public static void CreateMeta(Lua L)
|
public static void CreateMeta(Lua L)
|
||||||
{
|
{
|
||||||
L.NewMetaTable(ObjectType);
|
L.NewMetaTable(ObjectType);
|
||||||
L.SetFuncs(MetaMethods, 0);
|
L.SetFuncs(MetaMethods, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static uint[] ToBuffer(Lua L, bool gc = false)
|
public static GPUBuffer ToBuffer(Lua L, bool gc = false)
|
||||||
{
|
{
|
||||||
return ObjectManager.ToObject<uint[]>(L, 1, gc);
|
return ObjectManager.ToObject<GPUBuffer>(L, 1, gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static uint[] CheckBuffer(Lua L, bool gc = false)
|
public static GPUBuffer CheckBuffer(Lua L, bool gc = false)
|
||||||
{
|
{
|
||||||
var obj = ObjectManager.CheckObject<uint[]>(L, 1, ObjectType, gc);
|
var obj = ObjectManager.CheckObject<GPUBuffer>(L, 1, ObjectType, gc);
|
||||||
if (obj is null)
|
if (obj.Buffer is null)
|
||||||
{
|
{
|
||||||
L.Error("attempt to use a closed buffer");
|
L.Error("attempt to use a closed buffer");
|
||||||
return null;
|
return default;
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -94,19 +116,27 @@ public class GPUBuffer : IComponent
|
||||||
|
|
||||||
if (!L.IsInteger(2))
|
if (!L.IsInteger(2))
|
||||||
{
|
{
|
||||||
L.PushNil();
|
var vkey = L.ToString(2);
|
||||||
|
|
||||||
|
if (vkey == "width")
|
||||||
|
L.PushInteger(buffer.Width);
|
||||||
|
else if (vkey == "height")
|
||||||
|
L.PushInteger(buffer.Height);
|
||||||
|
else
|
||||||
|
L.PushNil();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = L.ToInteger(2);
|
var key = L.ToInteger(2);
|
||||||
|
|
||||||
if (key < 0 || key >= buffer.Length)
|
if (key < 0 || key >= buffer.Buffer.Length)
|
||||||
{
|
{
|
||||||
L.PushNil();
|
L.PushNil();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var value = buffer[key];
|
var value = buffer.Buffer[key];
|
||||||
|
|
||||||
// ABGR to RGB
|
// ABGR to RGB
|
||||||
value =
|
value =
|
||||||
|
@ -131,7 +161,7 @@ public class GPUBuffer : IComponent
|
||||||
|
|
||||||
var key = L.ToInteger(2);
|
var key = L.ToInteger(2);
|
||||||
|
|
||||||
if (key < 0 || key >= buffer.Length)
|
if (key < 0 || key >= buffer.Buffer.Length)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -142,6 +172,7 @@ public class GPUBuffer : IComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
var value = (uint)L.ToInteger(3);
|
var value = (uint)L.ToInteger(3);
|
||||||
|
value = GetColor(value);
|
||||||
|
|
||||||
// RGB to ABGR
|
// RGB to ABGR
|
||||||
value =
|
value =
|
||||||
|
@ -151,7 +182,7 @@ public class GPUBuffer : IComponent
|
||||||
0xFF_00_00_00U;
|
0xFF_00_00_00U;
|
||||||
|
|
||||||
|
|
||||||
buffer[key] = value;
|
buffer.Buffer[key] = value;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +202,7 @@ public class GPUBuffer : IComponent
|
||||||
|
|
||||||
var buffer = CheckBuffer(L, false);
|
var buffer = CheckBuffer(L, false);
|
||||||
|
|
||||||
L.PushInteger(buffer.LongLength);
|
L.PushInteger(buffer.Buffer.LongLength);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +211,7 @@ public class GPUBuffer : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
var buffer = ToBuffer(L);
|
var buffer = ToBuffer(L);
|
||||||
if (buffer is not null)
|
if (buffer.Buffer is not null)
|
||||||
{
|
{
|
||||||
L.PushString("GPUBuffer ({0:X})", (ulong)&buffer);
|
L.PushString("GPUBuffer ({0:X})", (ulong)&buffer);
|
||||||
}
|
}
|
335
Capy64/Runtime/Objects/Task.cs
Normal file
335
Capy64/Runtime/Objects/Task.cs
Normal file
|
@ -0,0 +1,335 @@
|
||||||
|
// 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").
|
||||||
|
// 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 Cyotek.Drawing.BitmapFont;
|
||||||
|
using KeraLua;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Capy64.Runtime.Objects;
|
||||||
|
|
||||||
|
public class TaskMeta : IComponent
|
||||||
|
{
|
||||||
|
private static IGame _game;
|
||||||
|
public TaskMeta(IGame game)
|
||||||
|
{
|
||||||
|
_game = game;
|
||||||
|
}
|
||||||
|
|
||||||
|
public const string ObjectType = "Task";
|
||||||
|
|
||||||
|
public enum TaskStatus
|
||||||
|
{
|
||||||
|
Running,
|
||||||
|
Succeeded,
|
||||||
|
Failed,
|
||||||
|
}
|
||||||
|
public class RuntimeTask
|
||||||
|
{
|
||||||
|
public RuntimeTask(string typeName)
|
||||||
|
{
|
||||||
|
TypeName = typeName;
|
||||||
|
}
|
||||||
|
public Guid Guid { get; set; } = Guid.NewGuid();
|
||||||
|
public string TypeName { get; set; }
|
||||||
|
public TaskStatus Status { get; set; } = TaskStatus.Running;
|
||||||
|
public object Result { get; private set; }
|
||||||
|
public string Error { get; private set; }
|
||||||
|
|
||||||
|
public void Fulfill<T>(T obj)
|
||||||
|
{
|
||||||
|
Status = TaskStatus.Succeeded;
|
||||||
|
|
||||||
|
Result = obj;
|
||||||
|
|
||||||
|
_game.LuaRuntime.QueueEvent("task_finish", LK =>
|
||||||
|
{
|
||||||
|
LK.PushString(Guid.ToString());
|
||||||
|
|
||||||
|
ObjectManager.PushObject(LK, obj);
|
||||||
|
LK.SetMetaTable(TypeName);
|
||||||
|
|
||||||
|
LK.PushNil();
|
||||||
|
|
||||||
|
return 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Fulfill(Action<Lua> lk)
|
||||||
|
{
|
||||||
|
Status = TaskStatus.Succeeded;
|
||||||
|
|
||||||
|
Result = lk;
|
||||||
|
|
||||||
|
_game.LuaRuntime.QueueEvent("task_finish", LK =>
|
||||||
|
{
|
||||||
|
LK.PushString(Guid.ToString());
|
||||||
|
|
||||||
|
lk(LK);
|
||||||
|
|
||||||
|
LK.PushNil();
|
||||||
|
|
||||||
|
return 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reject(string error, params object[] args)
|
||||||
|
{
|
||||||
|
Status = TaskStatus.Failed;
|
||||||
|
Error = string.Format(error, args);
|
||||||
|
|
||||||
|
_game.LuaRuntime.QueueEvent("task_finish", LK =>
|
||||||
|
{
|
||||||
|
LK.PushString(Guid.ToString());
|
||||||
|
|
||||||
|
LK.PushNil();
|
||||||
|
|
||||||
|
LK.PushString(Error);
|
||||||
|
|
||||||
|
return 3;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static LuaRegister[] Methods = new LuaRegister[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "await",
|
||||||
|
function = L_Await,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "getID",
|
||||||
|
function = L_GetID,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "getType",
|
||||||
|
function = L_GetType,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "getStatus",
|
||||||
|
function = L_GetStatus,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "getResult",
|
||||||
|
function = L_GetResult,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "getError",
|
||||||
|
function = L_GetResult,
|
||||||
|
},
|
||||||
|
new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
private static LuaRegister[] MetaMethods = new LuaRegister[]
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "__index",
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "__gc",
|
||||||
|
function = LM_GC,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "__close",
|
||||||
|
function = LM_GC,
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
name = "__tostring",
|
||||||
|
function = LM_ToString,
|
||||||
|
},
|
||||||
|
|
||||||
|
new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
public void LuaInit(Lua L)
|
||||||
|
{
|
||||||
|
CreateMeta(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateMeta(Lua L)
|
||||||
|
{
|
||||||
|
L.NewMetaTable(ObjectType);
|
||||||
|
L.SetFuncs(MetaMethods, 0);
|
||||||
|
L.NewLibTable(Methods);
|
||||||
|
L.SetFuncs(Methods, 0);
|
||||||
|
L.SetField(-2, "__index");
|
||||||
|
L.Pop(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RuntimeTask Push(Lua L, string typeName)
|
||||||
|
{
|
||||||
|
var task = new RuntimeTask(typeName);
|
||||||
|
|
||||||
|
ObjectManager.PushObject(L, task);
|
||||||
|
L.SetMetaTable(ObjectType);
|
||||||
|
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RuntimeTask ToTask(Lua L, bool gc = false)
|
||||||
|
{
|
||||||
|
return ObjectManager.ToObject<RuntimeTask>(L, 1, gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RuntimeTask CheckTask(Lua L, bool gc = false)
|
||||||
|
{
|
||||||
|
var obj = ObjectManager.CheckObject<RuntimeTask>(L, 1, ObjectType, gc);
|
||||||
|
if (obj is null)
|
||||||
|
{
|
||||||
|
L.Error("attempt to use a closed file");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WaitForTask(Lua L)
|
||||||
|
{
|
||||||
|
L.PushCFunction(Libraries.Event.L_Pull);
|
||||||
|
L.PushString("task_finish");
|
||||||
|
L.CallK(1, 4, 0, LK_Await);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int L_Await(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
WaitForTask(L);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int LK_Await(IntPtr state, int status, nint ctx)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
var task = CheckTask(L, false);
|
||||||
|
var taskId = L.CheckString(3);
|
||||||
|
|
||||||
|
if (task.Guid.ToString() != taskId)
|
||||||
|
{
|
||||||
|
WaitForTask(L);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int L_GetID(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
var task = CheckTask(L, false);
|
||||||
|
|
||||||
|
L.PushString(task.Guid.ToString());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int L_GetType(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
var task = CheckTask(L, false);
|
||||||
|
|
||||||
|
L.PushString(task.TypeName);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int L_GetStatus(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
var task = CheckTask(L, false);
|
||||||
|
|
||||||
|
L.PushString(task.Status.ToString().ToLower());
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int L_GetResult(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
var task = CheckTask(L, false);
|
||||||
|
|
||||||
|
if (task.Status == TaskStatus.Succeeded)
|
||||||
|
{
|
||||||
|
if (task.Result is Action<Lua> lk)
|
||||||
|
{
|
||||||
|
// todo: make use of first-generated data
|
||||||
|
lk(L);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ObjectManager.PushObject(L, task.Result);
|
||||||
|
L.SetMetaTable(task.TypeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
L.PushNil();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int L_GetError(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
|
var task = CheckTask(L, false);
|
||||||
|
|
||||||
|
if (task.Status == TaskStatus.Failed)
|
||||||
|
{
|
||||||
|
L.PushString(task.Error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
L.PushNil();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int LM_GC(IntPtr state)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int LM_ToString(IntPtr state)
|
||||||
|
{
|
||||||
|
var L = Lua.FromIntPtr(state);
|
||||||
|
var task = ToTask(L);
|
||||||
|
L.PushString("Task<{0}>: {1} ({2})", task?.TypeName, task?.Guid, task?.Status);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -171,11 +171,11 @@ public class WebSocketClient : IComponent
|
||||||
var buffer = ToObject(L);
|
var buffer = ToObject(L);
|
||||||
if (buffer is not null)
|
if (buffer is not null)
|
||||||
{
|
{
|
||||||
L.PushString("GPUBuffer ({0:X})", (ulong)&buffer);
|
L.PushString("WebSocket ({0:X})", (ulong)&buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
L.PushString("GPUBuffer (closed)");
|
L.PushString("WebSocket (closed)");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,12 +123,6 @@ internal class RuntimeManager : IComponent
|
||||||
luaState.Thread.PushCFunction(L_Exit);
|
luaState.Thread.PushCFunction(L_Exit);
|
||||||
luaState.Thread.SetGlobal("exit");
|
luaState.Thread.SetGlobal("exit");
|
||||||
|
|
||||||
luaState.Thread.PushCFunction(L_SetConsole);
|
|
||||||
luaState.Thread.SetGlobal("setConsole");
|
|
||||||
|
|
||||||
luaState.Thread.PushCFunction(L_GetConsole);
|
|
||||||
luaState.Thread.SetGlobal("getConsole");
|
|
||||||
|
|
||||||
var status = luaState.Thread.LoadFile("Assets/bios.lua");
|
var status = luaState.Thread.LoadFile("Assets/bios.lua");
|
||||||
if (status != LuaStatus.OK)
|
if (status != LuaStatus.OK)
|
||||||
{
|
{
|
||||||
|
@ -219,26 +213,6 @@ internal class RuntimeManager : IComponent
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int L_SetConsole(IntPtr state)
|
|
||||||
{
|
|
||||||
var L = Lua.FromIntPtr(state);
|
|
||||||
|
|
||||||
var status = L.ToBoolean(1);
|
|
||||||
_game.Window.ToggleConsole(status);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int L_GetConsole(IntPtr state)
|
|
||||||
{
|
|
||||||
var L = Lua.FromIntPtr(state);
|
|
||||||
|
|
||||||
var status = _game.Window.IsConsoleVisible();
|
|
||||||
L.PushBoolean(status);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnInit(object sender, EventArgs e)
|
private void OnInit(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
Start();
|
Start();
|
||||||
|
@ -246,6 +220,7 @@ internal class RuntimeManager : IComponent
|
||||||
|
|
||||||
private void OnTick(object sender, TickEvent e)
|
private void OnTick(object sender, TickEvent e)
|
||||||
{
|
{
|
||||||
Resume();
|
if (e.IsActiveTick)
|
||||||
|
Resume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue