diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..6f98b12
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "FNA"]
+ path = FNA
+ url = https://github.com/FNA-XNA/FNA
+[submodule "FontStashSharp"]
+ path = FontStashSharp
+ url = https://github.com/FontStashSharp/FontStashSharp
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 35d1a04..403f4c7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ Additions
- Added an Enum constructor to GenericInput
- Added RandomPitchModifier and GetRandomPitch to SoundEffectInfo
- Added TextInput class, which is an isolated version of MLEM.Ui's TextField logic
+- Added MLEM.FNA, which is fully compatible with FNA
Improvements
- Allow comparing Keybind and Combination based on the amount of modifiers they have
@@ -31,6 +32,7 @@ Removals
Additions
- Added Element.AutoNavGroup which allows forming groups for auto-navigation
- Added UiMarkdownParser
+- Added MLEM.Ui.FNA, which is fully compatible with FNA
Improvements
- Ensure that Element.IsMouseOver is always accurate by making it an auto-property
@@ -59,6 +61,7 @@ Removals
### MLEM.Extended
Additions
- Added LayerPositionF
+- Added MLEM.Extended.FNA, which is fully compatible with FNA
Improvements
- Allow using a StaticSpriteBatch to render an IndividualTiledMapRenderer
@@ -67,6 +70,7 @@ Improvements
Additions
- Added the ability to add padding to RuntimeTexturePacker texture regions
- Added the ability to pack UniformTextureAtlas and DataTextureAtlas using RuntimeTexturePacker
+- Added MLEM.Data.FNA, which is fully compatible with FNA
Improvements
- Premultiply textures when using RawContentManager
@@ -77,6 +81,10 @@ Improvements
Fixes
- Fixed SoundEffectReader incorrectly claiming it could read ogg and mp3 files
+### MLEM.Startup
+Additions
+- Added MLEM.Startup.FNA, which is fully compatible with FNA
+
## 5.3.0
### MLEM
Additions
diff --git a/Demos.Android/Demos.Android.csproj b/Demos.Android/Demos.Android.csproj
index aef6f1e..0d6ecd8 100644
--- a/Demos.Android/Demos.Android.csproj
+++ b/Demos.Android/Demos.Android.csproj
@@ -80,7 +80,7 @@
-
+
diff --git a/Demos.DesktopGL/Demos.DesktopGL.FNA.csproj b/Demos.DesktopGL/Demos.DesktopGL.FNA.csproj
new file mode 100644
index 0000000..988c685
--- /dev/null
+++ b/Demos.DesktopGL/Demos.DesktopGL.FNA.csproj
@@ -0,0 +1,37 @@
+
+
+
+ Exe
+ net5.0
+ Icon.ico
+ MLEM Desktop Demos
+ Demos.DesktopGL
+ $(DefineConstants);FNA
+
+ DesktopGL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+ %(Filename)%(Extension)
+
+
+
+
diff --git a/Demos.DesktopGL/FNA/FAudio.dll b/Demos.DesktopGL/FNA/FAudio.dll
new file mode 100644
index 0000000..57c6067
Binary files /dev/null and b/Demos.DesktopGL/FNA/FAudio.dll differ
diff --git a/Demos.DesktopGL/FNA/FNA3D.dll b/Demos.DesktopGL/FNA/FNA3D.dll
new file mode 100644
index 0000000..fe8024f
Binary files /dev/null and b/Demos.DesktopGL/FNA/FNA3D.dll differ
diff --git a/Demos.DesktopGL/FNA/SDL2.dll b/Demos.DesktopGL/FNA/SDL2.dll
new file mode 100644
index 0000000..7a6c63d
Binary files /dev/null and b/Demos.DesktopGL/FNA/SDL2.dll differ
diff --git a/Demos.DesktopGL/FNA/libFAudio.0.dylib b/Demos.DesktopGL/FNA/libFAudio.0.dylib
new file mode 100644
index 0000000..035020c
Binary files /dev/null and b/Demos.DesktopGL/FNA/libFAudio.0.dylib differ
diff --git a/Demos.DesktopGL/FNA/libFAudio.so.0 b/Demos.DesktopGL/FNA/libFAudio.so.0
new file mode 100644
index 0000000..5b3b116
Binary files /dev/null and b/Demos.DesktopGL/FNA/libFAudio.so.0 differ
diff --git a/Demos.DesktopGL/FNA/libFNA3D.0.dylib b/Demos.DesktopGL/FNA/libFNA3D.0.dylib
new file mode 100644
index 0000000..17b80fb
Binary files /dev/null and b/Demos.DesktopGL/FNA/libFNA3D.0.dylib differ
diff --git a/Demos.DesktopGL/FNA/libFNA3D.so.0 b/Demos.DesktopGL/FNA/libFNA3D.so.0
new file mode 100644
index 0000000..b1c1986
Binary files /dev/null and b/Demos.DesktopGL/FNA/libFNA3D.so.0 differ
diff --git a/Demos.DesktopGL/FNA/libMoltenVK.dylib b/Demos.DesktopGL/FNA/libMoltenVK.dylib
new file mode 100644
index 0000000..9cf069d
Binary files /dev/null and b/Demos.DesktopGL/FNA/libMoltenVK.dylib differ
diff --git a/Demos.DesktopGL/FNA/libSDL2-2.0.0.dylib b/Demos.DesktopGL/FNA/libSDL2-2.0.0.dylib
new file mode 100644
index 0000000..71d8bec
Binary files /dev/null and b/Demos.DesktopGL/FNA/libSDL2-2.0.0.dylib differ
diff --git a/Demos.DesktopGL/FNA/libSDL2-2.0.so.0 b/Demos.DesktopGL/FNA/libSDL2-2.0.so.0
new file mode 100644
index 0000000..55d47d4
Binary files /dev/null and b/Demos.DesktopGL/FNA/libSDL2-2.0.so.0 differ
diff --git a/Demos.DesktopGL/FNA/libtheorafile.dll b/Demos.DesktopGL/FNA/libtheorafile.dll
new file mode 100644
index 0000000..a9b2929
Binary files /dev/null and b/Demos.DesktopGL/FNA/libtheorafile.dll differ
diff --git a/Demos.DesktopGL/FNA/libtheorafile.dylib b/Demos.DesktopGL/FNA/libtheorafile.dylib
new file mode 100644
index 0000000..49116fb
Binary files /dev/null and b/Demos.DesktopGL/FNA/libtheorafile.dylib differ
diff --git a/Demos.DesktopGL/FNA/libtheorafile.so b/Demos.DesktopGL/FNA/libtheorafile.so
new file mode 100644
index 0000000..687e841
Binary files /dev/null and b/Demos.DesktopGL/FNA/libtheorafile.so differ
diff --git a/Demos.DesktopGL/FNA/libvulkan.1.dylib b/Demos.DesktopGL/FNA/libvulkan.1.dylib
new file mode 100644
index 0000000..ff138d4
Binary files /dev/null and b/Demos.DesktopGL/FNA/libvulkan.1.dylib differ
diff --git a/Demos.DesktopGL/Program.cs b/Demos.DesktopGL/Program.cs
index 5915bfc..0ec70d1 100644
--- a/Demos.DesktopGL/Program.cs
+++ b/Demos.DesktopGL/Program.cs
@@ -1,11 +1,17 @@
-using Microsoft.Xna.Framework;
+using System;
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Input;
using MLEM.Misc;
namespace Demos.DesktopGL {
public static class Program {
public static void Main() {
+ #if FNA
+ MlemPlatform.Current = new MlemPlatform.DesktopFna(a => TextInputEXT.TextInput += a);
+ #else
MlemPlatform.Current = new MlemPlatform.DesktopGl((w, c) => w.TextInput += c);
+ #endif
using var game = new GameImpl();
game.Run();
}
diff --git a/Demos/AnimationDemo.cs b/Demos/AnimationDemo.cs
index 02b7f66..7b4731f 100644
--- a/Demos/AnimationDemo.cs
+++ b/Demos/AnimationDemo.cs
@@ -90,7 +90,7 @@ namespace Demos {
public override void DoDraw(GameTime gameTime) {
this.GraphicsDevice.Clear(Color.CornflowerBlue);
- this.SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, transformMatrix: Matrix.CreateScale(10));
+ this.SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, Matrix.CreateScale(10));
// draw the group's current region
// if not using a group, just draw the animation's CurrentRegion here
this.SpriteBatch.Draw(this.group.CurrentRegion, new Vector2(10, 10), Color.White);
diff --git a/Demos/AutoTilingDemo.cs b/Demos/AutoTilingDemo.cs
index 0ce21d1..d062f36 100644
--- a/Demos/AutoTilingDemo.cs
+++ b/Demos/AutoTilingDemo.cs
@@ -37,7 +37,7 @@ namespace Demos {
this.GraphicsDevice.Clear(Color.Black);
// drawing the auto tiles
- this.SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, transformMatrix: Matrix.CreateScale(10));
+ this.SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, Matrix.CreateScale(10));
for (var x = 0; x < 6; x++) {
for (var y = 0; y < 5; y++) {
// don't draw non-grass tiles ( )
diff --git a/Demos/Demos.FNA.csproj b/Demos/Demos.FNA.csproj
new file mode 100644
index 0000000..6d088d2
--- /dev/null
+++ b/Demos/Demos.FNA.csproj
@@ -0,0 +1,21 @@
+
+
+
+ netstandard2.0
+ Demos
+ $(DefineConstants);FNA
+
+
+
+
+
+
+
+
+
+
+ all
+
+
+
+
diff --git a/Demos/EasingsDemo.cs b/Demos/EasingsDemo.cs
index c28377b..14d5832 100644
--- a/Demos/EasingsDemo.cs
+++ b/Demos/EasingsDemo.cs
@@ -43,7 +43,7 @@ namespace Demos {
this.GraphicsDevice.Clear(Color.CornflowerBlue);
base.DoDraw(time);
- this.SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp);
+ this.SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null);
var view = this.GraphicsDevice.Viewport;
// graph the easing function
diff --git a/Demos/GameImpl.cs b/Demos/GameImpl.cs
index d058cbc..55dcfd2 100644
--- a/Demos/GameImpl.cs
+++ b/Demos/GameImpl.cs
@@ -9,7 +9,9 @@ using MLEM.Textures;
using MLEM.Ui;
using MLEM.Ui.Elements;
using MLEM.Ui.Style;
+#if !FNA
using MonoGame.Framework.Utilities;
+#endif
namespace Demos {
public class GameImpl : MlemGame {
@@ -47,11 +49,13 @@ namespace Demos {
protected override void LoadContent() {
// TODO remove with MonoGame 3.8.1 https://github.com/MonoGame/MonoGame/issues/7298
+ #if !FNA
if (PlatformInfo.MonoGamePlatform == MonoGamePlatform.DesktopGL) {
this.GraphicsDeviceManager.PreferredBackBufferWidth = 1280;
this.GraphicsDeviceManager.PreferredBackBufferHeight = 720;
this.GraphicsDeviceManager.ApplyChanges();
}
+ #endif
base.LoadContent();
this.UiSystem.AutoScaleReferenceSize = new Point(1280, 720);
diff --git a/Demos/PathfindingDemo.cs b/Demos/PathfindingDemo.cs
index 2325d76..716d33d 100644
--- a/Demos/PathfindingDemo.cs
+++ b/Demos/PathfindingDemo.cs
@@ -35,9 +35,9 @@ namespace Demos {
// Create a cost function, which determines how expensive (or difficult) it should be to move from a given position
// to the next, adjacent position. In our case, the only restriction should be walls and out-of-bounds positions, which
- // both have a cost of AStar2.InfiniteCost, meaning they are completely unwalkable.
+ // both have a cost of AStar2.InfiniteCost, meaning they are completely unwalkable.
// If your game contains harder-to-move-on areas like, say, a muddy pit, you can return a higher cost value for those
- // locations. If you want to scale your cost function differently, you can specify a different default cost in your
+ // locations. If you want to scale your cost function differently, you can specify a different default cost in your
// pathfinder's constructor
float Cost(Point pos, Point nextPos) {
if (nextPos.X < 0 || nextPos.Y < 0 || nextPos.X >= 50 || nextPos.Y >= 50)
@@ -73,7 +73,7 @@ namespace Demos {
public override void DoDraw(GameTime gameTime) {
this.GraphicsDevice.Clear(Color.White);
- this.SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, transformMatrix: Matrix.CreateScale(14));
+ this.SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, Matrix.CreateScale(14));
var tex = this.SpriteBatch.GetBlankTexture();
// draw the world with simple shapes
for (var x = 0; x < 50; x++) {
@@ -87,9 +87,9 @@ namespace Demos {
// in a real game, you'd obviously make your characters walk along the path instead of drawing it
if (this.path != null) {
for (var i = 1; i < this.path.Count; i++) {
- var (firstX, firstY) = this.path[i - 1];
- var (secondX, secondY) = this.path[i];
- this.SpriteBatch.Draw(tex, RectangleF.FromCorners(new Vector2(firstX + 0.25F, firstY + 0.25F), new Vector2(secondX + 0.75F, secondY + 0.75F)), Color.Blue);
+ var first = this.path[i - 1];
+ var second = this.path[i];
+ this.SpriteBatch.Draw(tex, RectangleF.FromCorners(new Vector2(first.X + 0.25F, first.Y + 0.25F), new Vector2(second.X + 0.75F, second.Y + 0.75F)), Color.Blue);
}
}
this.SpriteBatch.End();
diff --git a/Demos/TextFormattingDemo.cs b/Demos/TextFormattingDemo.cs
index c78d5c2..3cd0b8f 100644
--- a/Demos/TextFormattingDemo.cs
+++ b/Demos/TextFormattingDemo.cs
@@ -50,7 +50,7 @@ namespace Demos {
public override void DoDraw(GameTime time) {
this.GraphicsDevice.Clear(Color.DarkSlateGray);
- this.SpriteBatch.Begin(samplerState: SamplerState.PointClamp);
+ this.SpriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null);
// we draw the tokenized text in the center of the screen
// since the text is already center-aligned, we only need to align it on the y axis here
diff --git a/Demos/UiDemo.cs b/Demos/UiDemo.cs
index 89efc7f..1bb7b47 100644
--- a/Demos/UiDemo.cs
+++ b/Demos/UiDemo.cs
@@ -73,7 +73,7 @@ namespace Demos {
// add the root to the demos' ui
this.UiRoot.AddChild(this.root);
- this.root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "This is a small demo for MLEM.Ui, a user interface library that is part of the MLEM Library for Extending MonoGame."));
+ this.root.AddChild(new Paragraph(Anchor.AutoLeft, 1, "This is a small demo for MLEM.Ui, a user interface library that is part of the MLEM Library for Extending MonoGame and FNA."));
var image = this.root.AddChild(new Image(Anchor.AutoCenter, new Vector2(50, 50), new TextureRegion(this.testTexture, 0, 0, 8, 8)) {IsHidden = true, Padding = new Padding(3)});
// Setting the x or y coordinate of the size to 1 or a lower number causes the width or height to be a percentage of the parent's width or height
// (for example, setting the size's x to 0.75 would make the element's width be 0.75*parentWidth)
diff --git a/Docs/index.md b/Docs/index.md
index d30fe1c..21877fb 100644
--- a/Docs/index.md
+++ b/Docs/index.md
@@ -1,6 +1,6 @@
![The MLEM logo](https://raw.githubusercontent.com/Ellpeck/MLEM/release/Media/Banner.png)
-**MLEM Library for Extending MonoGame** is an addition to the game framework [MonoGame](https://www.monogame.net/) that provides extension methods, quality of life improvements and additional features like a ui system and easy input handling.
+**MLEM Library for Extending MonoGame and FNA** is an addition to the game frameworks [MonoGame](https://www.monogame.net/) and [FNA](https://fna-xna.github.io/) that provides extension methods, quality of life improvements and additional features like a ui system and easy input handling.
# What next?
- Get it on [NuGet](https://www.nuget.org/packages?q=mlem)
diff --git a/FNA b/FNA
new file mode 160000
index 0000000..e27bfb5
--- /dev/null
+++ b/FNA
@@ -0,0 +1 @@
+Subproject commit e27bfb5a34112461a6bff960888c0cce2b0c5be2
diff --git a/FontStashSharp b/FontStashSharp
new file mode 160000
index 0000000..460a60c
--- /dev/null
+++ b/FontStashSharp
@@ -0,0 +1 @@
+Subproject commit 460a60ca817e10b6c9bae3e3c05affd1b0bb4ba7
diff --git a/MLEM.Data/Content/RawContentManager.cs b/MLEM.Data/Content/RawContentManager.cs
index db08b7d..785811a 100644
--- a/MLEM.Data/Content/RawContentManager.cs
+++ b/MLEM.Data/Content/RawContentManager.cs
@@ -7,19 +7,22 @@ using Microsoft.Xna.Framework.Graphics;
namespace MLEM.Data.Content {
///
- /// Represents a version of that doesn't load content binary xnb files, but rather as their regular formats.
+ /// Represents a version of that doesn't load content binary xnb files, but rather as their regular formats.
///
public class RawContentManager : ContentManager, IGameComponent {
private static List readers;
- private readonly List disposableAssets = new List();
-
///
/// The graphics device that this content manager uses
///
public readonly GraphicsDevice GraphicsDevice;
+ private readonly List disposableAssets = new List();
+ #if FNA
+ private Dictionary LoadedAssets { get; } = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ #endif
+
///
/// Creates a new content manager with an optionally specified root directory.
///
@@ -50,7 +53,11 @@ namespace MLEM.Data.Content {
/// The original name of the asset.
/// The current asset instance.
/// The asset's type.
- protected override void ReloadAsset(string originalAssetName, T currentAsset) {
+ protected
+ #if !FNA
+ override
+ #endif
+ void ReloadAsset(string originalAssetName, T currentAsset) {
this.Read(originalAssetName, currentAsset);
}
diff --git a/MLEM.Data/Content/Texture2DReader.cs b/MLEM.Data/Content/Texture2DReader.cs
index 27e4c9f..dcaf03c 100644
--- a/MLEM.Data/Content/Texture2DReader.cs
+++ b/MLEM.Data/Content/Texture2DReader.cs
@@ -9,10 +9,13 @@ namespace MLEM.Data.Content {
///
protected override Texture2D Read(RawContentManager manager, string assetPath, Stream stream, Texture2D existing) {
+ #if !FNA
if (existing != null) {
existing.Reload(stream);
return existing;
- } else {
+ } else
+ #endif
+ {
// premultiply the texture's color to be in line with the pipeline's texture reader
// TODO this can be converted to use https://github.com/MonoGame/MonoGame/pull/7369 in the future
using (var texture = Texture2D.FromStream(manager.GraphicsDevice, stream)) {
diff --git a/MLEM.Data/DataTextureAtlas.cs b/MLEM.Data/DataTextureAtlas.cs
index 46c92f7..8373328 100644
--- a/MLEM.Data/DataTextureAtlas.cs
+++ b/MLEM.Data/DataTextureAtlas.cs
@@ -5,12 +5,13 @@ using System.Text.RegularExpressions;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
+using MLEM.Extensions;
using MLEM.Textures;
namespace MLEM.Data {
///
///
- /// This class represents an atlas of objects which are loaded from a special texture atlas file.
+ /// This class represents an atlas of objects which are loaded from a special texture atlas file.
/// To load a data texture atlas, you can use .
///
///
@@ -95,7 +96,7 @@ namespace MLEM.Data {
var loc = new Rectangle(
int.Parse(match.Groups[2].Value), int.Parse(match.Groups[3].Value),
int.Parse(match.Groups[4].Value), int.Parse(match.Groups[5].Value));
- loc.Offset(off);
+ loc.Offset(off.ToPoint());
// pivot
var piv = !match.Groups[6].Success ? Vector2.Zero : off + new Vector2(
diff --git a/MLEM.Data/MLEM.Data.FNA.csproj b/MLEM.Data/MLEM.Data.FNA.csproj
new file mode 100644
index 0000000..d4dae9c
--- /dev/null
+++ b/MLEM.Data/MLEM.Data.FNA.csproj
@@ -0,0 +1,45 @@
+
+
+ netstandard2.0
+ true
+ true
+ MLEM.Data
+ $(DefineConstants);FNA
+ NU1701
+
+
+
+ Ellpeck
+ Simple loading and processing of textures and other data for FNA, including the ability to load non-XNB content files easily
+ See the full changelog at https://mlem.ellpeck.de/CHANGELOG
+ fna ellpeck mlem utility extensions data serialize
+ https://mlem.ellpeck.de/
+ https://github.com/Ellpeck/MLEM
+ MIT
+ Logo.png
+ README.md
+
+
+
+
+
+
+
+ all
+
+
+ all
+
+
+ all
+
+
+ all
+
+
+
+
+
+
+
+
diff --git a/MLEM.Data/MLEM.Data.csproj b/MLEM.Data/MLEM.Data.csproj
index 7cb20da..4d47947 100644
--- a/MLEM.Data/MLEM.Data.csproj
+++ b/MLEM.Data/MLEM.Data.csproj
@@ -3,8 +3,9 @@
netstandard2.0truetrue
+ NU1701
-
+
EllpeckSimple loading and processing of textures and other data for MonoGame, including the ability to load non-XNB content files easily
@@ -15,12 +16,11 @@
MITLogo.pngREADME.md
- NU1701
-
+
-
+
all
@@ -35,9 +35,9 @@
all
-
+
-
\ No newline at end of file
+
diff --git a/MLEM.Data/RuntimeTexturePacker.cs b/MLEM.Data/RuntimeTexturePacker.cs
index 9d6f302..ac1e901 100644
--- a/MLEM.Data/RuntimeTexturePacker.cs
+++ b/MLEM.Data/RuntimeTexturePacker.cs
@@ -170,7 +170,7 @@ namespace MLEM.Data {
foreach (var request in this.texturesToPack.OrderByDescending(t => t.Texture.Width * t.Texture.Height)) {
request.PackedArea = this.FindFreeArea(request);
// if this is the first position that this request fit in, no other requests of the same size will find a position before it
- this.firstPossiblePosForSizeCache[request.PackedArea.Size] = request.PackedArea.Location;
+ this.firstPossiblePosForSizeCache[new Point(request.PackedArea.Width, request.PackedArea.Height)] = request.PackedArea.Location;
this.alreadyPackedTextures.Add(request);
}
stopwatch.Stop();
@@ -198,7 +198,7 @@ namespace MLEM.Data {
// invoke callbacks
foreach (var request in this.alreadyPackedTextures) {
- var packedArea = request.PackedArea.Shrink(new Point(request.Padding));
+ var packedArea = request.PackedArea.Shrink(new Point(request.Padding, request.Padding));
request.Result.Invoke(new TextureRegion(this.PackedTexture, packedArea));
if (this.disposeTextures)
request.Texture.Texture.Dispose();
@@ -232,7 +232,7 @@ namespace MLEM.Data {
var lowestY = int.MaxValue;
while (true) {
var intersected = false;
- var area = new Rectangle(pos, size);
+ var area = new Rectangle(pos.X, pos.Y, size.X, size.Y);
foreach (var tex in this.alreadyPackedTextures) {
if (tex.PackedArea.Intersects(area)) {
pos.X = tex.PackedArea.Right;
@@ -255,7 +255,7 @@ namespace MLEM.Data {
private void CopyRegion(TextureData destination, Request request) {
var data = this.GetCachedTextureData(request.Texture.Texture);
- var location = request.PackedArea.Location + new Point(request.Padding);
+ var location = request.PackedArea.Location + new Point(request.Padding, request.Padding);
for (var x = -request.Padding; x < request.Texture.Width + request.Padding; x++) {
for (var y = -request.Padding; y < request.Texture.Height + request.Padding; y++) {
Color srcColor;
@@ -264,7 +264,7 @@ namespace MLEM.Data {
srcColor = Color.Transparent;
} else {
// otherwise, we just use the closest pixel that is actually in bounds, causing the border pixels to be doubled up
- var src = new Point(MathHelper.Clamp(x, 0, request.Texture.Width - 1), MathHelper.Clamp(y, 0, request.Texture.Height - 1));
+ var src = new Point((int) MathHelper.Clamp(x, 0, request.Texture.Width - 1), (int) MathHelper.Clamp(y, 0, request.Texture.Height - 1));
srcColor = data[request.Texture.Position + src];
}
destination[location + new Point(x, y)] = srcColor;
diff --git a/MLEM.Extended/MLEM.Extended.FNA.csproj b/MLEM.Extended/MLEM.Extended.FNA.csproj
new file mode 100644
index 0000000..6419392
--- /dev/null
+++ b/MLEM.Extended/MLEM.Extended.FNA.csproj
@@ -0,0 +1,42 @@
+
+
+ netstandard2.0
+ true
+ true
+ MLEM.Extended
+ $(DefineConstants);FNA
+ NU1702
+
+
+
+ Ellpeck
+ MLEM Library for Extending FNA extension that ties in with other FNA libraries
+ See the full changelog at https://mlem.ellpeck.de/CHANGELOG
+ fna ellpeck mlem utility extensions extended
+ https://mlem.ellpeck.de/
+ https://github.com/Ellpeck/MLEM
+ MIT
+ Logo.png
+ README.md
+
+
+
+
+
+
+ all
+
+
+ all
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MLEM.Extended/MLEM.Extended.csproj b/MLEM.Extended/MLEM.Extended.csproj
index 1739308..d54704a 100644
--- a/MLEM.Extended/MLEM.Extended.csproj
+++ b/MLEM.Extended/MLEM.Extended.csproj
@@ -26,7 +26,7 @@
all
-
+ all
diff --git a/MLEM.FNA.sln b/MLEM.FNA.sln
new file mode 100644
index 0000000..ce9c1b9
--- /dev/null
+++ b/MLEM.FNA.sln
@@ -0,0 +1,76 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLEM.FNA", "MLEM\MLEM.FNA.csproj", "{C2C88AE6-6274-4395-8B03-52AE898BA070}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLEM.Ui.FNA", "MLEM.Ui\MLEM.Ui.FNA.csproj", "{1B47A40B-3BF6-4933-A7DB-57EADEBDFB61}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLEM.Startup.FNA", "MLEM.Startup\MLEM.Startup.FNA.csproj", "{FBE2C9B5-293D-47A7-9BA1-5A4BD1C4E816}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLEM.Data.FNA", "MLEM.Data\MLEM.Data.FNA.csproj", "{6587BC91-0640-43FB-988A-4F545B8ACFC5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demos.FNA", "Demos\Demos.FNA.csproj", "{D83D7D24-14CB-4A7C-A80B-BA4FEC66AB55}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demos.DesktopGL.FNA", "Demos.DesktopGL\Demos.DesktopGL.FNA.csproj", "{AB08FEC7-3AC3-4FDE-B632-226FAAD7F73F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests.FNA", "Tests\Tests.FNA.csproj", "{C74FC4C5-3BE0-42A7-8BA6-4A9AD438A9E2}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLEM.Extended.FNA", "MLEM.Extended\MLEM.Extended.FNA.csproj", "{A5B22930-DF4B-4A62-93ED-A6549F7B666B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FontStashSharp.FNA", "FontStashSharp\src\XNA\FontStashSharp.FNA.csproj", "{B805851C-9802-4239-AB16-AE77226771CA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNA", "FNA\FNA.csproj", "{35253CE1-C864-4CD3-8249-4D1319748E8F}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNA.Core", "FNA\FNA.Core.csproj", "{06459F72-CEAA-4B45-B2B1-708FC28D04F8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C2C88AE6-6274-4395-8B03-52AE898BA070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C2C88AE6-6274-4395-8B03-52AE898BA070}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C2C88AE6-6274-4395-8B03-52AE898BA070}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C2C88AE6-6274-4395-8B03-52AE898BA070}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1B47A40B-3BF6-4933-A7DB-57EADEBDFB61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1B47A40B-3BF6-4933-A7DB-57EADEBDFB61}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1B47A40B-3BF6-4933-A7DB-57EADEBDFB61}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1B47A40B-3BF6-4933-A7DB-57EADEBDFB61}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FBE2C9B5-293D-47A7-9BA1-5A4BD1C4E816}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FBE2C9B5-293D-47A7-9BA1-5A4BD1C4E816}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FBE2C9B5-293D-47A7-9BA1-5A4BD1C4E816}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FBE2C9B5-293D-47A7-9BA1-5A4BD1C4E816}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6587BC91-0640-43FB-988A-4F545B8ACFC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6587BC91-0640-43FB-988A-4F545B8ACFC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6587BC91-0640-43FB-988A-4F545B8ACFC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6587BC91-0640-43FB-988A-4F545B8ACFC5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D83D7D24-14CB-4A7C-A80B-BA4FEC66AB55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D83D7D24-14CB-4A7C-A80B-BA4FEC66AB55}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D83D7D24-14CB-4A7C-A80B-BA4FEC66AB55}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D83D7D24-14CB-4A7C-A80B-BA4FEC66AB55}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB08FEC7-3AC3-4FDE-B632-226FAAD7F73F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB08FEC7-3AC3-4FDE-B632-226FAAD7F73F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB08FEC7-3AC3-4FDE-B632-226FAAD7F73F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AB08FEC7-3AC3-4FDE-B632-226FAAD7F73F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C74FC4C5-3BE0-42A7-8BA6-4A9AD438A9E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C74FC4C5-3BE0-42A7-8BA6-4A9AD438A9E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C74FC4C5-3BE0-42A7-8BA6-4A9AD438A9E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C74FC4C5-3BE0-42A7-8BA6-4A9AD438A9E2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A5B22930-DF4B-4A62-93ED-A6549F7B666B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A5B22930-DF4B-4A62-93ED-A6549F7B666B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A5B22930-DF4B-4A62-93ED-A6549F7B666B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A5B22930-DF4B-4A62-93ED-A6549F7B666B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B805851C-9802-4239-AB16-AE77226771CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B805851C-9802-4239-AB16-AE77226771CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B805851C-9802-4239-AB16-AE77226771CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B805851C-9802-4239-AB16-AE77226771CA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {35253CE1-C864-4CD3-8249-4D1319748E8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {35253CE1-C864-4CD3-8249-4D1319748E8F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {35253CE1-C864-4CD3-8249-4D1319748E8F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {35253CE1-C864-4CD3-8249-4D1319748E8F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {06459F72-CEAA-4B45-B2B1-708FC28D04F8}.Debug|Any CPU.ActiveCfg = Debug|x64
+ {06459F72-CEAA-4B45-B2B1-708FC28D04F8}.Debug|Any CPU.Build.0 = Debug|x64
+ {06459F72-CEAA-4B45-B2B1-708FC28D04F8}.Release|Any CPU.ActiveCfg = Release|x64
+ {06459F72-CEAA-4B45-B2B1-708FC28D04F8}.Release|Any CPU.Build.0 = Release|x64
+ EndGlobalSection
+EndGlobal
diff --git a/MLEM.Startup/MLEM.Startup.FNA.csproj b/MLEM.Startup/MLEM.Startup.FNA.csproj
new file mode 100644
index 0000000..57e5474
--- /dev/null
+++ b/MLEM.Startup/MLEM.Startup.FNA.csproj
@@ -0,0 +1,37 @@
+
+
+
+ netstandard2.0
+ true
+ true
+ MLEM.Startup
+ $(DefineConstants);FNA
+
+
+
+ Ellpeck
+ MLEM Library for Extending FNA combined with some other useful libraries into a quick Game startup class
+ See the full changelog at https://mlem.ellpeck.de/CHANGELOG
+ fna ellpeck mlem utility extensions
+ https://mlem.ellpeck.de/
+ https://github.com/Ellpeck/MLEM
+ MIT
+ Logo.png
+ README.md
+
+
+
+
+
+
+
+
+ all
+
+
+
+
+
+
+
+
diff --git a/MLEM.Startup/MlemGame.cs b/MLEM.Startup/MlemGame.cs
index 36a820f..2d7445d 100644
--- a/MLEM.Startup/MlemGame.cs
+++ b/MLEM.Startup/MlemGame.cs
@@ -69,7 +69,9 @@ namespace MLEM.Startup {
this.GraphicsDeviceManager = new GraphicsDeviceManager(this) {
PreferredBackBufferWidth = windowWidth,
PreferredBackBufferHeight = windowHeight,
+ #if !FNA
HardwareModeSwitch = false
+ #endif
};
this.Window.AllowUserResizing = true;
this.Content.RootDirectory = "Content";
diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs
index 2e9efd0..c0ef4a7 100644
--- a/MLEM.Ui/Elements/Element.cs
+++ b/MLEM.Ui/Elements/Element.cs
@@ -70,7 +70,7 @@ namespace MLEM.Ui.Elements {
///
/// The size of this element, where X represents the width and Y represents the height.
/// If the x or y value of the size is between 0 and 1, the size will be seen as a percentage of its parent's size rather than as an absolute value.
- /// If the x (or y) value of the size is negative, the width (or height) is seen as a percentage of the element's resulting height (or width).
+ /// If the x (or y) value of the size is negative, the width (or height) is seen as a percentage of the element's resulting height (or width).
///
///
/// The following example combines both types of percentage-based sizing.
@@ -178,12 +178,12 @@ namespace MLEM.Ui.Elements {
///
/// This element's transform matrix.
/// Can easily be scaled using .
- /// Note that, when this is non-null, a new call is used for this element.
+ /// Note that, when this is non-null, a new SpriteBatch.Begin call is used for this element.
///
public Matrix Transform = Matrix.Identity;
///
/// The call that this element should make to to begin drawing.
- /// Note that, when this is non-null, a new call is used for this element.
+ /// Note that, when this is non-null, a new SpriteBatch.Begin call is used for this element.
///
#pragma warning disable CS0618
[Obsolete("BeginImpl is deprecated. You can create a custom element class and override Draw instead.")]
@@ -927,7 +927,7 @@ namespace MLEM.Ui.Elements {
///
/// Draws this element by calling internally.
- /// If or is set, a new call is also started.
+ /// If or is set, a new SpriteBatch.Begin call is also started.
///
/// The game's time
/// The sprite batch to use for drawing
@@ -944,7 +944,7 @@ namespace MLEM.Ui.Elements {
///
/// Draws this element by calling internally.
- /// If or is set, a new call is also started.
+ /// If or is set, a new SpriteBatch.Begin call is also started.
///
/// The game's time
/// The sprite batch to use for drawing
@@ -981,7 +981,7 @@ namespace MLEM.Ui.Elements {
///
/// Draws this element and all of its children. Override this method to draw the content of custom elements.
- /// Note that, when this is called, has already been called with custom etc. applied.
+ /// Note that, when this is called, SpriteBatch.Begin has already been called with custom etc. applied.
///
/// The game's time
/// The sprite batch to use for drawing
@@ -998,7 +998,7 @@ namespace MLEM.Ui.Elements {
///
/// Draws this element and all of its children. Override this method to draw the content of custom elements.
- /// Note that, when this is called, has already been called with custom etc. applied.
+ /// Note that, when this is called, SpriteBatch.Begin has already been called with custom etc. applied.
///
/// The game's time
/// The sprite batch to use for drawing
@@ -1021,7 +1021,7 @@ namespace MLEM.Ui.Elements {
///
/// Draws this element and all of its early.
/// Drawing early involves drawing onto instances rather than onto the screen.
- /// Note that, when this is called, has not yet been called.
+ /// Note that, when this is called, SpriteBatch.Begin has not yet been called.
///
/// The game's time
/// The sprite batch to use for drawing
diff --git a/MLEM.Ui/Elements/Image.cs b/MLEM.Ui/Elements/Image.cs
index 67d5484..79ad69e 100644
--- a/MLEM.Ui/Elements/Image.cs
+++ b/MLEM.Ui/Elements/Image.cs
@@ -1,6 +1,7 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
+using MLEM.Extensions;
using MLEM.Graphics;
using MLEM.Misc;
using MLEM.Textures;
diff --git a/MLEM.Ui/Elements/Paragraph.cs b/MLEM.Ui/Elements/Paragraph.cs
index 86c9def..2e81a5d 100644
--- a/MLEM.Ui/Elements/Paragraph.cs
+++ b/MLEM.Ui/Elements/Paragraph.cs
@@ -135,8 +135,8 @@ namespace MLEM.Ui.Elements {
protected override Vector2 CalcActualSize(RectangleF parentArea) {
var size = base.CalcActualSize(parentArea);
this.ParseText(size);
- var (w, h) = this.TokenizedText.Measure(this.RegularFont) * this.TextScale * this.TextScaleMultiplier * this.Scale;
- return new Vector2(this.AutoAdjustWidth ? w + this.ScaledPadding.Width : size.X, h + this.ScaledPadding.Height);
+ var textSize = this.TokenizedText.Measure(this.RegularFont) * this.TextScale * this.TextScaleMultiplier * this.Scale;
+ return new Vector2(this.AutoAdjustWidth ? textSize.X + this.ScaledPadding.Width : size.X, textSize.Y + this.ScaledPadding.Height);
}
///
diff --git a/MLEM.Ui/Elements/ScrollBar.cs b/MLEM.Ui/Elements/ScrollBar.cs
index 4af3790..e421def 100644
--- a/MLEM.Ui/Elements/ScrollBar.cs
+++ b/MLEM.Ui/Elements/ScrollBar.cs
@@ -3,6 +3,7 @@ using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input.Touch;
+using MLEM.Extensions;
using MLEM.Graphics;
using MLEM.Input;
using MLEM.Misc;
@@ -195,13 +196,13 @@ namespace MLEM.Ui.Elements {
}
private void ScrollToPos(Vector2 position) {
- var (width, height) = this.ScrollerSize * this.Scale;
+ var size = this.ScrollerSize * this.Scale;
if (this.Horizontal) {
- var offset = this.scrollStartOffset.X >= 0 && this.scrollStartOffset.X <= width ? this.scrollStartOffset.X : width / 2;
- this.CurrentValue = (position.X - this.Area.X - offset) / (this.Area.Width - width) * this.MaxValue;
+ var offset = this.scrollStartOffset.X >= 0 && this.scrollStartOffset.X <= size.X ? this.scrollStartOffset.X : size.X / 2;
+ this.CurrentValue = (position.X - this.Area.X - offset) / (this.Area.Width - size.X) * this.MaxValue;
} else {
- var offset = this.scrollStartOffset.Y >= 0 && this.scrollStartOffset.Y <= height ? this.scrollStartOffset.Y : height / 2;
- this.CurrentValue = (position.Y - this.Area.Y - offset) / (this.Area.Height - height) * this.MaxValue;
+ var offset = this.scrollStartOffset.Y >= 0 && this.scrollStartOffset.Y <= size.Y ? this.scrollStartOffset.Y : size.Y / 2;
+ this.CurrentValue = (position.Y - this.Area.Y - offset) / (this.Area.Height - size.Y) * this.MaxValue;
}
}
diff --git a/MLEM.Ui/Elements/TextField.cs b/MLEM.Ui/Elements/TextField.cs
index d319b97..8b97a98 100644
--- a/MLEM.Ui/Elements/TextField.cs
+++ b/MLEM.Ui/Elements/TextField.cs
@@ -1,3 +1,4 @@
+using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MLEM.Font;
diff --git a/MLEM.Ui/Elements/Tooltip.cs b/MLEM.Ui/Elements/Tooltip.cs
index 91670af..18b1f6e 100644
--- a/MLEM.Ui/Elements/Tooltip.cs
+++ b/MLEM.Ui/Elements/Tooltip.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
+using MLEM.Extensions;
using MLEM.Input;
using MLEM.Ui.Style;
diff --git a/MLEM.Ui/MLEM.Ui.FNA.csproj b/MLEM.Ui/MLEM.Ui.FNA.csproj
new file mode 100644
index 0000000..23f0414
--- /dev/null
+++ b/MLEM.Ui/MLEM.Ui.FNA.csproj
@@ -0,0 +1,35 @@
+
+
+ netstandard2.0
+ true
+ true
+ MLEM.Ui
+ $(DefineConstants);FNA
+
+
+
+ Ellpeck
+ A mouse, keyboard, gamepad and touch ready Ui system for FNA that features automatic anchoring, sizing and several ready-to-use element types
+ See the full changelog at https://mlem.ellpeck.de/CHANGELOG
+ fna ellpeck mlem ui user interface graphical gui system mouse keyboard gamepad touch
+ https://mlem.ellpeck.de/
+ https://github.com/Ellpeck/MLEM
+ MIT
+ Logo.png
+ README.md
+
+
+
+
+
+
+
+ all
+
+
+
+
+
+
+
+
diff --git a/MLEM.Ui/MLEM.Ui.csproj b/MLEM.Ui/MLEM.Ui.csproj
index 49b3d35..e9aecaa 100644
--- a/MLEM.Ui/MLEM.Ui.csproj
+++ b/MLEM.Ui/MLEM.Ui.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/MLEM.Ui/Parsers/UiMarkdownParser.cs b/MLEM.Ui/Parsers/UiMarkdownParser.cs
index 69ee617..449ba95 100644
--- a/MLEM.Ui/Parsers/UiMarkdownParser.cs
+++ b/MLEM.Ui/Parsers/UiMarkdownParser.cs
@@ -170,8 +170,13 @@ namespace MLEM.Ui.Parsers {
Texture2D tex;
if (loc.StartsWith("http")) {
using (var client = new HttpClient()) {
- using (var src = await client.GetStreamAsync(loc))
- tex = Texture2D.FromStream(this.GraphicsDevice, src);
+ using (var src = await client.GetStreamAsync(loc)) {
+ using (var memory = new MemoryStream()) {
+ // download the full stream before passing it to texture
+ await src.CopyToAsync(memory);
+ tex = Texture2D.FromStream(this.GraphicsDevice, memory);
+ }
+ }
}
} else {
using (var stream = Path.IsPathRooted(loc) ? File.OpenRead(loc) : TitleContainer.OpenStream(loc))
diff --git a/MLEM.Ui/UiControls.cs b/MLEM.Ui/UiControls.cs
index 6827ce5..a279e5e 100644
--- a/MLEM.Ui/UiControls.cs
+++ b/MLEM.Ui/UiControls.cs
@@ -159,7 +159,7 @@ namespace MLEM.Ui {
// MOUSE INPUT
if (this.HandleMouse) {
- var mousedNow = this.GetElementUnderPos(this.Input.ViewportMousePosition.ToVector2());
+ var mousedNow = this.GetElementUnderPos(new Vector2(this.Input.ViewportMousePosition.X, this.Input.ViewportMousePosition.Y));
this.SetMousedElement(mousedNow);
if (this.Input.IsMouseButtonPressedAvailable(MouseButton.Left)) {
@@ -414,8 +414,8 @@ namespace MLEM.Ui {
foreach (var child in children) {
if (child == this.SelectedElement)
continue;
- var (xOffset, yOffset) = child.Area.Center - this.SelectedElement.Area.Center;
- var angle = Math.Abs(MathHelper.WrapAngle(direction.Angle() - (float) Math.Atan2(yOffset, xOffset)));
+ var offset = child.Area.Center - this.SelectedElement.Area.Center;
+ var angle = Math.Abs(MathHelper.WrapAngle(direction.Angle() - (float) Math.Atan2(offset.Y, offset.X)));
if (angle >= MathHelper.PiOver2 - Element.Epsilon)
continue;
var distSq = child.Area.DistanceSquared(this.SelectedElement.Area);
diff --git a/MLEM.Ui/UiMetrics.cs b/MLEM.Ui/UiMetrics.cs
index d06b1f3..81901e0 100644
--- a/MLEM.Ui/UiMetrics.cs
+++ b/MLEM.Ui/UiMetrics.cs
@@ -5,7 +5,6 @@ using MLEM.Ui.Elements;
namespace MLEM.Ui {
///
/// A snapshot of update and rendering statistics from to be used for runtime debugging and profiling.
- /// This metrics struct works similarly to .
///
public struct UiMetrics {
diff --git a/MLEM.Ui/UiSystem.cs b/MLEM.Ui/UiSystem.cs
index bc5b2d3..f25ce22 100644
--- a/MLEM.Ui/UiSystem.cs
+++ b/MLEM.Ui/UiSystem.cs
@@ -88,7 +88,7 @@ namespace MLEM.Ui {
public SamplerState SamplerState;
///
/// The depth stencil state that this ui system and all of its elements draw with.
- /// The default is , which is also the default for .
+ /// The default is , which is also the default for SpriteBatch.Begin.
///
[Obsolete("Set this through SpriteBatchContext instead")]
public DepthStencilState DepthStencilState;
@@ -241,10 +241,10 @@ namespace MLEM.Ui {
MlemPlatform.Current?.AddTextInputListener(game.Window, (sender, key, character) => this.ApplyToAll(e => e.OnTextInput?.Invoke(e, key, character)));
if (automaticViewport) {
- this.Viewport = new Rectangle(Point.Zero, game.Window.ClientBounds.Size);
- this.AutoScaleReferenceSize = this.Viewport.Size;
+ this.Viewport = new Rectangle(0, 0, game.Window.ClientBounds.Width, game.Window.ClientBounds.Height);
+ this.AutoScaleReferenceSize = new Point(this.Viewport.X, this.Viewport.Y);
game.Window.ClientSizeChanged += (sender, args) => {
- this.Viewport = new Rectangle(Point.Zero, game.Window.ClientBounds.Size);
+ this.Viewport = new Rectangle(0, 0, game.Window.ClientBounds.Width, game.Window.ClientBounds.Height);
};
}
@@ -570,11 +570,11 @@ namespace MLEM.Ui {
///
public event Element.GenericCallback OnElementRemoved;
///
- /// Event that is invoked when this gets added to a in
+ /// Event that is invoked when this gets added to a in
///
public event Action OnAddedToUi;
///
- /// Event that is invoked when this gets removed from a in
+ /// Event that is invoked when this gets removed from a in
///
public event Action OnRemovedFromUi;
diff --git a/MLEM/Cameras/Camera.cs b/MLEM/Cameras/Camera.cs
index d8f7e0e..ee7288a 100644
--- a/MLEM/Cameras/Camera.cs
+++ b/MLEM/Cameras/Camera.cs
@@ -58,7 +58,7 @@ namespace MLEM.Cameras {
}
///
/// The matrix that this camera "sees", based on its position and scale.
- /// Use this in your calls to render based on the camera's viewport.
+ /// Use this in your SpriteBatch.Begin calls to render based on the camera's viewport.
///
public Matrix ViewMatrix {
get {
@@ -105,7 +105,7 @@ namespace MLEM.Cameras {
/// Whether the camera's should be rounded to full integers when calculating the
public Camera(GraphicsDevice graphicsDevice, bool roundPosition = true) {
this.graphicsDevice = graphicsDevice;
- this.AutoScaleReferenceSize = this.Viewport.Size;
+ this.AutoScaleReferenceSize = new Point(this.Viewport.Width, this.Viewport.Height);
this.RoundPosition = roundPosition;
}
@@ -173,7 +173,7 @@ namespace MLEM.Cameras {
/// The amount to zoom in or out by
/// The position that should be regarded as the zoom's center, in screen space. The default value is the center.
public void Zoom(float delta, Vector2? zoomCenter = null) {
- var center = (zoomCenter ?? this.Viewport.Size.ToVector2() / 2) / this.ActualScale;
+ var center = (zoomCenter ?? new Vector2(this.Viewport.Width, this.Viewport.Height) / 2) / this.ActualScale;
var lastScale = this.Scale;
this.Scale += delta;
this.Position += center * ((this.Scale - lastScale) / this.Scale);
diff --git a/MLEM/Extensions/GraphicsExtensions.cs b/MLEM/Extensions/GraphicsExtensions.cs
index d6657a6..85aeac3 100644
--- a/MLEM/Extensions/GraphicsExtensions.cs
+++ b/MLEM/Extensions/GraphicsExtensions.cs
@@ -57,7 +57,7 @@ namespace MLEM.Extensions {
/// The graphics device manager
/// The window whose bounds to use
public static void ResetWidthAndHeight(this GraphicsDeviceManager manager, GameWindow window) {
- var (_, _, width, height) = window.ClientBounds;
+ var (width, height) = (window.ClientBounds.Width, window.ClientBounds.Height);
manager.PreferredBackBufferWidth = Math.Max(height, width);
manager.PreferredBackBufferHeight = Math.Min(height, width);
manager.ApplyChanges();
@@ -90,7 +90,12 @@ namespace MLEM.Extensions {
/// The target to apply
public TargetContext(GraphicsDevice device, RenderTarget2D target) {
this.device = device;
+ #if FNA
+ // RenderTargetCount doesn't exist in FNA but we still want the optimization in MG
+ this.lastTargets = device.GetRenderTargets();
+ #else
this.lastTargets = device.RenderTargetCount <= 0 ? null : device.GetRenderTargets();
+ #endif
device.SetRenderTarget(target);
}
diff --git a/MLEM/Extensions/NumberExtensions.cs b/MLEM/Extensions/NumberExtensions.cs
index 61b12a9..3900c06 100644
--- a/MLEM/Extensions/NumberExtensions.cs
+++ b/MLEM/Extensions/NumberExtensions.cs
@@ -223,13 +223,13 @@ namespace MLEM.Extensions {
/// The matrix
/// The rotation of the matrix
public static Quaternion Rotation(this Matrix matrix) {
- var (scX, scY, scZ) = matrix.Scale();
- if (scX == 0 || scY == 0 || scZ == 0)
+ var sc = matrix.Scale();
+ if (sc.X == 0 || sc.Y == 0 || sc.Z == 0)
return Quaternion.Identity;
return Quaternion.CreateFromRotationMatrix(new Matrix(
- matrix.M11 / scX, matrix.M12 / scX, matrix.M13 / scX, 0,
- matrix.M21 / scY, matrix.M22 / scY, matrix.M23 / scY, 0,
- matrix.M31 / scZ, matrix.M32 / scZ, matrix.M33 / scZ, 0,
+ matrix.M11 / sc.X, matrix.M12 / sc.X, matrix.M13 / sc.X, 0,
+ matrix.M21 / sc.Y, matrix.M22 / sc.Y, matrix.M23 / sc.Y, 0,
+ matrix.M31 / sc.Z, matrix.M32 / sc.Z, matrix.M33 / sc.Z, 0,
0, 0, 0, 1));
}
@@ -250,7 +250,7 @@ namespace MLEM.Extensions {
/// The quaternion
/// The rotation of the quaternion
public static Vector3 RotationVector(this Quaternion quaternion) {
- var (x, y, z, w) = quaternion;
+ var (x, y, z, w) = (quaternion.X, quaternion.Y, quaternion.Z, quaternion.W);
return new Vector3(
(float) Math.Atan2(2 * (w * x + y * z), 1 - 2 * (x * x + y * y)),
(float) Math.Asin(MathHelper.Clamp(2 * (w * y - z * x), -1, 1)),
@@ -268,16 +268,16 @@ namespace MLEM.Extensions {
/// The amount that the penetration occured by, in the direction of
/// Whether or not a penetration occured
public static bool Penetrate(this RectangleF rect, RectangleF other, out Vector2 normal, out float penetration) {
- var (offsetX, offsetY) = other.Center - rect.Center;
- var overlapX = rect.Width / 2 + other.Width / 2 - Math.Abs(offsetX);
+ var offset = other.Center - rect.Center;
+ var overlapX = rect.Width / 2 + other.Width / 2 - Math.Abs(offset.X);
if (overlapX > 0) {
- var overlapY = rect.Height / 2 + other.Height / 2 - Math.Abs(offsetY);
+ var overlapY = rect.Height / 2 + other.Height / 2 - Math.Abs(offset.Y);
if (overlapY > 0) {
if (overlapX < overlapY) {
- normal = new Vector2(offsetX < 0 ? -1 : 1, 0);
+ normal = new Vector2(offset.X < 0 ? -1 : 1, 0);
penetration = overlapX;
} else {
- normal = new Vector2(0, offsetY < 0 ? -1 : 1);
+ normal = new Vector2(0, offset.Y < 0 ? -1 : 1);
penetration = overlapY;
}
return true;
@@ -288,5 +288,23 @@ namespace MLEM.Extensions {
return false;
}
+ #if FNA
+ ///
+ /// Gets a representation for this object.
+ ///
+ /// A representation for this object.
+ public static Point ToPoint(this Vector2 vector) {
+ return new Point((int) vector.X, (int) vector.Y);
+ }
+
+ ///
+ /// Gets a representation for this object.
+ ///
+ /// A representation for this object.
+ public static Vector2 ToVector2(this Point point) {
+ return new Vector2(point.X, point.Y);
+ }
+ #endif
+
}
}
diff --git a/MLEM/Font/GenericFont.cs b/MLEM/Font/GenericFont.cs
index dc8b370..28c4748 100644
--- a/MLEM/Font/GenericFont.cs
+++ b/MLEM/Font/GenericFont.cs
@@ -285,18 +285,18 @@ namespace MLEM.Font {
}
private void DrawString(SpriteBatch batch, CharSource text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effects, float layerDepth) {
- var (flipX, flipY) = Vector2.Zero;
+ var (flipX, flipY) = (0F, 0F);
var flippedV = (effects & SpriteEffects.FlipVertically) != 0;
var flippedH = (effects & SpriteEffects.FlipHorizontally) != 0;
if (flippedV || flippedH) {
- var (w, h) = this.MeasureString(text, false, null);
+ var size = this.MeasureString(text, false, null);
if (flippedH) {
origin.X *= -1;
- flipX = -w;
+ flipX = -size.X;
}
if (flippedV) {
origin.Y *= -1;
- flipY = this.LineHeight - h;
+ flipY = this.LineHeight - size.Y;
}
}
@@ -327,17 +327,17 @@ namespace MLEM.Font {
}
var cString = c.ToCachedString();
- var (cW, cH) = this.MeasureString(cString);
+ var cSize = this.MeasureString(cString);
var charPos = offset;
if (flippedH)
- charPos.X += cW;
+ charPos.X += cSize.X;
if (flippedV)
- charPos.Y += cH - this.LineHeight;
+ charPos.Y += cSize.Y - this.LineHeight;
Vector2.Transform(ref charPos, ref trans, out charPos);
this.DrawChar(batch, cString, charPos, color, rotation, scale, effects, layerDepth);
- offset.X += cW;
+ offset.X += cSize.X;
}
}
diff --git a/MLEM/Font/GenericSpriteFont.cs b/MLEM/Font/GenericSpriteFont.cs
index d350028..3250149 100644
--- a/MLEM/Font/GenericSpriteFont.cs
+++ b/MLEM/Font/GenericSpriteFont.cs
@@ -42,6 +42,10 @@ namespace MLEM.Font {
}
private static SpriteFont SetDefaults(SpriteFont font) {
+ #if FNA
+ // none of the copying is available with FNA
+ return font;
+ #else
// we copy the font here to set the default character to a space
return new SpriteFont(
font.Texture,
@@ -52,6 +56,7 @@ namespace MLEM.Font {
font.Spacing,
font.Glyphs.Select(g => new Vector3(g.LeftSideBearing, g.Width, g.RightSideBearing)).ToList(),
' ');
+ #endif
}
}
diff --git a/MLEM/Formatting/Codes/UnderlineCode.cs b/MLEM/Formatting/Codes/UnderlineCode.cs
index 9df532f..90aecf7 100644
--- a/MLEM/Formatting/Codes/UnderlineCode.cs
+++ b/MLEM/Formatting/Codes/UnderlineCode.cs
@@ -23,9 +23,9 @@ namespace MLEM.Formatting.Codes {
// don't underline spaces at the end of lines
if (c == ' ' && token.DisplayString.Length > indexInToken + 1 && token.DisplayString[indexInToken + 1] == '\n')
return false;
- var (w, h) = font.MeasureString(cString) * scale;
- var t = h * this.thickness;
- batch.Draw(batch.GetBlankTexture(), new RectangleF(pos.X, pos.Y + this.yOffset * h - t, w, t), color);
+ var size = font.MeasureString(cString) * scale;
+ var t = size.Y * this.thickness;
+ batch.Draw(batch.GetBlankTexture(), new RectangleF(pos.X, pos.Y + this.yOffset * size.Y - t, size.X, t), color);
return false;
}
diff --git a/MLEM/Graphics/AutoTiling.cs b/MLEM/Graphics/AutoTiling.cs
index 676828a..f5efc7f 100644
--- a/MLEM/Graphics/AutoTiling.cs
+++ b/MLEM/Graphics/AutoTiling.cs
@@ -62,8 +62,8 @@ namespace MLEM.Graphics {
///
/// This method allows for a tiled texture to be drawn in an auto-tiling mode.
/// This allows, for example, a grass patch on a tilemap to have nice looking edges that transfer over into a path without any hard edges between tiles.
- ///
- /// This method is a more complex version of that overlays separate border textures on a background texture region, which also allows for non-rectangular texture areas to be used easily.
+ ///
+ /// This method is a more complex version of that overlays separate border textures on a background texture region, which also allows for non-rectangular texture areas to be used easily.
/// For auto-tiling in this way to work, the overlay sections have to be laid out as follows: 16 sections aligned horizontally within the texture file, with the following information:
///
/// The texture used for straight, horizontal borders, with the borders facing away from the center, split up into four parts: top left, then top right, then bottom left, then bottom right
@@ -138,8 +138,8 @@ namespace MLEM.Graphics {
var xUr = up && right ? connectsTo(1, -1) ? 0 : 4 : right ? 1 : up ? 3 : 2;
var xDl = down && left ? connectsTo(-1, 1) ? 0 : 4 : left ? 1 : down ? 3 : 2;
var xDr = down && right ? connectsTo(1, 1) ? 0 : 4 : right ? 1 : down ? 3 : 2;
- var (w, h) = textureRegion.Size;
- var (w2, h2) = new Point(w / 2, h / 2);
+ var (w, h) = (textureRegion.Width, textureRegion.Height);
+ var (w2, h2) = (w / 2, h / 2);
return (
new Vector2(pos.X, pos.Y), new Rectangle(textureRegion.X + xUl * w, textureRegion.Y, w2, h2),
new Vector2(pos.X + w2 * scale.X, pos.Y), new Rectangle(textureRegion.X + w2 + xUr * w, textureRegion.Y, w2, h2),
@@ -156,7 +156,7 @@ namespace MLEM.Graphics {
var xUr = up && right ? connectsTo(1, -1) ? -1 : 13 : right ? 1 : up ? 9 : 5;
var xDl = down && left ? connectsTo(-1, 1) ? -1 : 14 : left ? 2 : down ? 10 : 6;
var xDr = down && right ? connectsTo(1, 1) ? -1 : 15 : right ? 3 : down ? 11 : 7;
- var (w, h) = textureRegion.Size;
+ var (w, h) = (textureRegion.Width, textureRegion.Height);
return (
xUl < 0 ? Rectangle.Empty : new Rectangle(textureRegion.X + xUl * w, textureRegion.Y, w, h),
xUr < 0 ? Rectangle.Empty : new Rectangle(textureRegion.X + xUr * w, textureRegion.Y, w, h),
diff --git a/MLEM/Graphics/SpriteBatchContext.cs b/MLEM/Graphics/SpriteBatchContext.cs
index 0e1734e..4983075 100644
--- a/MLEM/Graphics/SpriteBatchContext.cs
+++ b/MLEM/Graphics/SpriteBatchContext.cs
@@ -3,7 +3,7 @@ using Microsoft.Xna.Framework.Graphics;
namespace MLEM.Graphics {
///
- /// A sprite batch context is a set of information for a to use, which encapsulates all of the information usually passed directly to .
+ /// A sprite batch context is a set of information for a to use, which encapsulates all of the information usually passed directly to SpriteBatch.Begin.
/// To use a sprite batch context effectively, the extension methods in should be used.
///
public struct SpriteBatchContext {
@@ -17,7 +17,7 @@ namespace MLEM.Graphics {
///
public BlendState BlendState;
///
- /// State of the sampler.
+ /// State of the sampler.
///
public SamplerState SamplerState;
///
diff --git a/MLEM/Graphics/StaticSpriteBatch.cs b/MLEM/Graphics/StaticSpriteBatch.cs
index e27d00c..3bdc033 100644
--- a/MLEM/Graphics/StaticSpriteBatch.cs
+++ b/MLEM/Graphics/StaticSpriteBatch.cs
@@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
+using MLEM.Extensions;
namespace MLEM.Graphics {
///
@@ -174,18 +176,18 @@ namespace MLEM.Graphics {
for (var i = 0; i < this.FilledBuffers; i++) {
var buffer = this.vertexBuffers[i];
var texture = this.textures[i];
- var tris = Math.Min(this.items.Count * 4 - totalIndex, buffer.VertexCount) / 4 * 2;
+ var verts = Math.Min(this.items.Count * 4 - totalIndex, buffer.VertexCount);
this.graphicsDevice.SetVertexBuffer(buffer);
if (effect != null) {
foreach (var pass in effect.CurrentTechnique.Passes) {
pass.Apply();
this.graphicsDevice.Textures[0] = texture;
- this.graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, tris);
+ this.DrawPrimitives(verts);
}
} else {
this.graphicsDevice.Textures[0] = texture;
- this.graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, tris);
+ this.DrawPrimitives(verts);
}
totalIndex += buffer.VertexCount;
@@ -290,10 +292,11 @@ namespace MLEM.Graphics {
if ((effects & SpriteEffects.FlipHorizontally) != 0)
(texBr.X, texTl.X) = (texTl.X, texBr.X);
+ var destSize = new Vector2(destinationRectangle.Width, destinationRectangle.Height);
if (rotation == 0) {
- return this.Add(texture, destinationRectangle.Location.ToVector2() - origin, destinationRectangle.Size.ToVector2(), color, texTl, texBr, layerDepth);
+ return this.Add(texture, destinationRectangle.Location.ToVector2() - origin, destSize, color, texTl, texBr, layerDepth);
} else {
- return this.Add(texture, destinationRectangle.Location.ToVector2(), -origin, destinationRectangle.Size.ToVector2(), (float) Math.Sin(rotation), (float) Math.Cos(rotation), color, texTl, texBr, layerDepth);
+ return this.Add(texture, destinationRectangle.Location.ToVector2(), -origin, destSize, (float) Math.Sin(rotation), (float) Math.Cos(rotation), color, texTl, texBr, layerDepth);
}
}
@@ -439,6 +442,14 @@ namespace MLEM.Graphics {
this.textures.Insert(index, texture);
}
+ private void DrawPrimitives(int vertices) {
+ #if FNA
+ this.graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices, 0, vertices / 4 * 2);
+ #else
+ this.graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertices / 4 * 2);
+ #endif
+ }
+
///
/// A struct that represents an item added to a using Add or any of its overloads.
/// An item returned after adding can be removed using .
@@ -463,5 +474,58 @@ namespace MLEM.Graphics {
}
+ #if FNA
+ private class SpriteEffect : Effect {
+
+ private EffectParameter matrixParam;
+ private Viewport lastViewport;
+ private Matrix projection;
+
+ public Matrix? TransformMatrix { get; set; }
+
+ public SpriteEffect(GraphicsDevice device) : base(device, SpriteEffect.LoadEffectCode()) {
+ this.CacheEffectParameters();
+ }
+
+ private SpriteEffect(SpriteEffect cloneSource) : base(cloneSource) {
+ this.CacheEffectParameters();
+ }
+
+ public override Effect Clone() {
+ return new SpriteEffect(this);
+ }
+
+ private void CacheEffectParameters() {
+ this.matrixParam = this.Parameters["MatrixTransform"];
+ }
+
+ protected override void OnApply() {
+ var vp = this.GraphicsDevice.Viewport;
+ if (vp.Width != this.lastViewport.Width || vp.Height != this.lastViewport.Height) {
+ Matrix.CreateOrthographicOffCenter(0, vp.Width, vp.Height, 0, 0, -1, out this.projection);
+ this.projection.M41 += -0.5f * this.projection.M11;
+ this.projection.M42 += -0.5f * this.projection.M22;
+ this.lastViewport = vp;
+ }
+
+ if (this.TransformMatrix.HasValue) {
+ this.matrixParam.SetValue(this.TransformMatrix.GetValueOrDefault() * this.projection);
+ } else {
+ this.matrixParam.SetValue(this.projection);
+ }
+ }
+
+ private static byte[] LoadEffectCode() {
+ using (var stream = typeof(Effect).Assembly.GetManifestResourceStream("Microsoft.Xna.Framework.Graphics.Effect.Resources.SpriteEffect.fxb")) {
+ using (var memory = new MemoryStream()) {
+ stream.CopyTo(memory);
+ return memory.ToArray();
+ }
+ }
+ }
+
+ }
+ #endif
+
}
}
diff --git a/MLEM/Input/InputHandler.cs b/MLEM/Input/InputHandler.cs
index d063f34..90064a6 100644
--- a/MLEM/Input/InputHandler.cs
+++ b/MLEM/Input/InputHandler.cs
@@ -15,6 +15,12 @@ namespace MLEM.Input {
///
public class InputHandler : GameComponent {
+ #if FNA
+ private const int MaximumGamePadCount = 4;
+ #else
+ private static readonly int MaximumGamePadCount = GamePad.MaximumGamePadCount;
+ #endif
+
///
/// Contains all of the gestures that have finished during the last update call.
/// To easily query these gestures, use or .
@@ -80,11 +86,11 @@ namespace MLEM.Input {
///
/// Contains the touch state from the last update call
///
- public TouchCollection LastTouchState { get; private set; }
+ public TouchCollection LastTouchState { get; private set; } = new TouchCollection(Array.Empty());
///
/// Contains the current touch state
///
- public TouchCollection TouchState { get; private set; }
+ public TouchCollection TouchState { get; private set; } = new TouchCollection(Array.Empty());
///
/// Contains the , but with the taken into account.
///
@@ -109,7 +115,7 @@ namespace MLEM.Input {
///
/// Contains the position of the mouse from the last update call, extracted from
///
- public Point LastMousePosition => this.LastMouseState.Position;
+ public Point LastMousePosition => new Point(this.LastMouseState.X, this.LastMouseState.Y);
///
/// Contains the , but with the taken into account.
///
@@ -117,7 +123,7 @@ namespace MLEM.Input {
///
/// Contains the current position of the mouse, extracted from
///
- public Point MousePosition => this.MouseState.Position;
+ public Point MousePosition => new Point(this.MouseState.X, this.MouseState.Y);
///
/// Contains the , but with the taken into account.
///
@@ -139,11 +145,11 @@ namespace MLEM.Input {
///
public KeyboardState KeyboardState { get; private set; }
- private readonly GamePadState[] lastGamepads = new GamePadState[GamePad.MaximumGamePadCount];
- private readonly GamePadState[] gamepads = new GamePadState[GamePad.MaximumGamePadCount];
- private readonly DateTime[] lastGamepadButtonRepeats = new DateTime[GamePad.MaximumGamePadCount];
- private readonly bool[] triggerGamepadButtonRepeat = new bool[GamePad.MaximumGamePadCount];
- private readonly Buttons?[] heldGamepadButtons = new Buttons?[GamePad.MaximumGamePadCount];
+ private readonly GamePadState[] lastGamepads = new GamePadState[MaximumGamePadCount];
+ private readonly GamePadState[] gamepads = new GamePadState[MaximumGamePadCount];
+ private readonly DateTime[] lastGamepadButtonRepeats = new DateTime[MaximumGamePadCount];
+ private readonly bool[] triggerGamepadButtonRepeat = new bool[MaximumGamePadCount];
+ private readonly Buttons?[] heldGamepadButtons = new Buttons?[MaximumGamePadCount];
private readonly List gestures = new List();
private readonly HashSet<(GenericInput, int)> consumedPresses = new HashSet<(GenericInput, int)>();
@@ -209,7 +215,7 @@ namespace MLEM.Input {
if (this.HandleMouse) {
this.LastMouseState = this.MouseState;
var state = Mouse.GetState();
- if (active && this.Game.GraphicsDevice.Viewport.Bounds.Contains(state.Position)) {
+ if (active && this.Game.GraphicsDevice.Viewport.Bounds.Contains(state.X, state.Y)) {
this.MouseState = state;
foreach (var button in MouseExtensions.MouseButtons) {
if (state.GetState(button) == ButtonState.Pressed)
@@ -217,18 +223,22 @@ namespace MLEM.Input {
}
} else {
// mouse position and scroll wheel value should be preserved when the mouse is out of bounds
+ #if FNA
+ this.MouseState = new MouseState(state.X, state.Y, state.ScrollWheelValue, 0, 0, 0, 0, 0);
+ #else
this.MouseState = new MouseState(state.X, state.Y, state.ScrollWheelValue, 0, 0, 0, 0, 0, state.HorizontalScrollWheelValue);
+ #endif
}
}
if (this.HandleGamepads) {
- this.ConnectedGamepads = GamePad.MaximumGamePadCount;
- for (var i = 0; i < GamePad.MaximumGamePadCount; i++) {
+ this.ConnectedGamepads = MaximumGamePadCount;
+ for (var i = 0; i < MaximumGamePadCount; i++) {
this.lastGamepads[i] = this.gamepads[i];
- this.gamepads[i] = GamePadState.Default;
- if (GamePad.GetCapabilities(i).IsConnected) {
+ this.gamepads[i] = default;
+ if (GamePad.GetCapabilities((PlayerIndex) i).IsConnected) {
if (active) {
- this.gamepads[i] = GamePad.GetState(i);
+ this.gamepads[i] = GamePad.GetState((PlayerIndex) i);
foreach (var button in EnumHelper.Buttons) {
if (this.IsGamepadButtonDown(button, i))
this.AccumulateDown(button, i);
@@ -263,12 +273,13 @@ namespace MLEM.Input {
this.LastTouchState = this.TouchState;
this.LastViewportTouchState = this.ViewportTouchState;
- this.TouchState = active ? TouchPanel.GetState() : default;
+ this.TouchState = active ? TouchPanel.GetState() : new TouchCollection(Array.Empty());
if (this.TouchState.Count > 0 && this.ViewportOffset != Point.Zero) {
this.ViewportTouchState = new List();
foreach (var touch in this.TouchState) {
touch.TryGetPreviousLocation(out var previous);
- this.ViewportTouchState.Add(new TouchLocation(touch.Id, touch.State, touch.Position + this.ViewportOffset.ToVector2(), previous.State, previous.Position + this.ViewportOffset.ToVector2()));
+ var offset = new Vector2(this.ViewportOffset.X, this.ViewportOffset.Y);
+ this.ViewportTouchState.Add(new TouchLocation(touch.Id, touch.State, touch.Position + offset, previous.State, previous.Position + offset));
}
} else {
this.ViewportTouchState = this.TouchState;
@@ -548,7 +559,7 @@ namespace MLEM.Input {
///
/// Returns whether the given key is considered pressed.
/// A gamepad button is considered pressed if it was down the last update call, and is up the current update call. If is true, this behavior is inverted.
- /// This has the same behavior as , but ignores gamepad repeat events.
+ /// This has the same behavior as , but ignores gamepad repeat events.
/// If is false, this method does the same as .
///
/// The button to query
@@ -613,7 +624,8 @@ namespace MLEM.Input {
/// True if a gesture of the type was found, otherwise false
public bool GetViewportGesture(GestureType type, out GestureSample sample) {
if (this.GetGesture(type, out var original)) {
- sample = new GestureSample(original.GestureType, original.Timestamp, original.Position + this.ViewportOffset.ToVector2(), original.Position2 + this.ViewportOffset.ToVector2(), original.Delta, original.Delta2);
+ var offset = new Vector2(this.ViewportOffset.X, this.ViewportOffset.Y);
+ sample = new GestureSample(original.GestureType, original.Timestamp, original.Position + offset, original.Position2 + offset, original.Delta, original.Delta2);
return true;
}
sample = default;
diff --git a/MLEM/Input/TextInput.cs b/MLEM/Input/TextInput.cs
index 331b519..c574247 100644
--- a/MLEM/Input/TextInput.cs
+++ b/MLEM/Input/TextInput.cs
@@ -91,7 +91,7 @@ namespace MLEM.Input {
public int CaretPos {
get => this.caretPos;
set {
- var val = MathHelper.Clamp(value, 0, this.text.Length);
+ var val = (int) MathHelper.Clamp(value, 0F, this.text.Length);
if (this.caretPos != val) {
this.caretPos = val;
this.caretBlinkTimer = 0;
@@ -226,12 +226,14 @@ namespace MLEM.Input {
///
/// A method that should be called when the given text should be entered into this text input.
- /// This method is designed to be used with the event.
+ /// This method is designed to be used with or the TextInput event provided by MonoGame and FNA.
///
/// The key that was pressed.
/// The character that the represents.
/// Whether text was successfully input.
public bool OnTextInput(Keys key, char character) {
+ // FNA's text input event doesn't supply keys, so we handle this in Update
+ #if !FNA
if (key == Keys.Back) {
if (this.CaretPos > 0) {
this.CaretPos--;
@@ -246,6 +248,9 @@ namespace MLEM.Input {
return this.InsertText(character);
}
return false;
+ #else
+ return this.InsertText(character);
+ #endif
}
///
@@ -254,26 +259,37 @@ namespace MLEM.Input {
/// The current game time.
/// The input handler to use for input querying.
public void Update(GameTime time, InputHandler input) {
+ // FNA's text input event doesn't supply keys, so we handle this here
+ #if FNA
+ if (this.CaretPos > 0 && input.TryConsumePressed(Keys.Back)) {
+ this.CaretPos--;
+ this.RemoveText(this.CaretPos, 1);
+ } else if (this.CaretPos < this.text.Length && input.TryConsumePressed(Keys.Delete)) {
+ this.RemoveText(this.CaretPos, 1);
+ } else if (this.Multiline && input.TryConsumePressed(Keys.Enter)) {
+ this.InsertText('\n');
+ } else
+ #endif
if (this.CaretPos > 0 && input.TryConsumePressed(Keys.Left)) {
this.CaretPos--;
} else if (this.CaretPos < this.text.Length && input.TryConsumePressed(Keys.Right)) {
this.CaretPos++;
} else if (this.Multiline && input.IsKeyPressedAvailable(Keys.Up) && this.MoveCaretToLine(this.CaretLine - 1)) {
- input.TryConsumeKeyPressed(Keys.Up);
+ input.TryConsumePressed(Keys.Up);
} else if (this.Multiline && input.IsKeyPressedAvailable(Keys.Down) && this.MoveCaretToLine(this.CaretLine + 1)) {
- input.TryConsumeKeyPressed(Keys.Down);
- } else if (this.CaretPos != 0 && input.TryConsumeKeyPressed(Keys.Home)) {
+ input.TryConsumePressed(Keys.Down);
+ } else if (this.CaretPos != 0 && input.TryConsumePressed(Keys.Home)) {
this.CaretPos = 0;
- } else if (this.CaretPos != this.text.Length && input.TryConsumeKeyPressed(Keys.End)) {
+ } else if (this.CaretPos != this.text.Length && input.TryConsumePressed(Keys.End)) {
this.CaretPos = this.text.Length;
} else if (input.IsModifierKeyDown(ModifierKey.Control)) {
if (input.IsKeyPressedAvailable(Keys.V)) {
var clip = this.PasteFromClipboardFunction?.Invoke();
if (clip != null) {
this.InsertText(clip, true);
- input.TryConsumeKeyPressed(Keys.V);
+ input.TryConsumePressed(Keys.V);
}
- } else if (input.TryConsumeKeyPressed(Keys.C)) {
+ } else if (input.TryConsumePressed(Keys.C)) {
// until there is text selection, just copy the whole content
this.CopyToClipboardFunction?.Invoke(this.Text);
}
diff --git a/MLEM/MLEM.FNA.csproj b/MLEM/MLEM.FNA.csproj
new file mode 100644
index 0000000..fe14dd5
--- /dev/null
+++ b/MLEM/MLEM.FNA.csproj
@@ -0,0 +1,32 @@
+
+
+ netstandard2.0
+ true
+ true
+ MLEM
+ $(DefineConstants);FNA
+
+
+
+ Ellpeck
+ MLEM Library for Extending FNA provides extension methods and additional features for FNA
+ See the full changelog at https://mlem.ellpeck.de/CHANGELOG
+ fna ellpeck mlem utility extensions
+ https://mlem.ellpeck.de/
+ https://github.com/Ellpeck/MLEM
+ MIT
+ Logo.png
+ README.md
+
+
+
+
+ all
+
+
+
+
+
+
+
+
diff --git a/MLEM/Misc/Direction2.cs b/MLEM/Misc/Direction2.cs
index f5f6aa6..443bbb6 100644
--- a/MLEM/Misc/Direction2.cs
+++ b/MLEM/Misc/Direction2.cs
@@ -182,8 +182,8 @@ namespace MLEM.Misc {
/// The direction whose angle to get
/// The direction's angle
public static float Angle(this Direction2 dir) {
- var (x, y) = dir.Offset();
- return (float) Math.Atan2(y, x);
+ var off = dir.Offset();
+ return (float) Math.Atan2(off.Y, off.X);
}
///
diff --git a/MLEM/Misc/MlemPlatform.cs b/MLEM/Misc/MlemPlatform.cs
index f63de32..eacbb07 100644
--- a/MLEM/Misc/MlemPlatform.cs
+++ b/MLEM/Misc/MlemPlatform.cs
@@ -57,9 +57,9 @@ namespace MLEM.Misc {
///
/// A delegate method that can be used for
///
- /// The object that sent the event. The used in most cases.
- /// The key that was pressed
- /// The character that corresponds to that key
+ /// The object that sent the event. The or used in most cases.
+ /// The key that was pressed. Note that this is always on FNA.
+ /// The character that corresponds to that key.
public delegate void TextInputCallback(object sender, Keys key, char character);
///
@@ -78,10 +78,10 @@ namespace MLEM.Misc {
private readonly Action> addListener;
///
- /// Creates a new DesktopGL-based platform
+ /// Creates a new DesktopGL-based platform.
/// See class documentation for more detailed information.
///
- /// The function that is used to add a text input listener
+ /// The function that is used to add a text input listener.
public DesktopGl(Action> addListener) {
this.addListener = addListener;
}
@@ -109,6 +109,44 @@ namespace MLEM.Misc {
}
+ ///
+ /// The MLEM Desktop platform for FNA.
+ /// This platform uses the built-in FNA TextInputEXT event, which makes this listener work with any keyboard localization natively.
+ /// This platform is initialized as follows:
+ ///
+ /// MlemPlatform.Current = new MlemPlatform.DesktopFna(a => TextInputEXT.TextInput += a);
+ ///
+ ///
+ public class DesktopFna : MlemPlatform {
+
+ private readonly Action> addListener;
+
+ ///
+ /// Creates a new Desktop for FNA platform.
+ /// See class documentation for more detailed information.
+ ///
+ /// The function that is used to add a text input listener.
+ public DesktopFna(Action> addListener) {
+ this.addListener = addListener;
+ }
+
+ ///
+ public override Task OpenOnScreenKeyboard(string title, string description, string defaultText, bool usePasswordMode) {
+ return Task.FromResult(null);
+ }
+
+ ///
+ public override void AddTextInputListener(GameWindow window, TextInputCallback callback) {
+ this.addListener(c => callback(this, Keys.None, c));
+ }
+
+ ///
+ public override void OpenLinkOrFile(string link) {
+ Process.Start(new ProcessStartInfo(link) {UseShellExecute = true});
+ }
+
+ }
+
///
/// The MLEM platform for mobile platforms as well as consoles.
/// This platform opens an on-screen keyboard using the KeyboardInput class on mobile devices.
diff --git a/MLEM/Misc/RectangleF.cs b/MLEM/Misc/RectangleF.cs
index 6a3145b..8473f3a 100644
--- a/MLEM/Misc/RectangleF.cs
+++ b/MLEM/Misc/RectangleF.cs
@@ -105,12 +105,12 @@ namespace MLEM.Misc {
this.Height = size.Y;
}
- ///
+ ///
public bool Contains(float x, float y) {
return this.X <= x && x < this.X + this.Width && this.Y <= y && y < this.Y + this.Height;
}
- ///
+ ///
public bool Contains(Vector2 value) {
return this.Contains(value.X, value.Y);
}
@@ -140,7 +140,7 @@ namespace MLEM.Misc {
return (((17 * 23 + this.X.GetHashCode()) * 23 + this.Y.GetHashCode()) * 23 + this.Width.GetHashCode()) * 23 + this.Height.GetHashCode();
}
- ///
+ ///
public void Inflate(float horizontalAmount, float verticalAmount) {
this.X -= horizontalAmount;
this.Y -= verticalAmount;
@@ -153,13 +153,13 @@ namespace MLEM.Misc {
return value.Left < this.Right && this.Left < value.Right && value.Top < this.Bottom && this.Top < value.Bottom;
}
- ///
+ ///
public void Offset(float offsetX, float offsetY) {
this.X += offsetX;
this.Y += offsetY;
}
- ///
+ ///
public void Offset(Vector2 amount) {
this.X += amount.X;
this.Y += amount.Y;
@@ -173,7 +173,7 @@ namespace MLEM.Misc {
/// The squared distance between the two rectangles.
public float DistanceSquared(RectangleF value) {
// we calculate the distance based on the quadrants that the other rectangle is in using 8 cases:
- // 1 7 4
+ // 1 7 4
// 3 T 6
// 2 8 5
var valueIsAbove = value.Bottom < this.Top;
@@ -215,7 +215,13 @@ namespace MLEM.Misc {
return "{X:" + this.X + " Y:" + this.Y + " Width:" + this.Width + " Height:" + this.Height + "}";
}
- ///
+ ///
+ /// Deconstruction method for .
+ ///
+ ///
+ ///
+ ///
+ ///
public void Deconstruct(out float x, out float y, out float width, out float height) {
x = this.X;
y = this.Y;
diff --git a/MLEM/Textures/NinePatch.cs b/MLEM/Textures/NinePatch.cs
index 30078e7..4de6384 100644
--- a/MLEM/Textures/NinePatch.cs
+++ b/MLEM/Textures/NinePatch.cs
@@ -158,7 +158,8 @@ namespace MLEM.Textures {
for (var x = 0F; x < rect.Width; x += width) {
for (var y = 0F; y < rect.Height; y += height) {
var size = new Vector2(Math.Min(rect.Width - x, width), Math.Min(rect.Height - y, height));
- batch.Draw(texture.Region.Texture, new RectangleF(rect.Location + new Vector2(x, y), size), new Rectangle(src.Location, (size / patchScale).CeilCopy().ToPoint()), color, rotation, origin, effects, layerDepth);
+ var srcSize = (size / patchScale).CeilCopy().ToPoint();
+ batch.Draw(texture.Region.Texture, new RectangleF(rect.Location + new Vector2(x, y), size), new Rectangle(src.X, src.Y, srcSize.X, srcSize.Y), color, rotation, origin, effects, layerDepth);
}
}
break;
diff --git a/MLEM/Textures/TextureRegion.cs b/MLEM/Textures/TextureRegion.cs
index 6ed56d9..dc117bb 100644
--- a/MLEM/Textures/TextureRegion.cs
+++ b/MLEM/Textures/TextureRegion.cs
@@ -33,7 +33,7 @@ namespace MLEM.Textures {
///
/// The size of this texture region
///
- public Point Size => this.Area.Size;
+ public Point Size => new Point(this.Area.Width, this.Area.Height);
///
/// The width of this texture region
///
@@ -51,8 +51,8 @@ namespace MLEM.Textures {
/// The of this texture region, but in absolute pixels rather than percentage.
///
public Vector2 PivotPixels {
- get => this.Pivot * this.Size.ToVector2();
- set => this.Pivot = value / this.Size.ToVector2();
+ get => this.Pivot * new Vector2(this.Size.X, this.Size.Y);
+ set => this.Pivot = value / new Vector2(this.Size.X, this.Size.Y);
}
///
/// The name of this texture region. By default, this name is .
@@ -91,14 +91,14 @@ namespace MLEM.Textures {
/// The texture to use
/// The top left corner of this area
/// The size of this area
- public TextureRegion(Texture2D texture, Point uv, Point size) : this(texture, new Rectangle(uv, size)) {}
+ public TextureRegion(Texture2D texture, Point uv, Point size) : this(texture, new Rectangle(uv.X, uv.Y, size.X, size.Y)) {}
///
/// Creates a new texture region which is a sub-region of the given texture region
///
/// The texture region to create a sub-region of
/// The new texture region area
- public TextureRegion(TextureRegion region, Rectangle area) : this(region, area.Location, area.Size) {}
+ public TextureRegion(TextureRegion region, Rectangle area) : this(region, area.Location, new Point(area.Width, area.Height)) {}
///
/// Creates a new texture region which is a sub-region of the given texture region
diff --git a/MLEM/Textures/UniformTextureAtlas.cs b/MLEM/Textures/UniformTextureAtlas.cs
index 01d414f..9162033 100644
--- a/MLEM/Textures/UniformTextureAtlas.cs
+++ b/MLEM/Textures/UniformTextureAtlas.cs
@@ -47,7 +47,7 @@ namespace MLEM.Textures {
/// Returns the at this texture atlas' given region position
///
/// The region's x and y location
- public TextureRegion this[Point point] => this[new Rectangle(point, new Point(1, 1))];
+ public TextureRegion this[Point point] => this[new Rectangle(point.X, point.Y, 1, 1)];
///
public TextureRegion this[int x, int y] => this[new Point(x, y)];
///
diff --git a/README.md b/README.md
index 478f135..9637045 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
![The MLEM logo](https://raw.githubusercontent.com/Ellpeck/MLEM/main/Media/Banner.png)
-**MLEM Library for Extending MonoGame** is an addition to the game framework [MonoGame](https://www.monogame.net/) that provides extension methods, quality of life improvements and additional features like a ui system and easy input handling.
+**MLEM Library for Extending MonoGame and FNA** is an addition to the game frameworks [MonoGame](https://www.monogame.net/) and [FNA](https://fna-xna.github.io/) that provides extension methods, quality of life improvements and additional features like a ui system and easy input handling.
# What next?
- Get it on [NuGet](https://www.nuget.org/packages?q=mlem)
diff --git a/Sandbox/Sandbox.csproj b/Sandbox/Sandbox.csproj
index f24f47a..ca0fb86 100644
--- a/Sandbox/Sandbox.csproj
+++ b/Sandbox/Sandbox.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/Tests/FNA/FAudio.dll b/Tests/FNA/FAudio.dll
new file mode 100644
index 0000000..57c6067
Binary files /dev/null and b/Tests/FNA/FAudio.dll differ
diff --git a/Tests/FNA/FNA3D.dll b/Tests/FNA/FNA3D.dll
new file mode 100644
index 0000000..fe8024f
Binary files /dev/null and b/Tests/FNA/FNA3D.dll differ
diff --git a/Tests/FNA/SDL2.dll b/Tests/FNA/SDL2.dll
new file mode 100644
index 0000000..7a6c63d
Binary files /dev/null and b/Tests/FNA/SDL2.dll differ
diff --git a/Tests/FNA/libFAudio.0.dylib b/Tests/FNA/libFAudio.0.dylib
new file mode 100644
index 0000000..035020c
Binary files /dev/null and b/Tests/FNA/libFAudio.0.dylib differ
diff --git a/Tests/FNA/libFAudio.so.0 b/Tests/FNA/libFAudio.so.0
new file mode 100644
index 0000000..5b3b116
Binary files /dev/null and b/Tests/FNA/libFAudio.so.0 differ
diff --git a/Tests/FNA/libFNA3D.0.dylib b/Tests/FNA/libFNA3D.0.dylib
new file mode 100644
index 0000000..17b80fb
Binary files /dev/null and b/Tests/FNA/libFNA3D.0.dylib differ
diff --git a/Tests/FNA/libFNA3D.so.0 b/Tests/FNA/libFNA3D.so.0
new file mode 100644
index 0000000..b1c1986
Binary files /dev/null and b/Tests/FNA/libFNA3D.so.0 differ
diff --git a/Tests/FNA/libMoltenVK.dylib b/Tests/FNA/libMoltenVK.dylib
new file mode 100644
index 0000000..9cf069d
Binary files /dev/null and b/Tests/FNA/libMoltenVK.dylib differ
diff --git a/Tests/FNA/libSDL2-2.0.0.dylib b/Tests/FNA/libSDL2-2.0.0.dylib
new file mode 100644
index 0000000..71d8bec
Binary files /dev/null and b/Tests/FNA/libSDL2-2.0.0.dylib differ
diff --git a/Tests/FNA/libSDL2-2.0.so.0 b/Tests/FNA/libSDL2-2.0.so.0
new file mode 100644
index 0000000..55d47d4
Binary files /dev/null and b/Tests/FNA/libSDL2-2.0.so.0 differ
diff --git a/Tests/FNA/libtheorafile.dll b/Tests/FNA/libtheorafile.dll
new file mode 100644
index 0000000..a9b2929
Binary files /dev/null and b/Tests/FNA/libtheorafile.dll differ
diff --git a/Tests/FNA/libtheorafile.dylib b/Tests/FNA/libtheorafile.dylib
new file mode 100644
index 0000000..49116fb
Binary files /dev/null and b/Tests/FNA/libtheorafile.dylib differ
diff --git a/Tests/FNA/libtheorafile.so b/Tests/FNA/libtheorafile.so
new file mode 100644
index 0000000..687e841
Binary files /dev/null and b/Tests/FNA/libtheorafile.so differ
diff --git a/Tests/FNA/libvulkan.1.dylib b/Tests/FNA/libvulkan.1.dylib
new file mode 100644
index 0000000..ff138d4
Binary files /dev/null and b/Tests/FNA/libvulkan.1.dylib differ
diff --git a/Tests/Tests.FNA.csproj b/Tests/Tests.FNA.csproj
new file mode 100644
index 0000000..8bb56c8
--- /dev/null
+++ b/Tests/Tests.FNA.csproj
@@ -0,0 +1,38 @@
+
+
+ net5.0
+ nunit
+ Tests
+ $(DefineConstants);FNA
+
+
+
+
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+ %(Filename)%(Extension)
+
+
+
diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj
index 4a00718..fcf5c37 100644
--- a/Tests/Tests.csproj
+++ b/Tests/Tests.csproj
@@ -13,14 +13,14 @@
-
+ allruntime; build; native; contentfiles; analyzers; buildtransitive
-
+
-
-
+
+
diff --git a/build.cake b/build.cake
index 469b29b..21207e3 100644
--- a/build.cake
+++ b/build.cake
@@ -9,13 +9,13 @@ var config = Argument("configuration", "Release");
Task("Prepare").Does(() => {
DotNetCoreRestore("MLEM.sln");
-
+
if (branch != "release") {
var buildNum = EnvironmentVariable("BUILD_NUMBER");
if (buildNum != null)
version += "-" + buildNum;
}
-
+
DeleteFiles("**/*.nupkg");
});
@@ -27,13 +27,16 @@ Task("Build").IsDependentOn("Prepare").Does(() =>{
foreach (var project in GetFiles("**/MLEM*.csproj"))
DotNetCoreBuild(project.FullPath, settings);
DotNetCoreBuild("Demos/Demos.csproj", settings);
+ DotNetCoreBuild("Demos/Demos.FNA.csproj", settings);
});
Task("Test").IsDependentOn("Build").Does(() => {
- DotNetCoreTest("Tests/Tests.csproj", new DotNetCoreTestSettings {
+ var settings = new DotNetCoreTestSettings {
Configuration = config,
Collectors = {"XPlat Code Coverage"}
- });
+ };
+ DotNetCoreTest("Tests/Tests.csproj", settings);
+ DotNetCoreTest("Tests/Tests.FNA.csproj", settings);
});
Task("Pack").IsDependentOn("Test").Does(() => {
@@ -71,4 +74,4 @@ Task("Document").Does(() => {
Task("Default").IsDependentOn("Pack");
Task("Publish").IsDependentOn("Push");
-RunTarget(target);
\ No newline at end of file
+RunTarget(target);