diff --git a/CHANGELOG.md b/CHANGELOG.md index 5da4032..2fccb82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ Additions - Added GenericFont SplitStringSeparate which differentiates between existing newline characters and splits due to maximum width - Added StaticSpriteBatch class +Improvements +- Exposed Camera's RoundPosition + ### MLEM.Ui Additions - Allow specifying a maximum amount of characters for a TextField diff --git a/Docs/articles/startup.md b/Docs/articles/startup.md index 70717e7..661b066 100644 --- a/Docs/articles/startup.md +++ b/Docs/articles/startup.md @@ -1,9 +1,9 @@ # MLEM.Startup **MLEM.Startup** is a simple package that contains a `MlemGame` class which extends MonoGame's `Game`. This class contains additional properties that most games created with MonoGame and MLEM will have: -- An [InputHandler](https://github.com/Ellpeck/MLEM/wiki/Input-Handler) +- An [InputHandler](xref:MLEM.Input.InputHandler) - A `SpriteBatch` and `GraphicsDeviceManager` -- A [UiSystem](https://github.com/Ellpeck/MLEM/wiki/MLEM.Ui) +- A [UiSystem](ui.md) - Some delegate callbacks for loading, updating and drawing that allow additional code to be executed from outside the game class Additionally, it comes with the [Coroutine](https://www.nuget.org/packages/Coroutine) package preinstalled. The Coroutine package allows creating and running operations alongside the regular game loop without asynchrony. It comes with a `CoroutineEvents` class that contains two types of events that are automatically invoked by `MlemGame`. For more information on how this is useful, see [the Coroutine README](https://github.com/Ellpeck/Coroutine/blob/main/README.md). \ No newline at end of file diff --git a/Docs/articles/text_formatting.md b/Docs/articles/text_formatting.md index 0a3f81c..d5c879c 100644 --- a/Docs/articles/text_formatting.md +++ b/Docs/articles/text_formatting.md @@ -4,7 +4,7 @@ The **MLEM** package contains a simple text formatting system that supports colo Text formatting makes use of [generic fonts](font_extensions.md). -It should also be noted that [MLEM.Ui](https://github.com/Ellpeck/MLEM/wiki/MLEM.Ui)'s `Paragraph`s support text formatting out of the box. +It should also be noted that [MLEM.Ui](ui.md)'s `Paragraph`s support text formatting out of the box. *This documentation is about the new text formatting that was introduced in MLEM 3.3.1. You can see the documentation for the legacy text formatting system [here](text_formatting_legacy.md).* diff --git a/Docs/articles/text_formatting_legacy.md b/Docs/articles/text_formatting_legacy.md index cf5cba3..b1a578d 100644 --- a/Docs/articles/text_formatting_legacy.md +++ b/Docs/articles/text_formatting_legacy.md @@ -4,7 +4,7 @@ The **MLEM** package contains a simple text formatting system that supports colo Text formatting makes use of [generic fonts](font_extensions.md). -It should also be noted that [MLEM.Ui](https://github.com/Ellpeck/MLEM/wiki/MLEM.Ui)'s `Paragraph`s support text formatting out of the box. +It should also be noted that [MLEM.Ui](ui.md)'s `Paragraph`s support text formatting out of the box. ## Formatting codes To format your text, you can insert *formatting codes* into it. These codes are surrounded by `[]` by default, however these delimiters can be changed like so: @@ -23,7 +23,7 @@ By default, the following formatting options are available: ## Getting your text ready To actually display the text with formatting, you first need to gather the formatting data from the text. For performance reasons, this is best done when the text changes, and not every render frame. -To gather formatting data, you will need a [generic font](https://github.com/Ellpeck/MLEM/wiki/Font-Extensions). With it, you can gather the data in the form of a `FormattingCodeCollection` like so: +To gather formatting data, you will need a [generic font](font_extensions.md). With it, you can gather the data in the form of a `FormattingCodeCollection` like so: ```cs var font = new GenericSpriteFont(this.Content.Load("Fonts/ExampleFont")); var text = "This is the [Blue]text[White] that should be [Wobbly]formatted[Unanimated]."; diff --git a/Jenkinsfile b/Jenkinsfile index 9cbbef7..b3c2521 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,7 +5,7 @@ pipeline { steps { sh 'dotnet tool restore' // we use xvfb to allow for graphics-dependent tests - sh 'xvfb-run -a dotnet dotnet-cake --Target=Publish --Branch=' + env.BRANCH_NAME + sh 'xvfb-run -a dotnet cake --target Publish --branch ' + env.BRANCH_NAME } } stage('Document') { @@ -13,7 +13,7 @@ pipeline { branch 'release' } steps { - sh 'dotnet dotnet-cake --Target=Document' + sh 'dotnet cake --target Document' sh 'cp Docs/_site/** /var/www/MLEM/ -r' } } diff --git a/MLEM/Cameras/Camera.cs b/MLEM/Cameras/Camera.cs index f84f292..7f119ba 100644 --- a/MLEM/Cameras/Camera.cs +++ b/MLEM/Cameras/Camera.cs @@ -58,7 +58,7 @@ namespace MLEM.Cameras { get { var sc = this.ActualScale; var pos = -this.Position * sc; - if (this.roundPosition) + if (this.RoundPosition) pos = pos.FloorCopy(); return Matrix.CreateScale(sc, sc, 1) * Matrix.CreateTranslation(new Vector3(pos, 0)); } @@ -82,9 +82,13 @@ namespace MLEM.Cameras { /// The viewport of this camera, based on the game's and this camera's /// public Vector2 ScaledViewport => new Vector2(this.Viewport.Width, this.Viewport.Height) / this.ActualScale; + /// + /// Whether the camera's should be rounded to full integers when calculating the . + /// If this value is true, the occurence of rendering fragments due to floating point rounding might be reduced. + /// + public bool RoundPosition; private Rectangle Viewport => this.graphicsDevice.Viewport.Bounds; - private readonly bool roundPosition; private readonly GraphicsDevice graphicsDevice; private float scale = 1; @@ -92,11 +96,11 @@ namespace MLEM.Cameras { /// Creates a new camera. /// /// The game's graphics device - /// If this is true, the camera's and related properties will be rounded to full integers. + /// 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.roundPosition = roundPosition; + this.RoundPosition = roundPosition; } /// diff --git a/MLEM/Misc/MlemPlatform.cs b/MLEM/Misc/MlemPlatform.cs index d528d9b..a53fac8 100644 --- a/MLEM/Misc/MlemPlatform.cs +++ b/MLEM/Misc/MlemPlatform.cs @@ -66,13 +66,11 @@ namespace MLEM.Misc { /// /// The MLEM DesktopGL platform. /// This platform uses the built-in MonoGame TextInput event, which makes this listener work with any keyboard localization natively. - /// - /// /// This platform is initialized as follows: /// - /// new MlemPlatform.DesktopGl{TextInputEventArgs}((w, c) => w.TextInput += c) + /// MlemPlatform.Current = new MlemPlatform.DesktopGl<TextInputEventArgs>((w, c) => w.TextInput += c); /// - /// + /// /// public class DesktopGl : MlemPlatform { @@ -116,13 +114,11 @@ namespace MLEM.Misc { /// The MLEM platform for mobile platforms as well as consoles. /// This platform opens an on-screen keyboard using the KeyboardInput class on mobile devices. /// Additionally, it starts a new activity whenever is called. - /// - /// /// This listener is initialized as follows in the game's Activity class: /// - /// new MlemPlatform.Mobile(KeyboardInput.Show, l => this.StartActivity(new Intent(Intent.ActionView, Uri.Parse(l)))) + /// MlemPlatform.Current = new MlemPlatform.Mobile(KeyboardInput.Show, l => this.StartActivity(new Intent(Intent.ActionView, Uri.Parse(l)))); /// - /// + /// public class Mobile : MlemPlatform { private readonly OpenOnScreenKeyboardDelegate openOnScreenKeyboard; diff --git a/MLEM/Misc/StaticSpriteBatch.cs b/MLEM/Misc/StaticSpriteBatch.cs index c4f95c3..1e48af2 100644 --- a/MLEM/Misc/StaticSpriteBatch.cs +++ b/MLEM/Misc/StaticSpriteBatch.cs @@ -12,6 +12,10 @@ namespace MLEM.Misc { /// public class StaticSpriteBatch : IDisposable { + // this maximum is limited by indices being a short + private const int MaxBatchItems = short.MaxValue / 6; + private static readonly VertexPositionColorTexture[] Data = new VertexPositionColorTexture[MaxBatchItems * 4]; + /// /// The amount of vertices that are currently batched /// @@ -63,28 +67,23 @@ namespace MLEM.Misc { return; this.batchChanged = false; - // this maximum is limited by indices being a short - const int maxBatchItems = short.MaxValue / 6; - // ensure we have enough vertex buffers - var requiredBuffers = (this.vertices.Count / (maxBatchItems * 4F)).Ceil(); + var requiredBuffers = (this.vertices.Count / (MaxBatchItems * 4F)).Ceil(); while (this.vertexBuffers.Count < requiredBuffers) - this.vertexBuffers.Add(new VertexBuffer(this.graphicsDevice, VertexPositionColorTexture.VertexDeclaration, maxBatchItems * 4, BufferUsage.WriteOnly)); + this.vertexBuffers.Add(new VertexBuffer(this.graphicsDevice, VertexPositionColorTexture.VertexDeclaration, MaxBatchItems * 4, BufferUsage.WriteOnly)); // fill vertex buffers var arrayIndex = 0; var totalIndex = 0; - var data = new VertexPositionColorTexture[maxBatchItems * 4]; while (totalIndex < this.vertices.Count) { - var now = Math.Min(this.vertices.Count - totalIndex, data.Length); - for (var i = 0; i < now; i++) - data[i] = this.vertices[totalIndex + i]; - this.vertexBuffers[arrayIndex++].SetData(data); + var now = Math.Min(this.vertices.Count - totalIndex, Data.Length); + this.vertices.CopyTo(totalIndex, Data, 0, now); + this.vertexBuffers[arrayIndex++].SetData(Data); totalIndex += now; } // ensure we have enough indices - var maxItems = Math.Min(this.vertices.Count / 4, maxBatchItems); + var maxItems = Math.Min(this.vertices.Count / 4, MaxBatchItems); // each item has 2 triangles which each have 3 indices if (this.indices == null || this.indices.IndexCount < 6 * maxItems) { var newIndices = new short[6 * maxItems]; @@ -149,6 +148,8 @@ namespace MLEM.Misc { var totalIndex = 0; foreach (var buffer in this.vertexBuffers) { var tris = Math.Min(this.vertices.Count - totalIndex, buffer.VertexCount) / 4 * 2; + if (tris <= 0) + break; this.graphicsDevice.SetVertexBuffer(buffer); if (effect != null) { foreach (var pass in effect.CurrentTechnique.Passes) {