Too many changes.

This commit is contained in:
Alessandro Proto 2023-09-03 22:27:54 +02:00
parent 110afd1ca4
commit 4681c7060e
29 changed files with 1008 additions and 182 deletions

View file

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<RollForward>Major</RollForward>
<PublishReadyToRun>false</PublishReadyToRun>

122
Capy64/Core/Canvas.cs Normal file
View 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);
}
}

View file

@ -20,20 +20,31 @@ using System;
using System.Collections.Generic;
using System.Linq;
using SDL2;
using Newtonsoft.Json.Linq;
namespace Capy64.Eventing;
public class InputManager
{
// SDL inverts Right and Middle (2 and 3)
public enum MouseButton
{
Left = 1,
Right = 2,
Middle = 3,
Right = 3,
Middle = 2,
Button4 = 4,
Button5 = 5,
}
private Dictionary<MouseButton, int> MouseMap = new()
{
[MouseButton.Left] = 1,
[MouseButton.Right] = 2,
[MouseButton.Middle] = 3,
[MouseButton.Button4] = 4,
[MouseButton.Button5] = 5,
};
[Flags]
public enum Modifiers
{
@ -75,7 +86,6 @@ public class InputManager
};
public Texture2D Texture { get; set; }
public static float WindowScale => LegacyEntry.Instance.Scale;
public const int MouseScrollDelta = 120;
private Point mousePosition;
@ -85,9 +95,9 @@ public class InputManager
private Modifiers keyboardMods = 0;
private readonly HashSet<Keys> pressedKeys = new();
private readonly Capy64 _game;
private readonly Game _game;
private readonly EventEmitter _eventEmitter;
public InputManager(Capy64 game, EventEmitter eventManager)
public InputManager(Game game, EventEmitter eventManager)
{
_game = game;
@ -109,11 +119,16 @@ public class InputManager
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 rawPosition = position - new Point(LegacyEntry.Instance.Borders.Left, LegacyEntry.Instance.Borders.Top);
var pos = new Point((int)(rawPosition.X / WindowScale), (int)(rawPosition.Y / WindowScale)) + new Point(1, 1);
var position = new Point(x, y);
var rawPosition = position - new Point(_game.Borders.Left, _game.Borders.Top);
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)
return;
@ -121,6 +136,9 @@ public class InputManager
if (pos != mousePosition)
{
mousePosition = pos;
Console.WriteLine("MOTION {0} {1} {2}", pos.X, pos.Y, ev.button.state);
_eventEmitter.RaiseMouseMove(new()
{
Position = mousePosition,
@ -130,7 +148,36 @@ public class InputManager
.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)
@ -138,8 +185,8 @@ public class InputManager
if (!isActive)
return;
var rawPosition = state.Position - new Point(LegacyEntry.Instance.Borders.Left, LegacyEntry.Instance.Borders.Top);
var pos = new Point((int)(rawPosition.X / WindowScale), (int)(rawPosition.Y / WindowScale)) + new Point(1, 1);
var rawPosition = state.Position - new Point(_game.Borders.Left, _game.Borders.Top);
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)
return;

View file

@ -13,20 +13,27 @@
// See the License for the specific language governing permissions and
// limitations under the License.
using Capy64.API;
using Capy64.Core;
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;
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using static Utils;
using static SDL2.SDL;
public class Capy64 : IDisposable
public class Game : IDisposable
{
public static Game Instance { get; private set; }
public const string Version = "1.1.0-beta";
public nint Window { 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 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;
set {
set
{
_borders = value;
_outputRect = new() {
_outputRect = new()
{
x = value.Left,
y = value.Top,
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 AssetsPath = Path.Combine(AssemblyPath, "Assets");
public IConfiguration Configuration { get; private set; }
public static class DefaultParameters
{
@ -76,8 +89,10 @@ public class Capy64 : IDisposable
public const int FreeTickrate = 60;
}
public static string AppDataPath {
get {
public static string AppDataPath
{
get
{
string baseDir =
RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData,
@ -96,21 +111,73 @@ public class Capy64 : IDisposable
private bool _running = false;
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();
WindowWidth = (int)(Width * Scale) + Borders.Left + Borders.Right;
WindowHeight = (int)(Height * Scale) + Borders.Top + Borders.Bottom;
UpdateSize();
_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()
{
var size = (int)(Scale * DefaultParameters.BorderMultiplier);
Borders = new Borders {
Borders = new Borders
{
Top = size,
Bottom = 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()
{
Initialize();
#if DEBUG
SDL_SetHint(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, "1");
#endif
@ -158,31 +239,23 @@ public class Capy64 : IDisposable
VideoSurface = SDL_CreateRGBSurfaceWithFormat(0, Width, Height, 32, SDL_PIXELFORMAT_ARGB8888);
SurfaceRenderer = SDL_CreateSoftwareRenderer(VideoSurface);
SDL_SetRenderDrawColor(SurfaceRenderer, 255, 255, 255, 255);
SDL_SetRenderDrawColor(SurfaceRenderer, 0, 0, 0, 255);
SDL_RenderClear(SurfaceRenderer);
_running = true;
EventEmitter.RaiseInit();
ulong deltaEnd = 0;
var perfFreq = SDL_GetPerformanceFrequency();
while (_running)
{
var deltaStart = SDL_GetPerformanceCounter();
var delta = deltaStart - deltaEnd;
while (SDL_PollEvent(out var ev) != 0)
{
ProcessEvent(ev);
}
ulong totalTicks = 0;
if ((uint)(perfFreq / delta) >= Framerate)
var drawTimer = new Timer(TimeSpan.FromMilliseconds(1000d / Framerate));
drawTimer.Elapsed += (s, e) =>
{
continue;
}
deltaEnd = deltaStart;
SDL_SetRenderDrawColor(Renderer, BorderColor.R, BorderColor.G, BorderColor.B, 255);
SDL_RenderClear(Renderer);
SDL_SetRenderDrawColor(Renderer, 255, 255, 255, 255);
var texture = SDL_CreateTextureFromSurface(Renderer, VideoSurface);
@ -190,7 +263,49 @@ public class Capy64 : IDisposable
SDL_RenderCopy(Renderer, texture, 0, ref _outputRect);
SDL_DestroyTexture(texture);
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:
_running = false;
Dispose();
break;
case SDL_EventType.SDL_KEYUP:
case SDL_EventType.SDL_KEYDOWN:
break;
case SDL_EventType.SDL_MOUSEMOTION:
_inputManager.UpdateMouseMove(ev);
break;
case SDL_EventType.SDL_MOUSEBUTTONUP:
case SDL_EventType.SDL_MOUSEBUTTONDOWN:
_inputManager.UpdateMouseClick(ev);
break;
unsafe
{
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;
}
}
@ -221,10 +340,9 @@ public class Capy64 : IDisposable
public void Dispose()
{
SDL_DestroyRenderer(SurfaceRenderer);
SDL_FreeSurface(VideoSurface);
//SDL_FreeSurface(VideoSurface);
SDL_DestroyRenderer(Renderer);
SDL_DestroyWindow(Window);
SDL_Quit();
}
}

View file

@ -24,11 +24,12 @@ namespace Capy64.Integrations;
public class DiscordIntegration : IComponent
{
public static DiscordIntegration Instance { get; private set; }
public DiscordRpcClient Client { get; private set; }
public readonly bool Enabled;
private readonly IConfiguration _configuration;
public DiscordIntegration(LegacyEntry game)
public DiscordIntegration(Game game)
{
_configuration = game.Configuration;
@ -42,7 +43,7 @@ public class DiscordIntegration : IComponent
Client.OnReady += OnReady;
LegacyEntry.Instance.Discord = this;
Instance = this;
if (Enabled)
Client.Initialize();

View file

@ -20,6 +20,7 @@ using Capy64.Extensions;
using Capy64.Integrations;
using Capy64.PluginManager;
using Capy64.Runtime;
using Capy64.Utils;
using Microsoft.Extensions.Configuration;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@ -31,7 +32,6 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using static Capy64.Utils;
namespace Capy64;
@ -41,7 +41,7 @@ public enum EngineMode
Free
}
public class LegacyEntry : Game
public class LegacyEntry : Microsoft.Xna.Framework.Game
{
public const string Version = "1.1.0-beta";
@ -96,7 +96,7 @@ public class LegacyEntry : Game
public int TickRate => tickrate;
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()
{
@ -315,7 +315,7 @@ public class LegacyEntry : Game
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);
SpriteBatch.DrawRectangle(renderTarget.Bounds.Location.ToVector2() + new Vector2(Borders.Left, Borders.Top),
@ -333,6 +333,6 @@ public class LegacyEntry : Game
SpriteBatch.End();
base.Draw(gameTime);
base.Draw(gameTime);*/
}
}

View file

@ -17,7 +17,7 @@ using Capy64;
if (args.Length > 0 && args[0] == "sdl")
{
using var game = new Capy64.Capy64();
using var game = new Capy64.Game();
game.Run();
}

View file

@ -25,8 +25,8 @@ public class AudioLib : IComponent
{
private const int queueLimit = 8;
private static LegacyEntry _game;
public AudioLib(LegacyEntry game)
private static Game _game;
public AudioLib(Game game)
{
_game = game;
_game.EventEmitter.OnClose += OnClose;

View file

@ -29,8 +29,8 @@ public class EventLib : IComponent
private static bool FrozenTaskAwaiter = false;
private static LegacyEntry _game;
public EventLib(LegacyEntry game)
private static Game _game;
public EventLib(Game game)
{
_game = game;
}

View file

@ -111,7 +111,7 @@ public class FileSystemLib : IComponent
new(), // NULL
};
public FileSystemLib(LegacyEntry _) { }
public FileSystemLib(Game _) { }
public void LuaInit(Lua state)
{

View file

@ -15,9 +15,8 @@
using Capy64.API;
using Capy64.Runtime.Objects;
using Capy64.Utils;
using KeraLua;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.IO;
@ -28,8 +27,8 @@ namespace Capy64.Runtime.Libraries;
public class GPULib : IComponent
{
private static LegacyEntry _game;
public GPULib(LegacyEntry game)
private static Game _game;
public GPULib(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)
{
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)
@ -174,10 +175,12 @@ public class GPULib : IComponent
{
var L = Lua.FromIntPtr(state);
if (_game.EngineMode == EngineMode.Classic)
return 0;
/*if (_game.EngineMode == EngineMode.Classic)
{
return L.Error("Screen is not resizable");
}
}*/
var w = L.CheckInteger(1);
var h = L.CheckInteger(2);
@ -196,7 +199,8 @@ public class GPULib : IComponent
{
var L = Lua.FromIntPtr(state);
L.PushBoolean(_game.EngineMode != EngineMode.Classic);
//L.PushBoolean(_game.EngineMode != EngineMode.Classic);
L.PushBoolean(false);
return 1;
}
@ -208,9 +212,11 @@ public class GPULib : IComponent
var x = (int)L.CheckNumber(1) - 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;
}
@ -224,7 +230,7 @@ public class GPULib : IComponent
var c = L.CheckInteger(3);
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;
}
@ -259,7 +265,7 @@ public class GPULib : IComponent
}
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;
}
@ -274,7 +280,7 @@ public class GPULib : IComponent
var s = (int)L.OptNumber(4, 1);
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;
}
@ -291,7 +297,7 @@ public class GPULib : IComponent
var s = (int)L.OptInteger(6, -1);
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;
}
@ -308,7 +314,7 @@ public class GPULib : IComponent
var s = (int)L.OptNumber(6, 1);
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;
}
@ -325,7 +331,7 @@ public class GPULib : IComponent
var s = (int)L.OptNumber(6, 1);
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;
}
@ -361,7 +367,7 @@ public class GPULib : IComponent
}
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;
}
@ -378,7 +384,7 @@ public class GPULib : IComponent
var s = (int)L.OptNumber(6, 1);
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;
}
@ -395,7 +401,7 @@ public class GPULib : IComponent
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));
//_game.Drawing.DrawString(new Vector2(x, y), t, new Color(r, g, b));
}
catch (ArgumentException ex) // UTF-16 fuckery
{
@ -411,10 +417,10 @@ public class GPULib : IComponent
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.Y);
//L.PushNumber((int)sizes.X);
//L.PushNumber((int)sizes.Y);
return 2;
}
@ -425,7 +431,7 @@ public class GPULib : IComponent
var buffer = new uint[_game.Width * _game.Height];
_game.Drawing.Canvas.GetData(buffer);
//_game.Drawing.Canvas.GetData(buffer);
var gpuBuffer = new GPUBufferMeta.GPUBuffer
{
@ -446,7 +452,7 @@ public class GPULib : IComponent
var buffer = GPUBufferMeta.CheckBuffer(L, false);
_game.Drawing.Canvas.SetData(buffer.Buffer);
//_game.Drawing.Canvas.SetData(buffer.Buffer);
return 0;
}
@ -533,7 +539,7 @@ public class GPULib : IComponent
var x = (int)L.CheckInteger(2) - 1;
var y = (int)L.CheckInteger(3) - 1;
Rectangle? source = null;
/*Rectangle? source = null;
Color color = Color.White;
float rotation = 0;
Vector2 origin = Vector2.Zero;
@ -634,7 +640,7 @@ public class GPULib : IComponent
Width = buffer.Width,
Height = buffer.Height,
}, source, color, rotation, origin, scale, effects);
*/
return 0;
}
@ -654,10 +660,10 @@ public class GPULib : IComponent
var task = TaskMeta.Push(L, GPUBufferMeta.ObjectType);
Texture2D texture;
//Texture2D texture;
try
{
texture = Texture2D.FromFile(LegacyEntry.Instance.Drawing.Canvas.GraphicsDevice, path);
//texture = Texture2D.FromFile(LegacyEntry.Instance.Drawing.Canvas.GraphicsDevice, path);
}
catch (Exception e)
{
@ -665,8 +671,8 @@ public class GPULib : IComponent
return 1;
}
var data = new uint[texture.Width * texture.Height];
texture.GetData(data);
//var data = new uint[texture.Width * texture.Height];
//texture.GetData(data);
Task.Run(() =>
{
@ -695,7 +701,7 @@ public class GPULib : IComponent
}
}*/
var buffer = new GPUBufferMeta.GPUBuffer
/*var buffer = new GPUBufferMeta.GPUBuffer
{
Buffer = data,
Height = texture.Height,
@ -708,7 +714,7 @@ public class GPULib : IComponent
lk.SetMetaTable(GPUBufferMeta.ObjectType);
});
texture.Dispose();
texture.Dispose();*/
});
return 1;
@ -721,7 +727,7 @@ public class GPULib : IComponent
var c = L.OptInteger(1, 0x000000);
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;
}

View file

@ -30,7 +30,7 @@ namespace Capy64.Runtime.Libraries;
#nullable enable
public class HTTPLib : IComponent
{
private static LegacyEntry _game = null!;
private static Game _game = null!;
private static HttpClient _httpClient = null!;
private static long _requestId;
public static readonly HashSet<WebSocketClient.Client> WebSocketConnections = new();
@ -57,7 +57,7 @@ public class HTTPLib : IComponent
},
new(),
};
public HTTPLib(LegacyEntry game)
public HTTPLib(Game game)
{
_game = game;
_requestId = 0;

View file

@ -24,8 +24,8 @@ namespace Capy64.Runtime.Libraries;
public class MachineLib : IComponent
{
private static LegacyEntry _game;
public MachineLib(LegacyEntry game)
private static Game _game;
public MachineLib(Game game)
{
_game = game;
}

View file

@ -15,11 +15,9 @@
using Capy64.API;
using Capy64.Eventing.Events;
using Capy64.Utils;
using KeraLua;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using static Capy64.Utils;
namespace Capy64.Runtime.Libraries;
@ -49,11 +47,11 @@ internal class TermLib : IComponent
public static Color BackgroundColor { get; set; }
private static Char?[] CharGrid;
private static LegacyEntry _game;
private static Game _game;
private static bool cursorState = false;
private static bool enableCursor = true;
private static Texture2D cursorTexture;
public TermLib(LegacyEntry game)
//private static Texture2D cursorTexture;
public TermLib(Game game)
{
_game = game;
@ -61,10 +59,10 @@ internal class TermLib : IComponent
ForegroundColor = Color.White;
BackgroundColor = Color.Black;
cursorTexture = new(_game.Game.GraphicsDevice, 1, CharHeight - 3);
var textureData = new Color[CharHeight - 3];
Array.Fill(textureData, Color.White);
cursorTexture.SetData(textureData);
//cursorTexture = new(_game.Game.GraphicsDevice, 1, CharHeight - 3);
//var textureData = new Color[CharHeight - 3];
//Array.Fill(textureData, Color.White);
//cursorTexture.SetData(textureData);
UpdateSize();
@ -182,7 +180,9 @@ internal class TermLib : IComponent
{
/*if (_game.EngineMode == EngineMode.Classic)
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)
@ -212,22 +212,24 @@ internal class TermLib : IComponent
var realpos = ToRealPos(pos);
var charpos = realpos + CharOffset;
_game.Drawing.DrawRectangle(realpos, new(CharWidth, CharHeight), bg, Math.Min(CharWidth, CharHeight));
//_game.Drawing.DrawRectangle(realpos, new(CharWidth, CharHeight), Color.Red, 1);
_game.Canvas.DrawFilledRectangle(realpos, new(CharWidth, CharHeight), bg);
//_game.Drawing.DrawRectangle(realpos, new(CharWidth, CharHeight), bg, Math.Min(CharWidth, CharHeight));
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
{
_game.Drawing.DrawString(charpos, "\xFFFD", fg);
_game.Canvas.DrawString(charpos, "\xFFFD", fg);
//_game.Drawing.DrawString(charpos, "\xFFFD", fg);
}
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)
@ -318,14 +320,14 @@ internal class TermLib : IComponent
var realpos = ToRealPos(CursorPosition - Vector2.One);
var charpos = (realpos * _game.Scale) + ((CharOffset + new Vector2(0, 2)) * _game.Scale);
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()
{
CharGrid = new Char?[CharGrid.Length];
_game.Drawing.Clear(BackgroundColor);
_game.Canvas.Clear(BackgroundColor);
}
public static void Write(string text)
@ -399,10 +401,12 @@ internal class TermLib : IComponent
{
var L = Lua.FromIntPtr(state);
if (_game.EngineMode == EngineMode.Classic)
{
return L.Error("Terminal is not resizable");
}
return 0;
//if (_game.EngineMode == EngineMode.Classic)
//{
// return L.Error("Terminal is not resizable");
//}
var w = (int)L.CheckNumber(1);
var h = (int)L.CheckNumber(2);
@ -426,7 +430,8 @@ internal class TermLib : IComponent
{
var L = Lua.FromIntPtr(state);
L.PushBoolean(_game.EngineMode != EngineMode.Classic);
//L.PushBoolean(_game.EngineMode != EngineMode.Classic);
L.PushBoolean(false);
return 1;
}
@ -435,7 +440,7 @@ internal class TermLib : IComponent
{
var L = Lua.FromIntPtr(state);
L.PushInteger(PackRGB(ForegroundColor));
L.PushInteger(ForegroundColor.PackedRGB);
return 1;
}
@ -477,7 +482,7 @@ internal class TermLib : IComponent
{
var L = Lua.FromIntPtr(state);
L.PushInteger(PackRGB(BackgroundColor));
L.PushInteger(ForegroundColor.PackedRGB);
return 1;
}

View file

@ -50,11 +50,11 @@ class TimerLib : IComponent
new(),
};
private static LegacyEntry _game;
private static Game _game;
private static uint _timerId = 0;
private static readonly ConcurrentDictionary<uint, Timer> timers = new();
public TimerLib(LegacyEntry game)
public TimerLib(Game game)
{
_game = game;

View file

@ -72,8 +72,8 @@ public class LuaState : IDisposable
private void InitPlugins()
{
var allPlugins = new List<IComponent>(LegacyEntry.Instance.NativePlugins);
allPlugins.AddRange(LegacyEntry.Instance.Plugins);
var allPlugins = new List<IComponent>(Game.Instance.NativePlugins);
allPlugins.AddRange(Game.Instance.Plugins);
foreach (var plugin in allPlugins)
{
plugin.LuaInit(Thread);

View file

@ -25,8 +25,8 @@ public class ObjectManager : IComponent
{
private static readonly ConcurrentDictionary<nint, object> _objects = new();
private static LegacyEntry _game;
public ObjectManager(LegacyEntry game)
private static Game _game;
public ObjectManager(Game game)
{
_game = game;
_game.EventEmitter.OnClose += OnClose;

View file

@ -88,7 +88,7 @@ public class FileHandle : IComponent
new(),
};
public FileHandle(LegacyEntry _) { }
public FileHandle(Game _) { }
public void LuaInit(Lua L)
{

View file

@ -66,8 +66,8 @@ public class GPUBufferMeta : IComponent
new(),
};
private static LegacyEntry _game;
public GPUBufferMeta(LegacyEntry game)
private static Game _game;
public GPUBufferMeta(Game game)
{
_game = game;
}

View file

@ -29,8 +29,8 @@ public class Socket : IDisposable
public class SocketLib : IComponent
{
private static LegacyEntry _game = null!;
public SocketLib(LegacyEntry game)
private static Game _game = null!;
public SocketLib(Game game)
{
_game = game;
}

View file

@ -21,8 +21,8 @@ namespace Capy64.Runtime.Objects;
public class TaskMeta : IComponent
{
private static LegacyEntry _game;
public TaskMeta(LegacyEntry game)
private static Game _game;
public TaskMeta(Game game)
{
_game = game;
}

View file

@ -73,7 +73,7 @@ public class WebSocketClient : IComponent
new(),
};
public WebSocketClient(LegacyEntry _) { }
public WebSocketClient(Game _) { }
public void LuaInit(Lua L)
{

View file

@ -14,7 +14,7 @@
// limitations under the License.
using Capy64.Runtime.Libraries;
using Microsoft.Xna.Framework;
using Capy64.Utils;
namespace Capy64.Runtime;

View file

@ -32,8 +32,8 @@ internal class RuntimeManager : IComponent
private static bool close = false;
private static bool inPanic = false;
private static LegacyEntry _game;
public RuntimeManager(LegacyEntry game)
private static Game _game;
public RuntimeManager(Game game)
{
_game = game;
@ -95,7 +95,7 @@ internal class RuntimeManager : IComponent
private void InitBIOS()
{
_game.Discord.SetPresence("Booting up...");
//_game.Discord.SetPresence("Booting up...");
InstallOS(false);
@ -207,7 +207,7 @@ internal class RuntimeManager : IComponent
public static void Shutdown()
{
close = true;
_game.Exit();
//_game.Exit();
}
public static void InstallOS(bool force = false)

View file

@ -13,33 +13,20 @@
// 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;
namespace Capy64.Utils;
public static class Utils
{
public struct Borders
{
public int Top, Bottom, Left, Right;
}
/// <summary>
/// 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);
}
public int Top { get; set; }
public int Bottom { get; set; }
public int Left { get; set; }
public int Right { get; set; }
public Color Color { get; set; }
public float Size { get; set; }
}

103
Capy64/Utils/Color.cs Normal file
View 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
View 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
View 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
View 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;
}
}