Classic mode

This commit is contained in:
Alessandro Proto 2023-03-05 22:12:50 +01:00
parent 341ed38897
commit e941a481ea
9 changed files with 433 additions and 88 deletions

View file

@ -35,7 +35,6 @@ term.setBackground(bg)
term.clear()
term.setSize(53, 20)
gpu.setScale(2)
local w, h = term.getSize()
@ -157,11 +156,6 @@ local function installOS()
promptKey()
end
local function toggleConsole()
local status = getConsole()
setConsole(not status)
end
term.setBlink(false)
local function setupScreen()
@ -170,10 +164,6 @@ local function setupScreen()
"Open data folder",
openDataFolder,
},
{
"Toggle console window",
toggleConsole,
},
{
"Install default OS",
installOS,

View file

@ -1,4 +1,8 @@
{
"EngineMode": 0,
"Window": {
"Scale": 2
},
"HTTP": {
"Enable": true,
"Blacklist": [],

View file

@ -20,6 +20,7 @@ using Capy64.Extensions;
using Capy64.Integrations;
using Capy64.PluginManager;
using Capy64.Runtime;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@ -33,9 +34,29 @@ using static Capy64.Utils;
namespace Capy64;
public enum EngineMode
{
Classic,
Free
}
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
{
@ -56,11 +77,12 @@ public class Capy64 : Game, IGame
public static Capy64 Instance { get; private set; }
public Capy64 Game => this;
public EngineMode EngineMode { get; private set; } = EngineMode.Classic;
public IList<IComponent> NativePlugins { get; private set; }
public IList<IComponent> Plugins { get; private set; }
public int Width { get; set; } = 320;
public int Height { get; set; } = 240;
public float Scale { get; set; } = 2f;
public int Width { get; set; } = DefaultParameters.Width;
public int Height { get; set; } = DefaultParameters.Height;
public float Scale { get; set; } = DefaultParameters.Scale;
public Drawing Drawing { get; private set; }
public Audio Audio { get; private set; }
public LuaState LuaRuntime { get; set; }
@ -83,6 +105,7 @@ public class Capy64 : Game, IGame
private readonly GraphicsDeviceManager _graphics;
private IServiceProvider _serviceProvider;
private ulong _totalTicks = 0;
private ulong tickrate = 0;
public Capy64()
{
@ -103,6 +126,27 @@ public class Capy64 : Game, IGame
_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)
{
if (resize)
@ -157,7 +201,7 @@ public class Capy64 : Game, IGame
private void ResetBorder()
{
var size = (int)(Scale * 1.5);
var size = (int)(Scale * DefaultParameters.BorderMultiplier);
Borders = new Borders
{
Top = size,
@ -169,8 +213,12 @@ public class Capy64 : Game, IGame
protected override void Initialize()
{
var configuration = _serviceProvider.GetService<IConfiguration>();
Window.Title = "Capy64 " + Version;
Scale = configuration.GetValue("Window:Scale", DefaultParameters.Scale);
ResetBorder();
UpdateSize();
@ -179,6 +227,8 @@ public class Capy64 : Game, IGame
InactiveSleepTime = new TimeSpan(0);
SetEngineMode(configuration.GetValue<EngineMode>("EngineMode", DefaultParameters.EngineMode));
Audio = new Audio();
NativePlugins = GetNativePlugins();
@ -222,7 +272,8 @@ public class Capy64 : Game, IGame
EventEmitter.RaiseTick(new()
{
GameTime = gameTime,
TotalTicks = _totalTicks
TotalTicks = _totalTicks,
IsActiveTick = _totalTicks % (60 / tickrate) == 0,
});
Drawing.End();

321
Capy64/Core/ColorPalette.cs Normal file
View 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,
};
}

View file

@ -22,4 +22,5 @@ public class TickEvent : EventArgs
{
public GameTime GameTime { get; set; }
public ulong TotalTicks { get; set; }
public bool IsActiveTick { get; set; }
}

View file

@ -26,6 +26,7 @@ namespace Capy64;
public interface IGame
{
Capy64 Game { get; }
EngineMode EngineMode { get; }
IList<IComponent> NativePlugins { get; }
IList<IComponent> Plugins { get; }
GameWindow Window { get; }

View file

@ -14,6 +14,7 @@
// limitations under the License.
using Capy64.API;
using Capy64.Core;
using Capy64.Runtime.Objects;
using KeraLua;
using Microsoft.Xna.Framework;
@ -45,16 +46,6 @@ public class GPU : IComponent
function = L_SetSize,
},
new()
{
name = "getScale",
function = L_GetScale,
},
new()
{
name = "setScale",
function = L_SetScale,
},
new()
{
name = "getPixel",
function = L_GetPixel,
@ -153,6 +144,14 @@ public class GPU : IComponent
l.NewLib(gpuLib);
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)
{
var L = Lua.FromIntPtr(state);
@ -167,6 +166,12 @@ public class GPU : IComponent
{
var L = Lua.FromIntPtr(state);
if (_game.EngineMode == EngineMode.Classic)
{
L.PushBoolean(false);
return 1;
}
var w = L.CheckInteger(1);
var h = L.CheckInteger(2);
@ -175,31 +180,11 @@ public class GPU : IComponent
_game.UpdateSize();
return 0;
}
private static int L_GetScale(IntPtr state)
{
var L = Lua.FromIntPtr(state);
L.PushNumber(_game.Scale);
L.PushBoolean(true);
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)
{
var L = Lua.FromIntPtr(state);
@ -222,7 +207,7 @@ public class GPU : IComponent
var y = (int)L.CheckNumber(2) - 1;
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));
return 0;
@ -257,7 +242,7 @@ public class GPU : IComponent
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));
return 0;
@ -272,7 +257,7 @@ public class GPU : IComponent
var c = L.CheckInteger(3);
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);
return 0;
@ -289,7 +274,7 @@ public class GPU : IComponent
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);
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);
return 0;
@ -306,7 +291,7 @@ public class GPU : IComponent
var c = L.CheckInteger(5);
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);
return 0;
@ -323,7 +308,7 @@ public class GPU : IComponent
var c = L.CheckInteger(5);
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);
return 0;
@ -359,7 +344,7 @@ public class GPU : IComponent
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);
return 0;
@ -376,7 +361,7 @@ public class GPU : IComponent
var c = L.CheckInteger(5);
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);
return 0;
@ -391,7 +376,7 @@ public class GPU : IComponent
var c = L.CheckInteger(3);
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
{
_game.Drawing.DrawString(new Vector2(x, y), t, new Color(r, g, b));
@ -426,7 +411,6 @@ public class GPU : IComponent
_game.Drawing.Canvas.GetData(buffer);
ObjectManager.PushObject(L, buffer);
//L.PushObject(buffer);
L.SetMetaTable(GPUBuffer.ObjectType);
return 1;
@ -529,7 +513,7 @@ public class GPU : IComponent
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));
return 0;

View file

@ -14,6 +14,7 @@
// limitations under the License.
using Capy64.API;
using Capy64.Core;
using Capy64.Eventing.Events;
using KeraLua;
using Microsoft.Xna.Framework;
@ -174,6 +175,13 @@ internal class Term : IComponent
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)
{
Array.Resize(ref CharGrid, Width * Height);
@ -388,6 +396,12 @@ internal class Term : IComponent
{
var L = Lua.FromIntPtr(state);
if(_game.EngineMode == EngineMode.Classic)
{
L.PushBoolean(false);
return 1;
}
var w = (int)L.CheckNumber(1);
var h = (int)L.CheckNumber(2);
@ -402,7 +416,8 @@ internal class Term : IComponent
SetSize(w, h);
return 0;
L.PushBoolean(true);
return 1;
}
private static int L_GetForegroundColor(IntPtr state)
@ -427,12 +442,14 @@ internal class Term : IComponent
r = (byte)L.CheckNumber(1);
g = (byte)L.CheckNumber(2);
b = (byte)L.CheckNumber(3);
UnpackRGB(ColorPalette.GetColor(r, g, b), out r, out g, out b);
}
// packed RGB value
else if (argsn == 1)
{
var c = (uint)L.CheckInteger(1);
UnpackRGB(c, out r, out g, out b);
GetColor(c, out r, out g, out b);
}
else
{
@ -467,12 +484,13 @@ internal class Term : IComponent
r = (byte)L.CheckNumber(1);
g = (byte)L.CheckNumber(2);
b = (byte)L.CheckNumber(3);
UnpackRGB(ColorPalette.GetColor(r, g, b), out r, out g, out b);
}
// packed RGB value
else if (argsn == 1)
{
var c = (uint)L.CheckInteger(1);
UnpackRGB(c, out r, out g, out b);
GetColor(c, out r, out g, out b);
}
else
{

View file

@ -123,12 +123,6 @@ internal class RuntimeManager : IComponent
luaState.Thread.PushCFunction(L_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");
if (status != LuaStatus.OK)
{
@ -219,26 +213,6 @@ internal class RuntimeManager : IComponent
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)
{
Start();
@ -246,6 +220,7 @@ internal class RuntimeManager : IComponent
private void OnTick(object sender, TickEvent e)
{
Resume();
if (e.IsActiveTick)
Resume();
}
}