mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-01-18 10:36:44 +00:00
Too many changes.
This commit is contained in:
parent
110afd1ca4
commit
4681c7060e
29 changed files with 1008 additions and 182 deletions
|
@ -1,6 +1,6 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<RollForward>Major</RollForward>
|
<RollForward>Major</RollForward>
|
||||||
<PublishReadyToRun>false</PublishReadyToRun>
|
<PublishReadyToRun>false</PublishReadyToRun>
|
||||||
|
|
122
Capy64/Core/Canvas.cs
Normal file
122
Capy64/Core/Canvas.cs
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
// 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.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using static SDL2.SDL;
|
||||||
|
using static SDL2.SDL_ttf;
|
||||||
|
|
||||||
|
namespace Capy64.Core;
|
||||||
|
public class Canvas : IDisposable
|
||||||
|
{
|
||||||
|
public nint Font { get; private set; }
|
||||||
|
private readonly Game _game;
|
||||||
|
private nint _surface => _game.VideoSurface;
|
||||||
|
private nint _renderer => _game.SurfaceRenderer;
|
||||||
|
public Canvas(Game game)
|
||||||
|
{
|
||||||
|
_game = game;
|
||||||
|
//File.ReadAllBytes(Path.Combine(Game.AssetsPath, "font.ttf"));
|
||||||
|
Font = TTF_OpenFont(Path.Combine(Game.AssetsPath, "font.ttf"), 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetPixel(int x, int y, Color color) {
|
||||||
|
SDL_SetRenderDrawColor(_renderer, color.R, color.G, color.B, color.A);
|
||||||
|
SDL_RenderDrawPoint(_renderer, x, y);
|
||||||
|
}
|
||||||
|
public void SetPixel(Point point, Color color)
|
||||||
|
{
|
||||||
|
SetPixel(point.X, point.Y, color);
|
||||||
|
}
|
||||||
|
public Color GetPixel(int x, int y)
|
||||||
|
{
|
||||||
|
unsafe {
|
||||||
|
var pitch = ((SDL_Surface*)_surface)->pitch;
|
||||||
|
var c = ((uint*)((SDL_Surface*)_surface)->pixels)[x + y * pitch / 4];
|
||||||
|
return new Color(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public Color GetPixel(Point point)
|
||||||
|
{
|
||||||
|
return GetPixel(point.X, point.Y);
|
||||||
|
}
|
||||||
|
public void SetPixels(IEnumerable<Point> points, Color color)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawRectangle(Vector2 pos, Size2 size, Color color, int thickness = 1, float rotation = 0f)
|
||||||
|
{
|
||||||
|
var rect = new SDL_FRect
|
||||||
|
{
|
||||||
|
x = pos.X,
|
||||||
|
y = pos.Y,
|
||||||
|
w = size.Width,
|
||||||
|
h = size.Height,
|
||||||
|
};
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(_renderer, color.R, color.G, color.B, color.A);
|
||||||
|
SDL_RenderDrawRectF(_renderer, ref rect);
|
||||||
|
//DrawRectangle(new(pos, size), color, thickness, rotation, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void DrawFilledRectangle(Vector2 pos, Size2 size, Color color)
|
||||||
|
{
|
||||||
|
var rect = new SDL_FRect
|
||||||
|
{
|
||||||
|
x = pos.X,
|
||||||
|
y = pos.Y,
|
||||||
|
w = size.Width,
|
||||||
|
h = size.Height,
|
||||||
|
};
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(_renderer, color.R, color.G, color.B, color.A);
|
||||||
|
SDL_RenderFillRectF(_renderer, ref rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawString(Vector2 charpos, string v, Color fg)
|
||||||
|
{
|
||||||
|
var surf = TTF_RenderText_Solid(Font, v, fg.ToSDL());
|
||||||
|
var message = SDL_CreateTextureFromSurface(_renderer, surf);
|
||||||
|
var rect = new SDL_Rect
|
||||||
|
{
|
||||||
|
x = (int)charpos.X,
|
||||||
|
y = (int)charpos.Y,
|
||||||
|
w = 9,
|
||||||
|
h = 13,
|
||||||
|
};
|
||||||
|
|
||||||
|
SDL_SetRenderDrawColor(_surface, 255, 255, 255, 255);
|
||||||
|
SDL_RenderCopy(_renderer, message, 0, ref rect);
|
||||||
|
|
||||||
|
SDL_DestroyTexture(message);
|
||||||
|
SDL_FreeSurface(surf);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear(Color? color = default)
|
||||||
|
{
|
||||||
|
var clearColor = color ?? Color.Black;
|
||||||
|
SDL_SetRenderDrawColor(_renderer, clearColor.R, clearColor.G, clearColor.B, 255);
|
||||||
|
SDL_RenderClear(_renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
TTF_CloseFont(Font);
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,20 +20,31 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SDL2;
|
using SDL2;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace Capy64.Eventing;
|
namespace Capy64.Eventing;
|
||||||
|
|
||||||
public class InputManager
|
public class InputManager
|
||||||
{
|
{
|
||||||
|
// SDL inverts Right and Middle (2 and 3)
|
||||||
public enum MouseButton
|
public enum MouseButton
|
||||||
{
|
{
|
||||||
Left = 1,
|
Left = 1,
|
||||||
Right = 2,
|
Right = 3,
|
||||||
Middle = 3,
|
Middle = 2,
|
||||||
Button4 = 4,
|
Button4 = 4,
|
||||||
Button5 = 5,
|
Button5 = 5,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<MouseButton, int> MouseMap = new()
|
||||||
|
{
|
||||||
|
[MouseButton.Left] = 1,
|
||||||
|
[MouseButton.Right] = 2,
|
||||||
|
[MouseButton.Middle] = 3,
|
||||||
|
[MouseButton.Button4] = 4,
|
||||||
|
[MouseButton.Button5] = 5,
|
||||||
|
};
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum Modifiers
|
public enum Modifiers
|
||||||
{
|
{
|
||||||
|
@ -75,7 +86,6 @@ public class InputManager
|
||||||
};
|
};
|
||||||
|
|
||||||
public Texture2D Texture { get; set; }
|
public Texture2D Texture { get; set; }
|
||||||
public static float WindowScale => LegacyEntry.Instance.Scale;
|
|
||||||
public const int MouseScrollDelta = 120;
|
public const int MouseScrollDelta = 120;
|
||||||
|
|
||||||
private Point mousePosition;
|
private Point mousePosition;
|
||||||
|
@ -85,9 +95,9 @@ public class InputManager
|
||||||
private Modifiers keyboardMods = 0;
|
private Modifiers keyboardMods = 0;
|
||||||
private readonly HashSet<Keys> pressedKeys = new();
|
private readonly HashSet<Keys> pressedKeys = new();
|
||||||
|
|
||||||
private readonly Capy64 _game;
|
private readonly Game _game;
|
||||||
private readonly EventEmitter _eventEmitter;
|
private readonly EventEmitter _eventEmitter;
|
||||||
public InputManager(Capy64 game, EventEmitter eventManager)
|
public InputManager(Game game, EventEmitter eventManager)
|
||||||
|
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
|
@ -109,18 +119,26 @@ public class InputManager
|
||||||
UpdateGamePad(GamePad.GetState(PlayerIndex.One), IsActive);
|
UpdateGamePad(GamePad.GetState(PlayerIndex.One), IsActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateMouseSDL(SDL.SDL_Event ev)
|
private Point GetMouseCoords(int x, int y)
|
||||||
{
|
{
|
||||||
var position = new Point(ev.button.x, ev.button.y);
|
var position = new Point(x, y);
|
||||||
var rawPosition = position - new Point(LegacyEntry.Instance.Borders.Left, LegacyEntry.Instance.Borders.Top);
|
var rawPosition = position - new Point(_game.Borders.Left, _game.Borders.Top);
|
||||||
var pos = new Point((int)(rawPosition.X / WindowScale), (int)(rawPosition.Y / WindowScale)) + new Point(1, 1);
|
return new Point((int)(rawPosition.X / _game.Scale), (int)(rawPosition.Y / _game.Scale)) + new Point(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateMouseMove(SDL.SDL_Event ev)
|
||||||
|
{
|
||||||
|
var pos = GetMouseCoords(ev.button.x, ev.button.y);
|
||||||
|
|
||||||
if (pos.X < 1 || pos.Y < 1 || pos.X > (_game.Width) || pos.Y > _game.Height)
|
if (pos.X < 1 || pos.Y < 1 || pos.X > (_game.Width) || pos.Y > _game.Height)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pos != mousePosition)
|
if (pos != mousePosition)
|
||||||
{
|
{
|
||||||
mousePosition = pos;
|
mousePosition = pos;
|
||||||
|
|
||||||
|
Console.WriteLine("MOTION {0} {1} {2}", pos.X, pos.Y, ev.button.state);
|
||||||
|
|
||||||
_eventEmitter.RaiseMouseMove(new()
|
_eventEmitter.RaiseMouseMove(new()
|
||||||
{
|
{
|
||||||
Position = mousePosition,
|
Position = mousePosition,
|
||||||
|
@ -130,7 +148,36 @@ public class InputManager
|
||||||
.ToArray()
|
.ToArray()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateMouseClick(SDL.SDL_Event ev)
|
||||||
|
{
|
||||||
|
var pos = GetMouseCoords(ev.button.x, ev.button.y);
|
||||||
|
|
||||||
|
if (pos.X < 1 || pos.Y < 1 || pos.X > (_game.Width) || pos.Y > _game.Height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mouseButtonStates[(MouseButton)ev.button.button] = (ButtonState)ev.button.state;
|
||||||
|
|
||||||
|
Console.WriteLine("MCLICK {0} {1} {2} {3}", pos.X, pos.Y, ev.button.button, ev.button.state);
|
||||||
|
_eventEmitter.RaiseMouseButton(new()
|
||||||
|
{
|
||||||
|
Position = pos,
|
||||||
|
Button = (MouseButton)ev.button.button,
|
||||||
|
State = (ButtonState)ev.button.state,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateMouseScroll(SDL.SDL_Event ev)
|
||||||
|
{
|
||||||
|
|
||||||
|
Console.WriteLine("MWHEEL {0} {1} {2} {3}", mousePosition.X, mousePosition.Y, ev.wheel.x, ev.wheel.y);
|
||||||
|
_eventEmitter.RaiseMouseWheelEvent(new()
|
||||||
|
{
|
||||||
|
Position = mousePosition,
|
||||||
|
VerticalValue = ev.wheel.x,
|
||||||
|
HorizontalValue = ev.wheel.x,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateMouse(MouseState state, bool isActive)
|
private void UpdateMouse(MouseState state, bool isActive)
|
||||||
|
@ -138,8 +185,8 @@ public class InputManager
|
||||||
if (!isActive)
|
if (!isActive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var rawPosition = state.Position - new Point(LegacyEntry.Instance.Borders.Left, LegacyEntry.Instance.Borders.Top);
|
var rawPosition = state.Position - new Point(_game.Borders.Left, _game.Borders.Top);
|
||||||
var pos = new Point((int)(rawPosition.X / WindowScale), (int)(rawPosition.Y / WindowScale)) + new Point(1, 1);
|
var pos = new Point((int)(rawPosition.X / _game.Scale), (int)(rawPosition.Y / _game.Scale)) + new Point(1, 1);
|
||||||
|
|
||||||
if (pos.X < 1 || pos.Y < 1 || pos.X > Texture.Width || pos.Y > Texture.Height)
|
if (pos.X < 1 || pos.Y < 1 || pos.X > Texture.Width || pos.Y > Texture.Height)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -13,20 +13,27 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
using Capy64.API;
|
||||||
|
using Capy64.Core;
|
||||||
using Capy64.Eventing;
|
using Capy64.Eventing;
|
||||||
using Microsoft.Xna.Framework;
|
using Capy64.PluginManager;
|
||||||
|
using Capy64.Runtime;
|
||||||
|
using Capy64.Utils;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Timers;
|
||||||
|
using static SDL2.SDL;
|
||||||
|
|
||||||
namespace Capy64;
|
namespace Capy64;
|
||||||
|
|
||||||
using System;
|
public class Game : IDisposable
|
||||||
using System.IO;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using static Utils;
|
|
||||||
using static SDL2.SDL;
|
|
||||||
|
|
||||||
public class Capy64 : IDisposable
|
|
||||||
{
|
{
|
||||||
|
public static Game Instance { get; private set; }
|
||||||
public const string Version = "1.1.0-beta";
|
public const string Version = "1.1.0-beta";
|
||||||
public nint Window { get; private set; } = 0;
|
public nint Window { get; private set; } = 0;
|
||||||
public nint Renderer { get; private set; } = 0;
|
public nint Renderer { get; private set; } = 0;
|
||||||
|
@ -42,14 +49,19 @@ public class Capy64 : IDisposable
|
||||||
|
|
||||||
public float Ticktime => 1000f / Tickrate;
|
public float Ticktime => 1000f / Tickrate;
|
||||||
public float Frametime => 1000f / Framerate;
|
public float Frametime => 1000f / Framerate;
|
||||||
|
public IList<IComponent> NativePlugins { get; private set; }
|
||||||
|
public IList<IComponent> Plugins { get; private set; }
|
||||||
|
|
||||||
public Color BorderColor { get; set; } = Color.Blue;
|
public Color BorderColor { get; set; } = Color.Black;
|
||||||
|
|
||||||
public Borders Borders {
|
public Borders Borders
|
||||||
|
{
|
||||||
get => _borders;
|
get => _borders;
|
||||||
set {
|
set
|
||||||
|
{
|
||||||
_borders = value;
|
_borders = value;
|
||||||
_outputRect = new() {
|
_outputRect = new()
|
||||||
|
{
|
||||||
x = value.Left,
|
x = value.Left,
|
||||||
y = value.Top,
|
y = value.Top,
|
||||||
w = (int)(Width * Scale),
|
w = (int)(Width * Scale),
|
||||||
|
@ -63,6 +75,7 @@ public class Capy64 : IDisposable
|
||||||
|
|
||||||
public static readonly string AssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
public static readonly string AssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||||
public static readonly string AssetsPath = Path.Combine(AssemblyPath, "Assets");
|
public static readonly string AssetsPath = Path.Combine(AssemblyPath, "Assets");
|
||||||
|
public IConfiguration Configuration { get; private set; }
|
||||||
|
|
||||||
public static class DefaultParameters
|
public static class DefaultParameters
|
||||||
{
|
{
|
||||||
|
@ -76,8 +89,10 @@ public class Capy64 : IDisposable
|
||||||
public const int FreeTickrate = 60;
|
public const int FreeTickrate = 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string AppDataPath {
|
public static string AppDataPath
|
||||||
get {
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
string baseDir =
|
string baseDir =
|
||||||
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Environment.GetFolderPath(
|
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Environment.GetFolderPath(
|
||||||
Environment.SpecialFolder.ApplicationData,
|
Environment.SpecialFolder.ApplicationData,
|
||||||
|
@ -93,24 +108,76 @@ public class Capy64 : IDisposable
|
||||||
return Path.Combine(baseDir, "Capy64");
|
return Path.Combine(baseDir, "Capy64");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _running = false;
|
private bool _running = false;
|
||||||
private InputManager _inputManager;
|
private InputManager _inputManager;
|
||||||
public EventEmitter EventEmitter = new();
|
public Eventing.EventEmitter EventEmitter = new();
|
||||||
|
public readonly Canvas Canvas;
|
||||||
|
public Audio Audio { get; private set; }
|
||||||
|
public LuaState LuaRuntime { get; set; }
|
||||||
|
|
||||||
public Capy64()
|
public Game()
|
||||||
{
|
{
|
||||||
|
Instance = this;
|
||||||
|
Canvas = new(this);
|
||||||
ResetBorder();
|
ResetBorder();
|
||||||
WindowWidth = (int)(Width * Scale) + Borders.Left + Borders.Right;
|
UpdateSize();
|
||||||
WindowHeight = (int)(Height * Scale) + Borders.Top + Borders.Bottom;
|
|
||||||
|
|
||||||
_inputManager = new(null, EventEmitter);
|
_inputManager = new(this, EventEmitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
var configBuilder = new ConfigurationBuilder();
|
||||||
|
|
||||||
|
var settingsPath = Path.Combine(AppDataPath, "settings.json");
|
||||||
|
if (!Directory.Exists(AppDataPath))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(AppDataPath);
|
||||||
|
}
|
||||||
|
if (!File.Exists(settingsPath))
|
||||||
|
{
|
||||||
|
File.Copy(Path.Combine(AssetsPath, "default.json"), settingsPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
configBuilder.AddJsonFile(Path.Combine(AssetsPath, "default.json"), false);
|
||||||
|
configBuilder.AddJsonFile(settingsPath, false);
|
||||||
|
|
||||||
|
Configuration = configBuilder.Build();
|
||||||
|
|
||||||
|
Scale = Configuration.GetValue("Window:Scale", DefaultParameters.Scale);
|
||||||
|
|
||||||
|
Audio = new Audio();
|
||||||
|
|
||||||
|
NativePlugins = LoadNativePlugins();
|
||||||
|
var safeMode = Configuration.GetValue("SafeMode", false);
|
||||||
|
if (!safeMode)
|
||||||
|
Plugins = PluginLoader.LoadAllPlugins(Path.Combine(AppDataPath, "plugins"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<IComponent> LoadNativePlugins()
|
||||||
|
{
|
||||||
|
var iType = typeof(IComponent);
|
||||||
|
var types = AppDomain.CurrentDomain.GetAssemblies()
|
||||||
|
.SelectMany(s => s.GetTypes())
|
||||||
|
.Where(p => iType.IsAssignableFrom(p) && !p.IsInterface);
|
||||||
|
|
||||||
|
var plugins = new List<IComponent>();
|
||||||
|
|
||||||
|
foreach (var type in types)
|
||||||
|
{
|
||||||
|
var instance = (IComponent)Activator.CreateInstance(type, this);
|
||||||
|
plugins.Add(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResetBorder()
|
private void ResetBorder()
|
||||||
{
|
{
|
||||||
var size = (int)(Scale * DefaultParameters.BorderMultiplier);
|
var size = (int)(Scale * DefaultParameters.BorderMultiplier);
|
||||||
Borders = new Borders {
|
Borders = new Borders
|
||||||
|
{
|
||||||
Top = size,
|
Top = size,
|
||||||
Bottom = size,
|
Bottom = size,
|
||||||
Left = size,
|
Left = size,
|
||||||
|
@ -118,8 +185,22 @@ public class Capy64 : IDisposable
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateSize(bool resize = true)
|
||||||
|
{
|
||||||
|
if (resize)
|
||||||
|
{
|
||||||
|
WindowWidth = (int)(Width * Scale) + Borders.Left + Borders.Right;
|
||||||
|
WindowHeight = (int)(Height * Scale) + Borders.Top + Borders.Bottom;
|
||||||
|
SDL_SetWindowSize(Window, WindowWidth, WindowHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
EventEmitter.RaiseScreenSizeChange();
|
||||||
|
}
|
||||||
|
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
|
Initialize();
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1");
|
SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1");
|
||||||
#endif
|
#endif
|
||||||
|
@ -142,7 +223,7 @@ public class Capy64 : IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
var icon = SDL_LoadBMP("./Icon.bmp");
|
var icon = SDL_LoadBMP("./Icon.bmp");
|
||||||
if(icon != 0)
|
if (icon != 0)
|
||||||
SDL_SetWindowIcon(Window, icon);
|
SDL_SetWindowIcon(Window, icon);
|
||||||
|
|
||||||
Renderer = SDL_CreateRenderer(Window,
|
Renderer = SDL_CreateRenderer(Window,
|
||||||
|
@ -158,31 +239,23 @@ public class Capy64 : IDisposable
|
||||||
VideoSurface = SDL_CreateRGBSurfaceWithFormat(0, Width, Height, 32, SDL_PIXELFORMAT_ARGB8888);
|
VideoSurface = SDL_CreateRGBSurfaceWithFormat(0, Width, Height, 32, SDL_PIXELFORMAT_ARGB8888);
|
||||||
SurfaceRenderer = SDL_CreateSoftwareRenderer(VideoSurface);
|
SurfaceRenderer = SDL_CreateSoftwareRenderer(VideoSurface);
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(SurfaceRenderer, 255, 255, 255, 255);
|
SDL_SetRenderDrawColor(SurfaceRenderer, 0, 0, 0, 255);
|
||||||
SDL_RenderClear(SurfaceRenderer);
|
SDL_RenderClear(SurfaceRenderer);
|
||||||
|
|
||||||
_running = true;
|
EventEmitter.RaiseInit();
|
||||||
|
|
||||||
ulong deltaEnd = 0;
|
ulong deltaEnd = 0;
|
||||||
var perfFreq = SDL_GetPerformanceFrequency();
|
var perfFreq = SDL_GetPerformanceFrequency();
|
||||||
while (_running)
|
|
||||||
{
|
|
||||||
var deltaStart = SDL_GetPerformanceCounter();
|
|
||||||
var delta = deltaStart - deltaEnd;
|
|
||||||
|
|
||||||
while (SDL_PollEvent(out var ev) != 0)
|
|
||||||
{
|
|
||||||
ProcessEvent(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((uint)(perfFreq / delta) >= Framerate)
|
ulong totalTicks = 0;
|
||||||
{
|
|
||||||
continue;
|
var drawTimer = new Timer(TimeSpan.FromMilliseconds(1000d / Framerate));
|
||||||
}
|
drawTimer.Elapsed += (s, e) =>
|
||||||
deltaEnd = deltaStart;
|
{
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(Renderer, BorderColor.R, BorderColor.G, BorderColor.B, 255);
|
SDL_SetRenderDrawColor(Renderer, BorderColor.R, BorderColor.G, BorderColor.B, 255);
|
||||||
SDL_RenderClear(Renderer);
|
SDL_RenderClear(Renderer);
|
||||||
|
|
||||||
|
|
||||||
SDL_SetRenderDrawColor(Renderer, 255, 255, 255, 255);
|
SDL_SetRenderDrawColor(Renderer, 255, 255, 255, 255);
|
||||||
var texture = SDL_CreateTextureFromSurface(Renderer, VideoSurface);
|
var texture = SDL_CreateTextureFromSurface(Renderer, VideoSurface);
|
||||||
|
|
||||||
|
@ -190,7 +263,49 @@ public class Capy64 : IDisposable
|
||||||
|
|
||||||
SDL_RenderCopy(Renderer, texture, 0, ref _outputRect);
|
SDL_RenderCopy(Renderer, texture, 0, ref _outputRect);
|
||||||
SDL_DestroyTexture(texture);
|
SDL_DestroyTexture(texture);
|
||||||
|
|
||||||
SDL_RenderPresent(Renderer);
|
SDL_RenderPresent(Renderer);
|
||||||
|
};
|
||||||
|
|
||||||
|
var updateTimer = new Timer(TimeSpan.FromMilliseconds(1000d / Tickrate));
|
||||||
|
updateTimer.Elapsed += (s, e) => {
|
||||||
|
// Register user input
|
||||||
|
//_inputManager.Update(true);
|
||||||
|
|
||||||
|
EventEmitter.RaiseTick(new()
|
||||||
|
{
|
||||||
|
GameTime = null,
|
||||||
|
TotalTicks = totalTicks,
|
||||||
|
IsActiveTick = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
totalTicks++;
|
||||||
|
};
|
||||||
|
|
||||||
|
drawTimer.Start();
|
||||||
|
updateTimer.Start();
|
||||||
|
_running = true;
|
||||||
|
while (_running)
|
||||||
|
{
|
||||||
|
var deltaStart = SDL_GetPerformanceCounter();
|
||||||
|
var delta = deltaStart - deltaEnd;
|
||||||
|
|
||||||
|
while (SDL_WaitEvent(out var ev) != 0)
|
||||||
|
{
|
||||||
|
ProcessEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uint)(perfFreq / delta) < Tickrate)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uint)(perfFreq / delta) < Framerate)
|
||||||
|
{
|
||||||
|
deltaEnd = deltaStart;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,20 +315,24 @@ public class Capy64 : IDisposable
|
||||||
{
|
{
|
||||||
case SDL_EventType.SDL_QUIT:
|
case SDL_EventType.SDL_QUIT:
|
||||||
_running = false;
|
_running = false;
|
||||||
|
Dispose();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SDL_EventType.SDL_KEYUP:
|
||||||
case SDL_EventType.SDL_KEYDOWN:
|
case SDL_EventType.SDL_KEYDOWN:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SDL_EventType.SDL_MOUSEMOTION:
|
||||||
|
_inputManager.UpdateMouseMove(ev);
|
||||||
|
break;
|
||||||
|
|
||||||
case SDL_EventType.SDL_MOUSEBUTTONUP:
|
case SDL_EventType.SDL_MOUSEBUTTONUP:
|
||||||
case SDL_EventType.SDL_MOUSEBUTTONDOWN:
|
case SDL_EventType.SDL_MOUSEBUTTONDOWN:
|
||||||
|
_inputManager.UpdateMouseClick(ev);
|
||||||
unsafe
|
break;
|
||||||
{
|
|
||||||
var pitch = ((SDL_Surface*)VideoSurface)->pitch;
|
|
||||||
((uint*)((SDL_Surface*)VideoSurface)->pixels)[x + y * pitch / 4] = 0xFFFF00FF;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
case SDL_EventType.SDL_MOUSEWHEEL:
|
||||||
|
_inputManager.UpdateMouseScroll(ev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,10 +340,9 @@ public class Capy64 : IDisposable
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
SDL_DestroyRenderer(SurfaceRenderer);
|
SDL_DestroyRenderer(SurfaceRenderer);
|
||||||
SDL_FreeSurface(VideoSurface);
|
//SDL_FreeSurface(VideoSurface);
|
||||||
SDL_DestroyRenderer(Renderer);
|
SDL_DestroyRenderer(Renderer);
|
||||||
SDL_DestroyWindow(Window);
|
SDL_DestroyWindow(Window);
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,11 +24,12 @@ namespace Capy64.Integrations;
|
||||||
|
|
||||||
public class DiscordIntegration : IComponent
|
public class DiscordIntegration : IComponent
|
||||||
{
|
{
|
||||||
|
public static DiscordIntegration Instance { get; private set; }
|
||||||
public DiscordRpcClient Client { get; private set; }
|
public DiscordRpcClient Client { get; private set; }
|
||||||
public readonly bool Enabled;
|
public readonly bool Enabled;
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
public DiscordIntegration(LegacyEntry game)
|
public DiscordIntegration(Game game)
|
||||||
{
|
{
|
||||||
_configuration = game.Configuration;
|
_configuration = game.Configuration;
|
||||||
|
|
||||||
|
@ -42,7 +43,7 @@ public class DiscordIntegration : IComponent
|
||||||
|
|
||||||
Client.OnReady += OnReady;
|
Client.OnReady += OnReady;
|
||||||
|
|
||||||
LegacyEntry.Instance.Discord = this;
|
Instance = this;
|
||||||
|
|
||||||
if (Enabled)
|
if (Enabled)
|
||||||
Client.Initialize();
|
Client.Initialize();
|
||||||
|
|
|
@ -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 Capy64.Utils;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
@ -31,7 +32,6 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using static Capy64.Utils;
|
|
||||||
|
|
||||||
namespace Capy64;
|
namespace Capy64;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ public enum EngineMode
|
||||||
Free
|
Free
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LegacyEntry : Game
|
public class LegacyEntry : Microsoft.Xna.Framework.Game
|
||||||
{
|
{
|
||||||
public const string Version = "1.1.0-beta";
|
public const string Version = "1.1.0-beta";
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ public class LegacyEntry : Game
|
||||||
public int TickRate => tickrate;
|
public int TickRate => tickrate;
|
||||||
public IConfiguration Configuration { get; private set; }
|
public IConfiguration Configuration { get; private set; }
|
||||||
|
|
||||||
public Color BorderColor { get; set; } = Color.Black;
|
public Microsoft.Xna.Framework.Color BorderColor { get; set; } = Microsoft.Xna.Framework.Color.Black;
|
||||||
|
|
||||||
public Borders Borders = new()
|
public Borders Borders = new()
|
||||||
{
|
{
|
||||||
|
@ -315,7 +315,7 @@ public class LegacyEntry : Game
|
||||||
|
|
||||||
protected override void Draw(GameTime gameTime)
|
protected override void Draw(GameTime gameTime)
|
||||||
{
|
{
|
||||||
SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp);
|
/*SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp);
|
||||||
GraphicsDevice.Clear(BorderColor);
|
GraphicsDevice.Clear(BorderColor);
|
||||||
|
|
||||||
SpriteBatch.DrawRectangle(renderTarget.Bounds.Location.ToVector2() + new Vector2(Borders.Left, Borders.Top),
|
SpriteBatch.DrawRectangle(renderTarget.Bounds.Location.ToVector2() + new Vector2(Borders.Left, Borders.Top),
|
||||||
|
@ -333,6 +333,6 @@ public class LegacyEntry : Game
|
||||||
|
|
||||||
SpriteBatch.End();
|
SpriteBatch.End();
|
||||||
|
|
||||||
base.Draw(gameTime);
|
base.Draw(gameTime);*/
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -17,7 +17,7 @@ using Capy64;
|
||||||
|
|
||||||
if (args.Length > 0 && args[0] == "sdl")
|
if (args.Length > 0 && args[0] == "sdl")
|
||||||
{
|
{
|
||||||
using var game = new Capy64.Capy64();
|
using var game = new Capy64.Game();
|
||||||
|
|
||||||
game.Run();
|
game.Run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,8 @@ public class AudioLib : IComponent
|
||||||
{
|
{
|
||||||
private const int queueLimit = 8;
|
private const int queueLimit = 8;
|
||||||
|
|
||||||
private static LegacyEntry _game;
|
private static Game _game;
|
||||||
public AudioLib(LegacyEntry game)
|
public AudioLib(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
_game.EventEmitter.OnClose += OnClose;
|
_game.EventEmitter.OnClose += OnClose;
|
||||||
|
|
|
@ -29,8 +29,8 @@ public class EventLib : IComponent
|
||||||
|
|
||||||
private static bool FrozenTaskAwaiter = false;
|
private static bool FrozenTaskAwaiter = false;
|
||||||
|
|
||||||
private static LegacyEntry _game;
|
private static Game _game;
|
||||||
public EventLib(LegacyEntry game)
|
public EventLib(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ public class FileSystemLib : IComponent
|
||||||
new(), // NULL
|
new(), // NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
public FileSystemLib(LegacyEntry _) { }
|
public FileSystemLib(Game _) { }
|
||||||
|
|
||||||
public void LuaInit(Lua state)
|
public void LuaInit(Lua state)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,9 +15,8 @@
|
||||||
|
|
||||||
using Capy64.API;
|
using Capy64.API;
|
||||||
using Capy64.Runtime.Objects;
|
using Capy64.Runtime.Objects;
|
||||||
|
using Capy64.Utils;
|
||||||
using KeraLua;
|
using KeraLua;
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
@ -28,8 +27,8 @@ namespace Capy64.Runtime.Libraries;
|
||||||
public class GPULib : IComponent
|
public class GPULib : IComponent
|
||||||
{
|
{
|
||||||
|
|
||||||
private static LegacyEntry _game;
|
private static Game _game;
|
||||||
public GPULib(LegacyEntry game)
|
public GPULib(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
}
|
}
|
||||||
|
@ -157,7 +156,9 @@ public class GPULib : IComponent
|
||||||
|
|
||||||
public static void GetColor(uint c, out byte r, out byte g, out byte b)
|
public static void GetColor(uint c, out byte r, out byte g, out byte b)
|
||||||
{
|
{
|
||||||
Utils.UnpackRGB(c, out r, out g, out b);
|
var color = new Color(c);
|
||||||
|
//Utils.UnpackRGB(c, out r, out g, out b);
|
||||||
|
r = color.R; g = color.G; b = color.B;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int L_GetSize(IntPtr state)
|
private static int L_GetSize(IntPtr state)
|
||||||
|
@ -174,10 +175,12 @@ public class GPULib : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
if (_game.EngineMode == EngineMode.Classic)
|
return 0;
|
||||||
|
|
||||||
|
/*if (_game.EngineMode == EngineMode.Classic)
|
||||||
{
|
{
|
||||||
return L.Error("Screen is not resizable");
|
return L.Error("Screen is not resizable");
|
||||||
}
|
}*/
|
||||||
|
|
||||||
var w = L.CheckInteger(1);
|
var w = L.CheckInteger(1);
|
||||||
var h = L.CheckInteger(2);
|
var h = L.CheckInteger(2);
|
||||||
|
@ -196,7 +199,8 @@ public class GPULib : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
L.PushBoolean(_game.EngineMode != EngineMode.Classic);
|
//L.PushBoolean(_game.EngineMode != EngineMode.Classic);
|
||||||
|
L.PushBoolean(false);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -208,9 +212,11 @@ public class GPULib : IComponent
|
||||||
var x = (int)L.CheckNumber(1) - 1;
|
var x = (int)L.CheckNumber(1) - 1;
|
||||||
var y = (int)L.CheckNumber(2) - 1;
|
var y = (int)L.CheckNumber(2) - 1;
|
||||||
|
|
||||||
var c = _game.Drawing.GetPixel(new(x, y));
|
var c = _game.Canvas.GetPixel(new(x, y));
|
||||||
|
|
||||||
L.PushInteger(Utils.PackRGB(c));
|
//var c = _game.Drawing.GetPixel(new(x, y));
|
||||||
|
|
||||||
|
L.PushInteger(c.PackedRGB);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +230,7 @@ public class GPULib : IComponent
|
||||||
var c = L.CheckInteger(3);
|
var c = L.CheckInteger(3);
|
||||||
|
|
||||||
GetColor((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.Canvas.SetPixel(new Point(x, y), new Color(r, g, b));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -259,7 +265,7 @@ public class GPULib : IComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
GetColor((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.Canvas.SetPixels(pts, new(r, g, b));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -274,7 +280,7 @@ public class GPULib : IComponent
|
||||||
var s = (int)L.OptNumber(4, 1);
|
var s = (int)L.OptNumber(4, 1);
|
||||||
|
|
||||||
GetColor((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;
|
||||||
}
|
}
|
||||||
|
@ -291,7 +297,7 @@ public class GPULib : IComponent
|
||||||
var s = (int)L.OptInteger(6, -1);
|
var s = (int)L.OptInteger(6, -1);
|
||||||
|
|
||||||
GetColor((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;
|
||||||
}
|
}
|
||||||
|
@ -308,7 +314,7 @@ public class GPULib : IComponent
|
||||||
var s = (int)L.OptNumber(6, 1);
|
var s = (int)L.OptNumber(6, 1);
|
||||||
|
|
||||||
GetColor((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;
|
||||||
}
|
}
|
||||||
|
@ -325,7 +331,7 @@ public class GPULib : IComponent
|
||||||
var s = (int)L.OptNumber(6, 1);
|
var s = (int)L.OptNumber(6, 1);
|
||||||
|
|
||||||
GetColor((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;
|
||||||
}
|
}
|
||||||
|
@ -361,7 +367,7 @@ public class GPULib : IComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
GetColor((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;
|
||||||
}
|
}
|
||||||
|
@ -378,7 +384,7 @@ public class GPULib : IComponent
|
||||||
var s = (int)L.OptNumber(6, 1);
|
var s = (int)L.OptNumber(6, 1);
|
||||||
|
|
||||||
GetColor((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;
|
||||||
}
|
}
|
||||||
|
@ -395,7 +401,7 @@ public class GPULib : IComponent
|
||||||
GetColor((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));
|
||||||
}
|
}
|
||||||
catch (ArgumentException ex) // UTF-16 fuckery
|
catch (ArgumentException ex) // UTF-16 fuckery
|
||||||
{
|
{
|
||||||
|
@ -411,10 +417,10 @@ public class GPULib : IComponent
|
||||||
|
|
||||||
var t = L.CheckString(1);
|
var t = L.CheckString(1);
|
||||||
|
|
||||||
var sizes = _game.Drawing.MeasureString(t);
|
//var sizes = _game.Drawing.MeasureString(t);
|
||||||
|
|
||||||
L.PushNumber((int)sizes.X);
|
//L.PushNumber((int)sizes.X);
|
||||||
L.PushNumber((int)sizes.Y);
|
//L.PushNumber((int)sizes.Y);
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -425,7 +431,7 @@ public class GPULib : IComponent
|
||||||
|
|
||||||
|
|
||||||
var buffer = new uint[_game.Width * _game.Height];
|
var buffer = new uint[_game.Width * _game.Height];
|
||||||
_game.Drawing.Canvas.GetData(buffer);
|
//_game.Drawing.Canvas.GetData(buffer);
|
||||||
|
|
||||||
var gpuBuffer = new GPUBufferMeta.GPUBuffer
|
var gpuBuffer = new GPUBufferMeta.GPUBuffer
|
||||||
{
|
{
|
||||||
|
@ -446,7 +452,7 @@ public class GPULib : IComponent
|
||||||
|
|
||||||
var buffer = GPUBufferMeta.CheckBuffer(L, false);
|
var buffer = GPUBufferMeta.CheckBuffer(L, false);
|
||||||
|
|
||||||
_game.Drawing.Canvas.SetData(buffer.Buffer);
|
//_game.Drawing.Canvas.SetData(buffer.Buffer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -533,7 +539,7 @@ public class GPULib : IComponent
|
||||||
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;
|
||||||
|
|
||||||
Rectangle? source = null;
|
/*Rectangle? source = null;
|
||||||
Color color = Color.White;
|
Color color = Color.White;
|
||||||
float rotation = 0;
|
float rotation = 0;
|
||||||
Vector2 origin = Vector2.Zero;
|
Vector2 origin = Vector2.Zero;
|
||||||
|
@ -634,7 +640,7 @@ public class GPULib : IComponent
|
||||||
Width = buffer.Width,
|
Width = buffer.Width,
|
||||||
Height = buffer.Height,
|
Height = buffer.Height,
|
||||||
}, source, color, rotation, origin, scale, effects);
|
}, source, color, rotation, origin, scale, effects);
|
||||||
|
*/
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -654,10 +660,10 @@ public class GPULib : IComponent
|
||||||
|
|
||||||
var task = TaskMeta.Push(L, GPUBufferMeta.ObjectType);
|
var task = TaskMeta.Push(L, GPUBufferMeta.ObjectType);
|
||||||
|
|
||||||
Texture2D texture;
|
//Texture2D texture;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
texture = Texture2D.FromFile(LegacyEntry.Instance.Drawing.Canvas.GraphicsDevice, path);
|
//texture = Texture2D.FromFile(LegacyEntry.Instance.Drawing.Canvas.GraphicsDevice, path);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -665,8 +671,8 @@ public class GPULib : IComponent
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = new uint[texture.Width * texture.Height];
|
//var data = new uint[texture.Width * texture.Height];
|
||||||
texture.GetData(data);
|
//texture.GetData(data);
|
||||||
|
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
|
@ -695,7 +701,7 @@ public class GPULib : IComponent
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
var buffer = new GPUBufferMeta.GPUBuffer
|
/*var buffer = new GPUBufferMeta.GPUBuffer
|
||||||
{
|
{
|
||||||
Buffer = data,
|
Buffer = data,
|
||||||
Height = texture.Height,
|
Height = texture.Height,
|
||||||
|
@ -708,7 +714,7 @@ public class GPULib : IComponent
|
||||||
lk.SetMetaTable(GPUBufferMeta.ObjectType);
|
lk.SetMetaTable(GPUBufferMeta.ObjectType);
|
||||||
});
|
});
|
||||||
|
|
||||||
texture.Dispose();
|
texture.Dispose();*/
|
||||||
});
|
});
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -721,7 +727,7 @@ public class GPULib : IComponent
|
||||||
var c = L.OptInteger(1, 0x000000);
|
var c = L.OptInteger(1, 0x000000);
|
||||||
|
|
||||||
GetColor((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.Canvas.Clear(new Color(r, g, b));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace Capy64.Runtime.Libraries;
|
||||||
#nullable enable
|
#nullable enable
|
||||||
public class HTTPLib : IComponent
|
public class HTTPLib : IComponent
|
||||||
{
|
{
|
||||||
private static LegacyEntry _game = null!;
|
private static Game _game = null!;
|
||||||
private static HttpClient _httpClient = null!;
|
private static HttpClient _httpClient = null!;
|
||||||
private static long _requestId;
|
private static long _requestId;
|
||||||
public static readonly HashSet<WebSocketClient.Client> WebSocketConnections = new();
|
public static readonly HashSet<WebSocketClient.Client> WebSocketConnections = new();
|
||||||
|
@ -57,7 +57,7 @@ public class HTTPLib : IComponent
|
||||||
},
|
},
|
||||||
new(),
|
new(),
|
||||||
};
|
};
|
||||||
public HTTPLib(LegacyEntry game)
|
public HTTPLib(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
_requestId = 0;
|
_requestId = 0;
|
||||||
|
|
|
@ -24,8 +24,8 @@ namespace Capy64.Runtime.Libraries;
|
||||||
|
|
||||||
public class MachineLib : IComponent
|
public class MachineLib : IComponent
|
||||||
{
|
{
|
||||||
private static LegacyEntry _game;
|
private static Game _game;
|
||||||
public MachineLib(LegacyEntry game)
|
public MachineLib(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,9 @@
|
||||||
|
|
||||||
using Capy64.API;
|
using Capy64.API;
|
||||||
using Capy64.Eventing.Events;
|
using Capy64.Eventing.Events;
|
||||||
|
using Capy64.Utils;
|
||||||
using KeraLua;
|
using KeraLua;
|
||||||
using Microsoft.Xna.Framework;
|
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
|
||||||
using System;
|
using System;
|
||||||
using static Capy64.Utils;
|
|
||||||
|
|
||||||
namespace Capy64.Runtime.Libraries;
|
namespace Capy64.Runtime.Libraries;
|
||||||
|
|
||||||
|
@ -49,11 +47,11 @@ internal class TermLib : IComponent
|
||||||
public static Color BackgroundColor { get; set; }
|
public static Color BackgroundColor { get; set; }
|
||||||
private static Char?[] CharGrid;
|
private static Char?[] CharGrid;
|
||||||
|
|
||||||
private static LegacyEntry _game;
|
private static Game _game;
|
||||||
private static bool cursorState = false;
|
private static bool cursorState = false;
|
||||||
private static bool enableCursor = true;
|
private static bool enableCursor = true;
|
||||||
private static Texture2D cursorTexture;
|
//private static Texture2D cursorTexture;
|
||||||
public TermLib(LegacyEntry game)
|
public TermLib(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
|
|
||||||
|
@ -61,10 +59,10 @@ internal class TermLib : IComponent
|
||||||
ForegroundColor = Color.White;
|
ForegroundColor = Color.White;
|
||||||
BackgroundColor = Color.Black;
|
BackgroundColor = Color.Black;
|
||||||
|
|
||||||
cursorTexture = new(_game.Game.GraphicsDevice, 1, CharHeight - 3);
|
//cursorTexture = new(_game.Game.GraphicsDevice, 1, CharHeight - 3);
|
||||||
var textureData = new Color[CharHeight - 3];
|
//var textureData = new Color[CharHeight - 3];
|
||||||
Array.Fill(textureData, Color.White);
|
//Array.Fill(textureData, Color.White);
|
||||||
cursorTexture.SetData(textureData);
|
//cursorTexture.SetData(textureData);
|
||||||
|
|
||||||
UpdateSize();
|
UpdateSize();
|
||||||
|
|
||||||
|
@ -182,7 +180,9 @@ internal class TermLib : IComponent
|
||||||
{
|
{
|
||||||
/*if (_game.EngineMode == EngineMode.Classic)
|
/*if (_game.EngineMode == EngineMode.Classic)
|
||||||
c = ColorPalette.GetColor(c);*/
|
c = ColorPalette.GetColor(c);*/
|
||||||
UnpackRGB(c, out r, out g, out b);
|
var color = new Color(c);
|
||||||
|
//UnpackRGB(c, out r, out g, out b);
|
||||||
|
r = color.R; g = color.G; b = color.B;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateSize(bool resize = true)
|
public static void UpdateSize(bool resize = true)
|
||||||
|
@ -212,22 +212,24 @@ internal class TermLib : IComponent
|
||||||
|
|
||||||
var realpos = ToRealPos(pos);
|
var realpos = ToRealPos(pos);
|
||||||
var charpos = realpos + CharOffset;
|
var charpos = realpos + CharOffset;
|
||||||
_game.Drawing.DrawRectangle(realpos, new(CharWidth, CharHeight), bg, Math.Min(CharWidth, CharHeight));
|
_game.Canvas.DrawFilledRectangle(realpos, new(CharWidth, CharHeight), bg);
|
||||||
//_game.Drawing.DrawRectangle(realpos, new(CharWidth, CharHeight), Color.Red, 1);
|
//_game.Drawing.DrawRectangle(realpos, new(CharWidth, CharHeight), bg, Math.Min(CharWidth, CharHeight));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_game.Drawing.DrawString(charpos, ch.ToString(), fg);
|
_game.Canvas.DrawString(charpos, ch.ToString(), fg);
|
||||||
|
//_game.Drawing.DrawString(charpos, ch.ToString(), fg);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (ArgumentException) // UTF-16 fuckery
|
catch (ArgumentException) // UTF-16 fuckery
|
||||||
{
|
{
|
||||||
_game.Drawing.DrawString(charpos, "\xFFFD", fg);
|
_game.Canvas.DrawString(charpos, "\xFFFD", fg);
|
||||||
|
//_game.Drawing.DrawString(charpos, "\xFFFD", fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (underline)
|
if (underline)
|
||||||
{
|
{
|
||||||
_game.Drawing.DrawLine(charpos + new Vector2(0, CharHeight), charpos + new Vector2(CharWidth, CharHeight), fg);
|
//_game.Drawing.DrawLine(charpos + new Vector2(0, CharHeight), charpos + new Vector2(CharWidth, CharHeight), fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!save)
|
if (!save)
|
||||||
|
@ -318,14 +320,14 @@ internal class TermLib : IComponent
|
||||||
var realpos = ToRealPos(CursorPosition - Vector2.One);
|
var realpos = ToRealPos(CursorPosition - Vector2.One);
|
||||||
var charpos = (realpos * _game.Scale) + ((CharOffset + new Vector2(0, 2)) * _game.Scale);
|
var charpos = (realpos * _game.Scale) + ((CharOffset + new Vector2(0, 2)) * _game.Scale);
|
||||||
charpos += new Vector2(LegacyEntry.Instance.Borders.Left, LegacyEntry.Instance.Borders.Top);
|
charpos += new Vector2(LegacyEntry.Instance.Borders.Left, LegacyEntry.Instance.Borders.Top);
|
||||||
_game.Game.SpriteBatch.Draw(cursorTexture, charpos, null, ForegroundColor, 0f, Vector2.Zero, _game.Scale, SpriteEffects.None, 0);
|
//_game.Game.SpriteBatch.Draw(cursorTexture, charpos, null, ForegroundColor, 0f, Vector2.Zero, _game.Scale, SpriteEffects.None, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ClearGrid()
|
private static void ClearGrid()
|
||||||
{
|
{
|
||||||
CharGrid = new Char?[CharGrid.Length];
|
CharGrid = new Char?[CharGrid.Length];
|
||||||
_game.Drawing.Clear(BackgroundColor);
|
_game.Canvas.Clear(BackgroundColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Write(string text)
|
public static void Write(string text)
|
||||||
|
@ -399,10 +401,12 @@ internal class TermLib : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
if (_game.EngineMode == EngineMode.Classic)
|
return 0;
|
||||||
{
|
|
||||||
return L.Error("Terminal is not resizable");
|
//if (_game.EngineMode == EngineMode.Classic)
|
||||||
}
|
//{
|
||||||
|
// return L.Error("Terminal is not resizable");
|
||||||
|
//}
|
||||||
|
|
||||||
var w = (int)L.CheckNumber(1);
|
var w = (int)L.CheckNumber(1);
|
||||||
var h = (int)L.CheckNumber(2);
|
var h = (int)L.CheckNumber(2);
|
||||||
|
@ -426,7 +430,8 @@ internal class TermLib : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
L.PushBoolean(_game.EngineMode != EngineMode.Classic);
|
//L.PushBoolean(_game.EngineMode != EngineMode.Classic);
|
||||||
|
L.PushBoolean(false);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -435,7 +440,7 @@ internal class TermLib : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
L.PushInteger(PackRGB(ForegroundColor));
|
L.PushInteger(ForegroundColor.PackedRGB);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -477,7 +482,7 @@ internal class TermLib : IComponent
|
||||||
{
|
{
|
||||||
var L = Lua.FromIntPtr(state);
|
var L = Lua.FromIntPtr(state);
|
||||||
|
|
||||||
L.PushInteger(PackRGB(BackgroundColor));
|
L.PushInteger(ForegroundColor.PackedRGB);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,11 +50,11 @@ class TimerLib : IComponent
|
||||||
new(),
|
new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
private static LegacyEntry _game;
|
private static Game _game;
|
||||||
private static uint _timerId = 0;
|
private static uint _timerId = 0;
|
||||||
|
|
||||||
private static readonly ConcurrentDictionary<uint, Timer> timers = new();
|
private static readonly ConcurrentDictionary<uint, Timer> timers = new();
|
||||||
public TimerLib(LegacyEntry game)
|
public TimerLib(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,8 @@ public class LuaState : IDisposable
|
||||||
|
|
||||||
private void InitPlugins()
|
private void InitPlugins()
|
||||||
{
|
{
|
||||||
var allPlugins = new List<IComponent>(LegacyEntry.Instance.NativePlugins);
|
var allPlugins = new List<IComponent>(Game.Instance.NativePlugins);
|
||||||
allPlugins.AddRange(LegacyEntry.Instance.Plugins);
|
allPlugins.AddRange(Game.Instance.Plugins);
|
||||||
foreach (var plugin in allPlugins)
|
foreach (var plugin in allPlugins)
|
||||||
{
|
{
|
||||||
plugin.LuaInit(Thread);
|
plugin.LuaInit(Thread);
|
||||||
|
|
|
@ -25,8 +25,8 @@ public class ObjectManager : IComponent
|
||||||
{
|
{
|
||||||
private static readonly ConcurrentDictionary<nint, object> _objects = new();
|
private static readonly ConcurrentDictionary<nint, object> _objects = new();
|
||||||
|
|
||||||
private static LegacyEntry _game;
|
private static Game _game;
|
||||||
public ObjectManager(LegacyEntry game)
|
public ObjectManager(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
_game.EventEmitter.OnClose += OnClose;
|
_game.EventEmitter.OnClose += OnClose;
|
||||||
|
|
|
@ -88,7 +88,7 @@ public class FileHandle : IComponent
|
||||||
new(),
|
new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
public FileHandle(LegacyEntry _) { }
|
public FileHandle(Game _) { }
|
||||||
|
|
||||||
public void LuaInit(Lua L)
|
public void LuaInit(Lua L)
|
||||||
{
|
{
|
||||||
|
|
|
@ -66,8 +66,8 @@ public class GPUBufferMeta : IComponent
|
||||||
new(),
|
new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
private static LegacyEntry _game;
|
private static Game _game;
|
||||||
public GPUBufferMeta(LegacyEntry game)
|
public GPUBufferMeta(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ public class Socket : IDisposable
|
||||||
|
|
||||||
public class SocketLib : IComponent
|
public class SocketLib : IComponent
|
||||||
{
|
{
|
||||||
private static LegacyEntry _game = null!;
|
private static Game _game = null!;
|
||||||
public SocketLib(LegacyEntry game)
|
public SocketLib(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@ namespace Capy64.Runtime.Objects;
|
||||||
|
|
||||||
public class TaskMeta : IComponent
|
public class TaskMeta : IComponent
|
||||||
{
|
{
|
||||||
private static LegacyEntry _game;
|
private static Game _game;
|
||||||
public TaskMeta(LegacyEntry game)
|
public TaskMeta(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class WebSocketClient : IComponent
|
||||||
new(),
|
new(),
|
||||||
};
|
};
|
||||||
|
|
||||||
public WebSocketClient(LegacyEntry _) { }
|
public WebSocketClient(Game _) { }
|
||||||
|
|
||||||
public void LuaInit(Lua L)
|
public void LuaInit(Lua L)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
using Capy64.Runtime.Libraries;
|
using Capy64.Runtime.Libraries;
|
||||||
using Microsoft.Xna.Framework;
|
using Capy64.Utils;
|
||||||
|
|
||||||
namespace Capy64.Runtime;
|
namespace Capy64.Runtime;
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ internal class RuntimeManager : IComponent
|
||||||
private static bool close = false;
|
private static bool close = false;
|
||||||
private static bool inPanic = false;
|
private static bool inPanic = false;
|
||||||
|
|
||||||
private static LegacyEntry _game;
|
private static Game _game;
|
||||||
public RuntimeManager(LegacyEntry game)
|
public RuntimeManager(Game game)
|
||||||
{
|
{
|
||||||
_game = game;
|
_game = game;
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ internal class RuntimeManager : IComponent
|
||||||
|
|
||||||
private void InitBIOS()
|
private void InitBIOS()
|
||||||
{
|
{
|
||||||
_game.Discord.SetPresence("Booting up...");
|
//_game.Discord.SetPresence("Booting up...");
|
||||||
|
|
||||||
InstallOS(false);
|
InstallOS(false);
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ internal class RuntimeManager : IComponent
|
||||||
public static void Shutdown()
|
public static void Shutdown()
|
||||||
{
|
{
|
||||||
close = true;
|
close = true;
|
||||||
_game.Exit();
|
//_game.Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InstallOS(bool force = false)
|
public static void InstallOS(bool force = false)
|
||||||
|
|
|
@ -13,33 +13,20 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// 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;
|
namespace Capy64.Utils;
|
||||||
|
|
||||||
public static class Utils
|
public struct Borders
|
||||||
{
|
{
|
||||||
public struct Borders
|
public int Top { get; set; }
|
||||||
{
|
public int Bottom { get; set; }
|
||||||
public int Top, Bottom, Left, Right;
|
public int Left { get; set; }
|
||||||
}
|
public int Right { get; set; }
|
||||||
|
public Color Color { get; set; }
|
||||||
/// <summary>
|
public float Size { get; set; }
|
||||||
/// Return the sane 0xRRGGBB format
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="color"></param>
|
|
||||||
public static int PackRGB(Color color)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
(color.R << 16) +
|
|
||||||
(color.G << 8) +
|
|
||||||
color.B;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void UnpackRGB(uint packed, out byte r, out byte g, out byte b)
|
|
||||||
{
|
|
||||||
b = (byte)(packed & 0xff);
|
|
||||||
g = (byte)((packed >> 8) & 0xff);
|
|
||||||
r = (byte)((packed >> 16) & 0xff);
|
|
||||||
}
|
|
||||||
}
|
}
|
103
Capy64/Utils/Color.cs
Normal file
103
Capy64/Utils/Color.cs
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
// 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 System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using static SDL2.SDL;
|
||||||
|
|
||||||
|
namespace Capy64.Utils;
|
||||||
|
|
||||||
|
public struct Color
|
||||||
|
{
|
||||||
|
public byte R
|
||||||
|
{
|
||||||
|
get => (byte)(PackedValue >> 16);
|
||||||
|
set => PackedValue = PackedValue & 0xFF00FFFFu | (uint)value << 16;
|
||||||
|
}
|
||||||
|
public byte G
|
||||||
|
{
|
||||||
|
get => (byte)(PackedValue >> 8);
|
||||||
|
set => PackedValue = PackedValue & 0xFFFF00FFu | (uint)value << 8;
|
||||||
|
}
|
||||||
|
public byte B
|
||||||
|
{
|
||||||
|
get => (byte)PackedValue;
|
||||||
|
set => PackedValue = PackedValue & 0xFFFFFF00u | value;
|
||||||
|
}
|
||||||
|
public byte A
|
||||||
|
{
|
||||||
|
get => (byte)(PackedValue >> 24);
|
||||||
|
set => PackedValue = PackedValue & 0x00FFFFFFu | (uint)value << 24;
|
||||||
|
}
|
||||||
|
public uint PackedRGB => PackedValue & 0xFFFFFFu;
|
||||||
|
public uint PackedValue { get; set; }
|
||||||
|
|
||||||
|
public Color(byte r, byte g, byte b)
|
||||||
|
{
|
||||||
|
R = r;
|
||||||
|
G = g;
|
||||||
|
B = b;
|
||||||
|
A = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color(byte r, byte g, byte b, byte a)
|
||||||
|
{
|
||||||
|
R = r;
|
||||||
|
G = g;
|
||||||
|
B = b;
|
||||||
|
A = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color(uint packedValue)
|
||||||
|
{
|
||||||
|
PackedValue = packedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SDL_Color ToSDL() => new()
|
||||||
|
{
|
||||||
|
r = R,
|
||||||
|
g = G,
|
||||||
|
b = B,
|
||||||
|
a = A,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static Color Transparent { get; private set; }
|
||||||
|
public static Color Black { get; private set; }
|
||||||
|
public static Color White { get; private set; }
|
||||||
|
public static Color Gray { get; private set; }
|
||||||
|
public static Color Red { get; private set; }
|
||||||
|
public static Color Green { get; private set; }
|
||||||
|
public static Color Blue { get; private set; }
|
||||||
|
public static Color Yellow { get; private set; }
|
||||||
|
public static Color Magenta { get; private set; }
|
||||||
|
public static Color Cyan { get; private set; }
|
||||||
|
|
||||||
|
static Color()
|
||||||
|
{
|
||||||
|
Transparent = new Color(0u);
|
||||||
|
Black = new Color(0, 0, 0);
|
||||||
|
White = new Color(255, 255, 255);
|
||||||
|
Gray = new Color(128, 128, 128);
|
||||||
|
Red = new Color(255, 0, 0);
|
||||||
|
Green = new Color(0, 255, 0);
|
||||||
|
Blue = new Color(0, 0, 255);
|
||||||
|
Yellow = new Color(255, 255, 0);
|
||||||
|
Magenta = new Color(255, 0, 255);
|
||||||
|
Cyan = new Color(0, 255, 255);
|
||||||
|
}
|
||||||
|
}
|
124
Capy64/Utils/Point.cs
Normal file
124
Capy64/Utils/Point.cs
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
// 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 System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Capy64.Utils;
|
||||||
|
|
||||||
|
public struct Point : IEquatable<Point>
|
||||||
|
{
|
||||||
|
private static readonly Point zeroPoint;
|
||||||
|
|
||||||
|
[DataMember]
|
||||||
|
public int X;
|
||||||
|
|
||||||
|
[DataMember]
|
||||||
|
public int Y;
|
||||||
|
|
||||||
|
public static Point Zero => zeroPoint;
|
||||||
|
|
||||||
|
internal string DebugDisplayString => X + " " + Y;
|
||||||
|
|
||||||
|
public Point(int x, int y)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point(int value)
|
||||||
|
{
|
||||||
|
X = value;
|
||||||
|
Y = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Point operator +(Point value1, Point value2)
|
||||||
|
{
|
||||||
|
return new Point(value1.X + value2.X, value1.Y + value2.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Point operator -(Point value1, Point value2)
|
||||||
|
{
|
||||||
|
return new Point(value1.X - value2.X, value1.Y - value2.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Point operator *(Point value1, Point value2)
|
||||||
|
{
|
||||||
|
return new Point(value1.X * value2.X, value1.Y * value2.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Point operator /(Point source, Point divisor)
|
||||||
|
{
|
||||||
|
return new Point(source.X / divisor.X, source.Y / divisor.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(Point a, Point b)
|
||||||
|
{
|
||||||
|
return a.Equals(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(Point a, Point b)
|
||||||
|
{
|
||||||
|
return !a.Equals(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj is Point)
|
||||||
|
{
|
||||||
|
return Equals((Point)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(Point other)
|
||||||
|
{
|
||||||
|
if (X == other.X)
|
||||||
|
{
|
||||||
|
return Y == other.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return (17 * 23 + X.GetHashCode()) * 23 + Y.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "{X:" + X + " Y:" + Y + "}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public Vector2 ToVector2()
|
||||||
|
{
|
||||||
|
return new Vector2(X, Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Deconstruct(out int x, out int y)
|
||||||
|
{
|
||||||
|
x = X;
|
||||||
|
y = Y;
|
||||||
|
}
|
||||||
|
}
|
164
Capy64/Utils/Size2.cs
Normal file
164
Capy64/Utils/Size2.cs
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
// 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 MonoGame.Extended;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Capy64.Utils;
|
||||||
|
|
||||||
|
public struct Size2 : IEquatable<Size2>, IEquatableByRef<Size2>
|
||||||
|
{
|
||||||
|
public static readonly Size2 Empty;
|
||||||
|
|
||||||
|
public float Width;
|
||||||
|
|
||||||
|
public float Height;
|
||||||
|
|
||||||
|
public bool IsEmpty
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Width == 0f)
|
||||||
|
{
|
||||||
|
return Height == 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal string DebugDisplayString => ToString();
|
||||||
|
|
||||||
|
public Size2(float width, float height)
|
||||||
|
{
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(Size2 first, Size2 second)
|
||||||
|
{
|
||||||
|
return first.Equals(ref second);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(Size2 size)
|
||||||
|
{
|
||||||
|
return Equals(ref size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(ref Size2 size)
|
||||||
|
{
|
||||||
|
if (Width == size.Width)
|
||||||
|
{
|
||||||
|
return Height == size.Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj is Size2)
|
||||||
|
{
|
||||||
|
return Equals((Size2)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(Size2 first, Size2 second)
|
||||||
|
{
|
||||||
|
return !(first == second);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Size2 operator +(Size2 first, Size2 second)
|
||||||
|
{
|
||||||
|
return Add(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Size2 Add(Size2 first, Size2 second)
|
||||||
|
{
|
||||||
|
Size2 result = default(Size2);
|
||||||
|
result.Width = first.Width + second.Width;
|
||||||
|
result.Height = first.Height + second.Height;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Size2 operator -(Size2 first, Size2 second)
|
||||||
|
{
|
||||||
|
return Subtract(first, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Size2 operator /(Size2 size, float value)
|
||||||
|
{
|
||||||
|
return new Size2(size.Width / value, size.Height / value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Size2 operator *(Size2 size, float value)
|
||||||
|
{
|
||||||
|
return new Size2(size.Width * value, size.Height * value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Size2 Subtract(Size2 first, Size2 second)
|
||||||
|
{
|
||||||
|
Size2 result = default(Size2);
|
||||||
|
result.Width = first.Width - second.Width;
|
||||||
|
result.Height = first.Height - second.Height;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
return (Width.GetHashCode() * 397) ^ Height.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Size2(Point2 point)
|
||||||
|
{
|
||||||
|
return new Size2(point.X, point.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Size2(Point point)
|
||||||
|
{
|
||||||
|
return new Size2(point.X, point.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Point2(Size2 size)
|
||||||
|
{
|
||||||
|
return new Point2(size.Width, size.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Vector2(Size2 size)
|
||||||
|
{
|
||||||
|
return new Vector2(size.Width, size.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Size2(Vector2 vector)
|
||||||
|
{
|
||||||
|
return new Size2(vector.X, vector.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator Point(Size2 size)
|
||||||
|
{
|
||||||
|
return new Point((int)size.Width, (int)size.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"Width: {Width}, Height: {Height}";
|
||||||
|
}
|
||||||
|
}
|
149
Capy64/Utils/Vector2.cs
Normal file
149
Capy64/Utils/Vector2.cs
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
// 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 System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Capy64.Utils;
|
||||||
|
|
||||||
|
public struct Vector2 : IEquatable<Vector2>
|
||||||
|
{
|
||||||
|
private static readonly Vector2 zeroVector = new(0f, 0f);
|
||||||
|
private static readonly Vector2 unitVector = new(1f, 1f);
|
||||||
|
private static readonly Vector2 unitXVector = new(1f, 0f);
|
||||||
|
private static readonly Vector2 unitYVector = new(0f, 1f);
|
||||||
|
public static Vector2 Zero => zeroVector;
|
||||||
|
public static Vector2 One => unitVector;
|
||||||
|
public static Vector2 UnitX => unitXVector;
|
||||||
|
public static Vector2 UnitY => unitYVector;
|
||||||
|
|
||||||
|
public float X { get; set; }
|
||||||
|
public float Y { get; set; }
|
||||||
|
|
||||||
|
public Vector2(float x, float y)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2(float value)
|
||||||
|
{
|
||||||
|
X = value;
|
||||||
|
Y = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator Vector2(System.Numerics.Vector2 value)
|
||||||
|
{
|
||||||
|
return new Vector2(value.X, value.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 operator -(Vector2 value)
|
||||||
|
{
|
||||||
|
value.X = 0f - value.X;
|
||||||
|
value.Y = 0f - value.Y;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 operator +(Vector2 value1, Vector2 value2)
|
||||||
|
{
|
||||||
|
value1.X += value2.X;
|
||||||
|
value1.Y += value2.Y;
|
||||||
|
return value1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 operator -(Vector2 value1, Vector2 value2)
|
||||||
|
{
|
||||||
|
value1.X -= value2.X;
|
||||||
|
value1.Y -= value2.Y;
|
||||||
|
return value1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 operator *(Vector2 value1, Vector2 value2)
|
||||||
|
{
|
||||||
|
value1.X *= value2.X;
|
||||||
|
value1.Y *= value2.Y;
|
||||||
|
return value1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 operator *(Vector2 value, float scaleFactor)
|
||||||
|
{
|
||||||
|
value.X *= scaleFactor;
|
||||||
|
value.Y *= scaleFactor;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector2 operator *(float scaleFactor, Vector2 value)
|
||||||
|
{
|
||||||
|
value.X *= scaleFactor;
|
||||||
|
value.Y *= scaleFactor;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Vector2 operator /(Vector2 value1, Vector2 value2)
|
||||||
|
{
|
||||||
|
value1.X /= value2.X;
|
||||||
|
value1.Y /= value2.Y;
|
||||||
|
return value1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static Vector2 operator /(Vector2 value1, float divider)
|
||||||
|
{
|
||||||
|
float num = 1f / divider;
|
||||||
|
value1.X *= num;
|
||||||
|
value1.Y *= num;
|
||||||
|
return value1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(Vector2 value1, Vector2 value2)
|
||||||
|
{
|
||||||
|
if (value1.X == value2.X)
|
||||||
|
{
|
||||||
|
return value1.Y == value2.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(Vector2 value1, Vector2 value2)
|
||||||
|
{
|
||||||
|
if (value1.X == value2.X)
|
||||||
|
{
|
||||||
|
return value1.Y != value2.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (obj is Vector2)
|
||||||
|
{
|
||||||
|
return Equals((Vector2)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(Vector2 other)
|
||||||
|
{
|
||||||
|
return X == other.X && Y == other.Y;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue