From ef6f44aa8df7bed31314db3c559eb296319c0a1a Mon Sep 17 00:00:00 2001 From: Andy De George Date: Mon, 11 Jun 2018 11:09:12 -0700 Subject: [PATCH 01/44] Revert "Revert "Added decorator concept to cells"" This reverts commit 82e2504a5bd47a7c801ee237596be54d3cf08f56. --- .../CustomConsoles/StringParsingConsole.cs | 6 ++ src/SadConsole.Shared/Cell.cs | 58 +++++++++++++++++++ .../Renderers/SurfaceRenderer.cs | 7 +++ 3 files changed, 71 insertions(+) diff --git a/src/DemoProject/SharedCode/CustomConsoles/StringParsingConsole.cs b/src/DemoProject/SharedCode/CustomConsoles/StringParsingConsole.cs index 022edc2cb..c0bd21274 100644 --- a/src/DemoProject/SharedCode/CustomConsoles/StringParsingConsole.cs +++ b/src/DemoProject/SharedCode/CustomConsoles/StringParsingConsole.cs @@ -47,6 +47,12 @@ public StringParsingConsole():base(80, 23) Print(1, r, "[c:r f:ansibluebright][c:r b:ansiblue]Examples "); SetGlyph(0, r, 221, Color.Black, ColorAnsi.Blue); + var temp = new CellDecorator(Color.White, 95, Microsoft.Xna.Framework.Graphics.SpriteEffects.None); + for (int i = 241; i < 241 + 24; i++) + { + textSurface[i].Decorators.Add(temp); + } + r += 2; SadConsole.Shapes.Line line = new SadConsole.Shapes.Line(); diff --git a/src/SadConsole.Shared/Cell.cs b/src/SadConsole.Shared/Cell.cs index a78c4da5d..1ee4bc2dc 100644 --- a/src/SadConsole.Shared/Cell.cs +++ b/src/SadConsole.Shared/Cell.cs @@ -17,6 +17,11 @@ namespace SadConsole [DataContract] public class Cell { + /// + /// Modifies the look of a cell with additional character. + /// + public List Decorators = new List(); + /// /// The foreground color of this cell. /// @@ -350,4 +355,57 @@ public CellState(Color foreground, Color background, int glyph, SpriteEffects mi left.IsVisible != right.IsVisible; } } + + /// + /// Decorates a cell, such as an underline. + /// + [DataContract] + public struct CellDecorator + { + /// + /// Foreground color of the decorator. + /// + [DataMember] + public readonly Color Foreground; + + + /// + /// Glyph of the decorator. + /// + [DataMember] + public readonly int Glyph; + + /// + /// Mirror setting of the decorator. + /// + [DataMember] + public readonly SpriteEffects Mirror; + + /// + /// Creates a new decorator with the specified colors, glyph, visiblity, and mirror settings. + /// + /// Foreground color. + /// Glyph value. + /// Mirror setting. + public CellDecorator(Color foreground, int glyph, SpriteEffects mirror) + { + Foreground = foreground; + Glyph = glyph; + Mirror = mirror; + } + + public static bool operator ==(CellDecorator left, CellDecorator right) + { + return left.Foreground == right.Foreground && + left.Glyph == right.Glyph && + left.Mirror == right.Mirror; + } + + public static bool operator !=(CellDecorator left, CellDecorator right) + { + return left.Foreground != right.Foreground || + left.Glyph != right.Glyph || + left.Mirror != right.Mirror; + } + } } diff --git a/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs b/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs index c7f8c79d2..e807f7e92 100644 --- a/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs +++ b/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs @@ -74,6 +74,7 @@ public virtual void RenderCells(Surfaces.ISurface surface, bool force = false) if (surface.Tint.A != 255) { Cell cell; + CellDecorator decorator; if (surface.DefaultBackground.A != 0) Global.SpriteBatch.Draw(surface.Font.FontImage, surface.AbsoluteArea, surface.Font.GlyphRects[surface.Font.SolidGlyphIndex], surface.DefaultBackground, 0f, Vector2.Zero, SpriteEffects.None, 0.2f); @@ -89,6 +90,12 @@ public virtual void RenderCells(Surfaces.ISurface surface, bool force = false) if (cell.Foreground != Color.Transparent) Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[cell.Glyph], cell.Foreground, 0f, Vector2.Zero, cell.Mirror, 0.4f); + + for (int d = 0; d < cell.Decorators.Count; d++) + { + decorator = cell.Decorators[d]; + Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[decorator.Glyph], decorator.Foreground, 0f, Vector2.Zero, decorator.Mirror, 0.4f); + } } } } From 480a8d11bc2deba227375977121ee2593ef78f81 Mon Sep 17 00:00:00 2001 From: Andy De George Date: Thu, 28 Jun 2018 23:44:44 -0700 Subject: [PATCH 02/44] Finished cell decorators feature. fixes #133 --- ChangeLog.md | 8 +- src/SadConsole.Shared/Cell.cs | 193 ++---------------- src/SadConsole.Shared/CellDecorator.cs | 73 +++++++ src/SadConsole.Shared/CellState.cs | 143 +++++++++++++ src/SadConsole.Shared/Palette.cs | 9 +- .../Renderers/ControlsConsoleRenderer.cs | 10 + .../Renderers/LayeredSurfaceRenderer.cs | 15 +- .../Renderers/SurfaceRenderer.cs | 4 +- .../SadConsole.Shared.projitems | 2 + src/SadConsole.Shared/SerializedTypes/Cell.cs | 16 +- 10 files changed, 293 insertions(+), 180 deletions(-) create mode 100644 src/SadConsole.Shared/CellDecorator.cs create mode 100644 src/SadConsole.Shared/CellState.cs diff --git a/ChangeLog.md b/ChangeLog.md index b3649145a..d909a5546 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,4 +1,10 @@ -## 06/11/2018 +## 06/28/2018 V7.0.0 + +- Draw(SpriteBatch batch, Point position, Point size, Font font) has been removed. +- Cell/CellState have a Decorators list which are used to add extra glyph draws to individual cells. +- CellDecorator class added that has a color, glyph, and mirror setting. + +## 06/11/2018 - Fix a stack overflow problem in the window object introduced by the previous mouse bug fix. - Cell states can be stored and restored with variables now. Each cell still has a backing cellstate that can be used. diff --git a/src/SadConsole.Shared/Cell.cs b/src/SadConsole.Shared/Cell.cs index 1ee4bc2dc..94856010d 100644 --- a/src/SadConsole.Shared/Cell.cs +++ b/src/SadConsole.Shared/Cell.cs @@ -1,7 +1,9 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; +using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Runtime.Serialization; using System.Text; @@ -20,7 +22,8 @@ public class Cell /// /// Modifies the look of a cell with additional character. /// - public List Decorators = new List(); + [DataMember] + public List Decorators { get; internal set; } = new List(); /// /// The foreground color of this cell. @@ -109,6 +112,7 @@ public void CopyAppearanceTo(Cell cell) cell.Background = this.Background; cell.Glyph = this.Glyph; cell.Mirror = this.Mirror; + cell.Decorators = new List(this.Decorators); } /// @@ -121,6 +125,7 @@ public void CopyAppearanceFrom(Cell cell) this.Background = cell.Background; this.Glyph = cell.Glyph; this.Mirror = cell.Mirror; + this.Decorators = new List(cell.Decorators); } /// @@ -132,6 +137,7 @@ public void Clear() Background = Color.Black; Glyph = 0; Mirror = SpriteEffects.None; + Decorators.Clear(); } /// @@ -159,17 +165,21 @@ public void Draw(SpriteBatch batch, Rectangle drawingRectangle, Font font) if (Foreground != Color.Transparent) batch.Draw(font.FontImage, drawingRectangle, font.GlyphRects[Glyph], Foreground, 0f, Vector2.Zero, Mirror, 0.4f); + + foreach (var decorator in Decorators) + if (decorator.Color != Color.Transparent) + batch.Draw(font.FontImage, drawingRectangle, font.GlyphRects[decorator.Glyph], decorator.Color, 0f, Vector2.Zero, decorator.Mirror, 0.5f); } /// /// Saves the current state of this cell to the property. /// - public void SaveState() => State = new CellState(Foreground, Background, Glyph, Mirror, IsVisible); + public void SaveState() => State = new CellState(Foreground, Background, Glyph, Mirror, IsVisible, Decorators); /// /// Saves the current state of this cell to the provided state variable. /// - public void SaveState(out CellState state) => state = new CellState(Foreground, Background, Glyph, Mirror, IsVisible); + public void SaveState(out CellState state) => state = new CellState(Foreground, Background, Glyph, Mirror, IsVisible, Decorators); /// /// Restores the state of this cell from the property. @@ -183,7 +193,7 @@ public void RestoreState() Glyph = State.Value.Glyph; Mirror = State.Value.Mirror; IsVisible = State.Value.IsVisible; - + Decorators = new List(State.Value.Decorators); State = null; } } @@ -198,6 +208,7 @@ public void RestoreState(ref CellState state) Glyph = state.Glyph; Mirror = state.Mirror; IsVisible = state.IsVisible; + Decorators = new List(state.Decorators); } /// @@ -209,7 +220,7 @@ public void RestoreState(ref CellState state) /// Returns a new cell with the same properties as this one. /// /// The new cell. - public Cell Clone() => new Cell(Foreground, Background, Glyph, Mirror) { IsVisible = this.IsVisible }; + public Cell Clone() => new Cell(Foreground, Background, Glyph, Mirror) { IsVisible = this.IsVisible, Decorators = new List(this.Decorators) }; /// /// Compares if the cell is the same as the state. @@ -223,7 +234,8 @@ public void RestoreState(ref CellState state) left.Foreground == right.Foreground && left.Glyph == right.Glyph && left.Mirror == right.Mirror && - left.IsVisible == right.IsVisible; + left.IsVisible == right.IsVisible && + left.Decorators.SequenceEqual(right.Decorators); } /// @@ -238,174 +250,11 @@ public void RestoreState(ref CellState state) left.Foreground != right.Foreground || left.Glyph != right.Glyph || left.Mirror != right.Mirror || - left.IsVisible != right.IsVisible; + left.IsVisible != right.IsVisible && + !left.Decorators.SequenceEqual(right.Decorators); } } - /// - /// A cell in structure format for temporary storage. - /// - [DataContract] - public struct CellState - { - /// - /// Foreground color of the state. - /// - [DataMember] - public readonly Color Foreground; - - /// - /// Background color of the state. - /// - [DataMember] - public readonly Color Background; - - /// - /// Glyph of the state. - /// - [DataMember] - public readonly int Glyph; - - /// - /// Mirror setting of the state. - /// - [DataMember] - public readonly SpriteEffects Mirror; - /// - /// Visible setting of the state. - /// - [DataMember] - public readonly bool IsVisible; - - /// - /// Creates a new state with the specified colors, glyph, visiblity, and mirror settings. - /// - /// Foreground color. - /// Background color. - /// Glyph value. - /// Mirror setting. - /// Visbility setting. - public CellState(Color foreground, Color background, int glyph, SpriteEffects mirror, bool isVisible) - { - Foreground = foreground; - Background = background; - Glyph = glyph; - Mirror = mirror; - IsVisible = isVisible; - } - - /// - /// Creates a cell state from a cell. - /// - /// The source cell to create a state from. - public CellState(Cell source) : this(source.Foreground, source.Background, source.Glyph, source.Mirror, source.IsVisible) { } - - public static bool operator ==(CellState left, CellState right) - { - return left.Background == right.Background && - left.Foreground == right.Foreground && - left.Glyph == right.Glyph && - left.Mirror == right.Mirror && - left.IsVisible == right.IsVisible; - } - - public static bool operator !=(CellState left, CellState right) - { - return left.Background != right.Background || - left.Foreground != right.Foreground || - left.Glyph != right.Glyph || - left.Mirror != right.Mirror || - left.IsVisible != right.IsVisible; - } - - public static bool operator ==(CellState left, Cell right) - { - return left.Background == right.Background && - left.Foreground == right.Foreground && - left.Glyph == right.Glyph && - left.Mirror == right.Mirror && - left.IsVisible == right.IsVisible; - } - - public static bool operator !=(CellState left, Cell right) - { - return left.Background != right.Background || - left.Foreground != right.Foreground || - left.Glyph != right.Glyph || - left.Mirror != right.Mirror || - left.IsVisible != right.IsVisible; - } - - public static bool operator ==(Cell right, CellState left) - { - return left.Background == right.Background && - left.Foreground == right.Foreground && - left.Glyph == right.Glyph && - left.Mirror == right.Mirror && - left.IsVisible == right.IsVisible; - } - - public static bool operator !=(Cell left, CellState right) - { - return left.Background != right.Background || - left.Foreground != right.Foreground || - left.Glyph != right.Glyph || - left.Mirror != right.Mirror || - left.IsVisible != right.IsVisible; - } - } - - /// - /// Decorates a cell, such as an underline. - /// - [DataContract] - public struct CellDecorator - { - /// - /// Foreground color of the decorator. - /// - [DataMember] - public readonly Color Foreground; - - - /// - /// Glyph of the decorator. - /// - [DataMember] - public readonly int Glyph; - - /// - /// Mirror setting of the decorator. - /// - [DataMember] - public readonly SpriteEffects Mirror; - - /// - /// Creates a new decorator with the specified colors, glyph, visiblity, and mirror settings. - /// - /// Foreground color. - /// Glyph value. - /// Mirror setting. - public CellDecorator(Color foreground, int glyph, SpriteEffects mirror) - { - Foreground = foreground; - Glyph = glyph; - Mirror = mirror; - } - - public static bool operator ==(CellDecorator left, CellDecorator right) - { - return left.Foreground == right.Foreground && - left.Glyph == right.Glyph && - left.Mirror == right.Mirror; - } - - public static bool operator !=(CellDecorator left, CellDecorator right) - { - return left.Foreground != right.Foreground || - left.Glyph != right.Glyph || - left.Mirror != right.Mirror; - } - } + } diff --git a/src/SadConsole.Shared/CellDecorator.cs b/src/SadConsole.Shared/CellDecorator.cs new file mode 100644 index 000000000..da7bb0d98 --- /dev/null +++ b/src/SadConsole.Shared/CellDecorator.cs @@ -0,0 +1,73 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Text; + +namespace SadConsole +{ + /// + /// Decorates a cell with a colored glyph. + /// + [DataContract] + public struct CellDecorator : IEquatable + { + /// + /// An empty cell decorator. + /// + public static CellDecorator Empty { get; } + + /// + /// Foreground color of the decorator. + /// + [DataMember] + public readonly Color Color; + + /// + /// Glyph of the decorator. + /// + [DataMember] + public readonly int Glyph; + + /// + /// Mirror setting of the decorator. + /// + [DataMember] + public readonly SpriteEffects Mirror; + + /// + /// Creates a new decorator with the specified colors, glyph, visiblity, and mirror settings. + /// + /// Foreground color. + /// Glyph value. + /// Mirror setting. + public CellDecorator(Color color, int glyph, SpriteEffects mirror) + { + Color = color; + Glyph = glyph; + Mirror = mirror; + } + + /// + /// Determines if this object has the same value as the other. + /// + /// The object to test against. + /// True if the objects have the same values. + public bool Equals(CellDecorator other) => other == this; + + public static bool operator ==(CellDecorator left, CellDecorator right) + { + return left.Color == right.Color && + left.Glyph == right.Glyph && + left.Mirror == right.Mirror; + } + + public static bool operator !=(CellDecorator left, CellDecorator right) + { + return left.Color != right.Color || + left.Glyph != right.Glyph || + left.Mirror != right.Mirror; + } + } +} diff --git a/src/SadConsole.Shared/CellState.cs b/src/SadConsole.Shared/CellState.cs new file mode 100644 index 000000000..0becff0db --- /dev/null +++ b/src/SadConsole.Shared/CellState.cs @@ -0,0 +1,143 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Linq; +using System.Text; + +namespace SadConsole +{ + /// + /// A cell in structure format for temporary storage. + /// + [DataContract] + public struct CellState: IEquatable + { + /// + /// Decorators of the state. + /// + [DataMember] + public readonly CellDecorator[] Decorators; + + /// + /// Foreground color of the state. + /// + [DataMember] + public readonly Color Foreground; + + /// + /// Background color of the state. + /// + [DataMember] + public readonly Color Background; + + /// + /// Glyph of the state. + /// + [DataMember] + public readonly int Glyph; + + /// + /// Mirror setting of the state. + /// + [DataMember] + public readonly SpriteEffects Mirror; + + /// + /// Visible setting of the state. + /// + [DataMember] + public readonly bool IsVisible; + + /// + /// Creates a new state with the specified colors, glyph, visiblity, and mirror settings. + /// + /// Foreground color. + /// Background color. + /// Glyph value. + /// Mirror setting. + /// Visbility setting. + /// Decorators setting. + public CellState(Color foreground, Color background, int glyph, SpriteEffects mirror, bool isVisible, IEnumerable decorators) + { + Foreground = foreground; + Background = background; + Glyph = glyph; + Mirror = mirror; + IsVisible = isVisible; + Decorators = new List(decorators).ToArray(); + } + + /// + /// Creates a cell state from a cell. + /// + /// The source cell to create a state from. + public CellState(Cell source) : this(source.Foreground, source.Background, source.Glyph, source.Mirror, source.IsVisible, source.Decorators) { } + + public static bool operator ==(CellState left, CellState right) + { + return left.Background == right.Background && + left.Foreground == right.Foreground && + left.Glyph == right.Glyph && + left.Mirror == right.Mirror && + left.IsVisible == right.IsVisible && + left.Decorators.SequenceEqual(right.Decorators); + } + + public static bool operator !=(CellState left, CellState right) + { + return left.Background != right.Background || + left.Foreground != right.Foreground || + left.Glyph != right.Glyph || + left.Mirror != right.Mirror || + left.IsVisible != right.IsVisible && + !left.Decorators.SequenceEqual(right.Decorators); + } + + public static bool operator ==(CellState left, Cell right) + { + return left.Background == right.Background && + left.Foreground == right.Foreground && + left.Glyph == right.Glyph && + left.Mirror == right.Mirror && + left.IsVisible == right.IsVisible && + left.Decorators.SequenceEqual(right.Decorators); + } + + public static bool operator !=(CellState left, Cell right) + { + return left.Background != right.Background || + left.Foreground != right.Foreground || + left.Glyph != right.Glyph || + left.Mirror != right.Mirror || + left.IsVisible != right.IsVisible && + !left.Decorators.SequenceEqual(right.Decorators); + } + + public static bool operator ==(Cell right, CellState left) + { + return left.Background == right.Background && + left.Foreground == right.Foreground && + left.Glyph == right.Glyph && + left.Mirror == right.Mirror && + left.IsVisible == right.IsVisible && + left.Decorators.SequenceEqual(right.Decorators); + } + + public static bool operator !=(Cell left, CellState right) + { + return left.Background != right.Background || + left.Foreground != right.Foreground || + left.Glyph != right.Glyph || + left.Mirror != right.Mirror || + left.IsVisible != right.IsVisible && + !left.Decorators.SequenceEqual(right.Decorators); + } + + public bool Equals(CellState other) + { + return this == other; + } + } +} diff --git a/src/SadConsole.Shared/Palette.cs b/src/SadConsole.Shared/Palette.cs index c9a1b62e2..e75f7ef66 100644 --- a/src/SadConsole.Shared/Palette.cs +++ b/src/SadConsole.Shared/Palette.cs @@ -98,8 +98,15 @@ public void ShiftRight(int startingIndex, int count) /// Gets the closest color in the palette to the provided color. /// /// The color to find. + /// The closest matching color. + public Color GetNearest(Color color) => colors[GetNearestIndex(color)]; + + /// + /// Gets the index of the closest color in the palette to the provided color. + /// + /// The color to find. /// The palette index of the closest color. - public int GetNearest(Color color) + public int GetNearestIndex(Color color) { int lowestDistanceIndex = -1; int lowestDistance = int.MaxValue; diff --git a/src/SadConsole.Shared/Renderers/ControlsConsoleRenderer.cs b/src/SadConsole.Shared/Renderers/ControlsConsoleRenderer.cs index 175fe0d64..071ad3020 100644 --- a/src/SadConsole.Shared/Renderers/ControlsConsoleRenderer.cs +++ b/src/SadConsole.Shared/Renderers/ControlsConsoleRenderer.cs @@ -41,6 +41,8 @@ public virtual void RenderControls(ISurface surface, bool force = false) Controls.ControlBase control; Cell cell; Font font; + CellDecorator decorator; + // For each control for (int i = 0; i < Controls.Count; i++) { @@ -71,6 +73,14 @@ public virtual void RenderControls(ISurface surface, bool force = false) if (cell.Foreground != Color.Transparent) Global.SpriteBatch.Draw(font.FontImage, rect, font.GlyphRects[cell.Glyph], cell.Foreground, 0f, Vector2.Zero, cell.Mirror, 0.26f); + + for (int d = 0; d < cell.Decorators.Count; d++) + { + decorator = cell.Decorators[d]; + + if (decorator.Color != Color.Transparent) + Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[decorator.Glyph], decorator.Color, 0f, Vector2.Zero, decorator.Mirror, 0.5f); + } } } } diff --git a/src/SadConsole.Shared/Renderers/LayeredSurfaceRenderer.cs b/src/SadConsole.Shared/Renderers/LayeredSurfaceRenderer.cs index 0eb495ea0..dda3fafcc 100644 --- a/src/SadConsole.Shared/Renderers/LayeredSurfaceRenderer.cs +++ b/src/SadConsole.Shared/Renderers/LayeredSurfaceRenderer.cs @@ -36,6 +36,7 @@ public override void RenderCells(ISurface surface, bool force = false) if (surface.Tint.A != 255) { Cell cell; + CellDecorator decorator; if (surface.DefaultBackground.A != 0) Global.SpriteBatch.Draw(surface.Font.FontImage, surface.AbsoluteArea, surface.Font.GlyphRects[surface.Font.SolidGlyphIndex], surface.DefaultBackground, 0f, Vector2.Zero, SpriteEffects.None, 0.2f); @@ -50,9 +51,19 @@ public override void RenderCells(ISurface surface, bool force = false) if (cell.IsVisible) { - Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[surface.Font.SolidGlyphIndex], cell.Background, 0f, Vector2.Zero, SpriteEffects.None, 0.3f); + if (cell.Background != Color.Transparent && cell.Background != surface.DefaultBackground) + Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[surface.Font.SolidGlyphIndex], cell.Background, 0f, Vector2.Zero, SpriteEffects.None, 0.3f); - Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[cell.Glyph], cell.Foreground, 0f, Vector2.Zero, cell.Mirror, 0.4f); + if (cell.Foreground != Color.Transparent) + Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[cell.Glyph], cell.Foreground, 0f, Vector2.Zero, cell.Mirror, 0.4f); + + for (int d = 0; d < cell.Decorators.Count; d++) + { + decorator = cell.Decorators[d]; + + if (decorator.Color != Color.Transparent) + Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[decorator.Glyph], decorator.Color, 0f, Vector2.Zero, decorator.Mirror, 0.5f); + } } } } diff --git a/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs b/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs index e807f7e92..73a7a8fd6 100644 --- a/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs +++ b/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs @@ -94,7 +94,9 @@ public virtual void RenderCells(Surfaces.ISurface surface, bool force = false) for (int d = 0; d < cell.Decorators.Count; d++) { decorator = cell.Decorators[d]; - Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[decorator.Glyph], decorator.Foreground, 0f, Vector2.Zero, decorator.Mirror, 0.4f); + + if (decorator.Color != Color.Transparent) + Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[decorator.Glyph], decorator.Color, 0f, Vector2.Zero, decorator.Mirror, 0.5f); } } } diff --git a/src/SadConsole.Shared/SadConsole.Shared.projitems b/src/SadConsole.Shared/SadConsole.Shared.projitems index 260d2345d..fa6f2fec5 100644 --- a/src/SadConsole.Shared/SadConsole.Shared.projitems +++ b/src/SadConsole.Shared/SadConsole.Shared.projitems @@ -15,6 +15,8 @@ + + diff --git a/src/SadConsole.Shared/SerializedTypes/Cell.cs b/src/SadConsole.Shared/SerializedTypes/Cell.cs index 0ee56305f..42824d590 100644 --- a/src/SadConsole.Shared/SerializedTypes/Cell.cs +++ b/src/SadConsole.Shared/SerializedTypes/Cell.cs @@ -2,12 +2,16 @@ using System.Collections.Generic; using System.Runtime.Serialization; using System.Text; +using System.Linq; namespace SadConsole.SerializedTypes { [DataContract] public class CellSerialized { + [DataMember] + public CellDecorator[] Decorators; + [DataMember] public ColorSerialized Foreground; @@ -35,6 +39,7 @@ public class CellSerialized Glyph = cell.Glyph, IsVisible = cell.IsVisible, Mirror = cell.Mirror, + Decorators = cell.Decorators.ToArray(), CellState = cell.State == null ? null : cell.State }; } @@ -43,7 +48,8 @@ public class CellSerialized { var newCell = new Cell(cell.Foreground, cell.Background, cell.Glyph, cell.Mirror) { - IsVisible = cell.IsVisible + IsVisible = cell.IsVisible, + Decorators = new List(cell.Decorators) }; if (cell.CellState != null) @@ -57,6 +63,9 @@ public class CellSerialized [DataContract] public class CellStateSerialized { + [DataMember] + public CellDecorator[] Decorators; + [DataMember] public ColorSerialized Foreground; @@ -80,13 +89,14 @@ public class CellStateSerialized Background = cell.Background, Glyph = cell.Glyph, IsVisible = cell.IsVisible, - Mirror = cell.Mirror + Mirror = cell.Mirror, + Decorators = cell.Decorators.ToArray() }; } public static implicit operator CellState(CellStateSerialized cell) { - return new CellState(cell.Foreground, cell.Background, cell.Glyph, cell.Mirror, cell.IsVisible); + return new CellState(cell.Foreground, cell.Background, cell.Glyph, cell.Mirror, cell.IsVisible, cell.Decorators); } } From 121cd11c12de4ac789cd849da14382f37389e22b Mon Sep 17 00:00:00 2001 From: Andy De George Date: Fri, 29 Jun 2018 12:03:59 -0700 Subject: [PATCH 03/44] Changed Carrot to Caret. Fixed orientation/alignment namespace to SadConsole. Fixes #120 --- src/SadConsole.Shared/Controls/Button.cs | 4 +- src/SadConsole.Shared/Controls/CheckBox.cs | 4 +- src/SadConsole.Shared/Controls/InputBox.cs | 94 +++++++++---------- src/SadConsole.Shared/Controls/ListBox.cs | 2 +- src/SadConsole.Shared/Controls/ProgressBar.cs | 32 +++---- src/SadConsole.Shared/Controls/RadioButton.cs | 4 +- src/SadConsole.Shared/Controls/ScrollBar.cs | 18 ++-- .../Extensions/XamlExtensions.cs | 4 +- src/SadConsole.Shared/Themes/InputBoxTheme.cs | 4 +- src/SadConsole.Shared/Themes/Library.cs | 2 +- 10 files changed, 84 insertions(+), 84 deletions(-) diff --git a/src/SadConsole.Shared/Controls/Button.cs b/src/SadConsole.Shared/Controls/Button.cs index 6b498f17d..3302037ad 100644 --- a/src/SadConsole.Shared/Controls/Button.cs +++ b/src/SadConsole.Shared/Controls/Button.cs @@ -45,7 +45,7 @@ public abstract class ButtonBase: ControlBase /// The alignment of the . /// [DataMember(Name = "TextAlignment")] - protected System.Windows.HorizontalAlignment textAlignment = System.Windows.HorizontalAlignment.Center; + protected HorizontalAlignment textAlignment = HorizontalAlignment.Center; /// /// Selected part of the theme based on the state of the control. @@ -64,7 +64,7 @@ public string Text /// /// The alignment of the text, left, center, or right. /// - public System.Windows.HorizontalAlignment TextAlignment + public HorizontalAlignment TextAlignment { get { return textAlignment; } set { textAlignment = value; Compose(true); } diff --git a/src/SadConsole.Shared/Controls/CheckBox.cs b/src/SadConsole.Shared/Controls/CheckBox.cs index 34c1cbfd4..94e2a8fbe 100644 --- a/src/SadConsole.Shared/Controls/CheckBox.cs +++ b/src/SadConsole.Shared/Controls/CheckBox.cs @@ -25,7 +25,7 @@ public class CheckBox : ControlBase [DataMember(Name = "Text")] protected string _text; [DataMember(Name = "TextAlignment")] - protected System.Windows.HorizontalAlignment _textAlignment; + protected HorizontalAlignment _textAlignment; [DataMember(Name = "IsSelected")] protected bool _isSelected; protected bool _isMouseDown; @@ -64,7 +64,7 @@ public string Text /// /// The alignment of the text, left, center, or right. /// - public System.Windows.HorizontalAlignment TextAlignment + public HorizontalAlignment TextAlignment { get { return _textAlignment; } set { _textAlignment = value; Compose(true); } diff --git a/src/SadConsole.Shared/Controls/InputBox.cs b/src/SadConsole.Shared/Controls/InputBox.cs index e1998f7b7..5c75799e1 100644 --- a/src/SadConsole.Shared/Controls/InputBox.cs +++ b/src/SadConsole.Shared/Controls/InputBox.cs @@ -21,9 +21,9 @@ namespace SadConsole.Controls public class InputBox: ControlBase { /// - /// Indicates the carrot is visible. + /// Indicates the caret is visible. /// - protected bool isCarrotVisible = false; + protected bool isCaretVisible = false; /// /// A list of valid number characters @@ -48,10 +48,10 @@ public class InputBox: ControlBase protected int _leftDrawOffset; /// - /// The location of the carrot. + /// The location of the caret. /// - [DataMember(Name = "CarrotPosition")] - protected int _carrotPos; + [DataMember(Name = "CaretPosition")] + protected int _caretPos; /// /// The text value of the input box. @@ -122,7 +122,7 @@ public virtual InputBoxTheme Theme } /// - /// The alignment of the carrot. + /// The alignment of the caret. /// public HorizontalAlignment TextAlignment { @@ -137,14 +137,14 @@ public HorizontalAlignment TextAlignment public int MaxLength { get; set; } /// - /// Gets or sets the position of the carrot in the current text. + /// Gets or sets the position of the caret in the current text. /// - public int CarrotPosition + public int CaretPosition { - get { return _carrotPos; } + get { return _caretPos; } set { - _carrotPos = value; + _caretPos = value; IsDirty = true; } } @@ -224,12 +224,12 @@ public override void Compose() if (base.IsFocused && !DisableKeyboard) { this.Print(0, 0, _editingText.Substring(_leftDrawOffset)); - effects.SetEffect(this[this._carrotPos - _leftDrawOffset, 0], Theme.CarrotEffect); - isCarrotVisible = true; + effects.SetEffect(this[this._caretPos - _leftDrawOffset, 0], Theme.CaretEffect); + isCaretVisible = true; } else { - isCarrotVisible = false; + isCaretVisible = false; this.Print(0, 0, _text.Align(TextAlignment, this.Width)); } @@ -307,15 +307,15 @@ protected void PositionCursor() _editingText = _editingText.Substring(0, MaxLength); if (_editingText.Length == MaxLength) - _carrotPos = _editingText.Length - 1; + _caretPos = _editingText.Length - 1; else - _carrotPos = _editingText.Length; + _caretPos = _editingText.Length; } else - _carrotPos = _editingText.Length; + _caretPos = _editingText.Length; - // Test to see if carrot is off edge of box - if (_carrotPos >= Width) + // Test to see if caret is off edge of box + if (_caretPos >= Width) { _leftDrawOffset = _editingText.Length - Width + 1; @@ -387,33 +387,33 @@ public override bool ProcessKeyboard(Input.Keyboard info) else { - if (info.KeysPressed[i].Key == Keys.Back && newText.Length != 0 && _carrotPos != 0) + if (info.KeysPressed[i].Key == Keys.Back && newText.Length != 0 && _caretPos != 0) { - if (_carrotPos == newText.Length) + if (_caretPos == newText.Length) newText.Remove(newText.Length - 1, 1); else - newText.Remove(_carrotPos - 1, 1); + newText.Remove(_caretPos - 1, 1); - _carrotPos -= 1; + _caretPos -= 1; - if (_carrotPos == -1) - _carrotPos = 0; + if (_caretPos == -1) + _caretPos = 0; } else if (info.KeysPressed[i].Key == Keys.Space && (MaxLength == 0 || (MaxLength != 0 && newText.Length < MaxLength))) { - newText.Insert(_carrotPos, ' '); - _carrotPos++; + newText.Insert(_caretPos, ' '); + _caretPos++; - if (_carrotPos > newText.Length) - _carrotPos = newText.Length; + if (_caretPos > newText.Length) + _caretPos = newText.Length; } - else if (info.KeysPressed[i].Key == Keys.Delete && _carrotPos != newText.Length) + else if (info.KeysPressed[i].Key == Keys.Delete && _caretPos != newText.Length) { - newText.Remove(_carrotPos, 1); + newText.Remove(_caretPos, 1); - if (_carrotPos > newText.Length) - _carrotPos = newText.Length; + if (_caretPos > newText.Length) + _caretPos = newText.Length; } else if (info.KeysPressed[i].Key == Keys.Enter) @@ -429,40 +429,40 @@ public override bool ProcessKeyboard(Input.Keyboard info) } else if (info.KeysPressed[i].Key == Keys.Left) { - _carrotPos -= 1; + _caretPos -= 1; - if (_carrotPos == -1) - _carrotPos = 0; + if (_caretPos == -1) + _caretPos = 0; } else if (info.KeysPressed[i].Key == Keys.Right) { - _carrotPos += 1; + _caretPos += 1; - if (_carrotPos > newText.Length) - _carrotPos = newText.Length; + if (_caretPos > newText.Length) + _caretPos = newText.Length; } else if (info.KeysPressed[i].Key == Keys.Home) { - _carrotPos = 0; + _caretPos = 0; } else if (info.KeysPressed[i].Key == Keys.End) { - _carrotPos = newText.Length; + _caretPos = newText.Length; } else if (info.KeysPressed[i].Character != 0 && (MaxLength == 0 || (MaxLength != 0 && newText.Length < MaxLength))) { - newText.Insert(_carrotPos, info.KeysPressed[i].Character); - _carrotPos++; + newText.Insert(_caretPos, info.KeysPressed[i].Character); + _caretPos++; - if (_carrotPos > newText.Length) - _carrotPos = newText.Length; + if (_caretPos > newText.Length) + _caretPos = newText.Length; } - // Test to see if carrot is off edge of box - if (_carrotPos >= Width) + // Test to see if caret is off edge of box + if (_caretPos >= Width) { _leftDrawOffset = newText.Length - Width + 1; @@ -530,7 +530,7 @@ protected override void OnLeftMouseClicked(Input.MouseConsoleState state) public override void Update() { - if (isCarrotVisible) + if (isCaretVisible) { effects.UpdateEffects(Global.GameTimeElapsedUpdate); OnComposed?.Invoke(this); diff --git a/src/SadConsole.Shared/Controls/ListBox.cs b/src/SadConsole.Shared/Controls/ListBox.cs index 699081b96..13a37079b 100644 --- a/src/SadConsole.Shared/Controls/ListBox.cs +++ b/src/SadConsole.Shared/Controls/ListBox.cs @@ -230,7 +230,7 @@ protected void SetupSlider() if (initialized) { //_slider.Width, height < 3 ? 3 : height - _scrollBarSizeAdjust - slider = ScrollBar.Create(System.Windows.Controls.Orientation.Vertical, Height); + slider = ScrollBar.Create(Orientation.Vertical, Height); slider.ValueChanged += new EventHandler(_slider_ValueChanged); slider.IsVisible = false; slider.Theme = this.Theme.ScrollBarTheme; diff --git a/src/SadConsole.Shared/Controls/ProgressBar.cs b/src/SadConsole.Shared/Controls/ProgressBar.cs index 05e8c540b..3864b9cbc 100644 --- a/src/SadConsole.Shared/Controls/ProgressBar.cs +++ b/src/SadConsole.Shared/Controls/ProgressBar.cs @@ -56,13 +56,13 @@ public class ProgressBar : ControlBase /// The alignment if the bar is horizontal. /// [DataMember] - protected System.Windows.HorizontalAlignment horizontalAlignment; + protected HorizontalAlignment horizontalAlignment; /// /// The alignment if the bar is vertical. /// [DataMember] - protected System.Windows.VerticalAlignment verticalAlignment; + protected VerticalAlignment verticalAlignment; /// /// The theme of this control. If the theme is not explicitly set, the theme is taken from the library. @@ -87,13 +87,13 @@ public virtual ProgressBarTheme Theme /// /// The horizontal orientation used when is set to true. /// - /// Thrown when the value is set to either or . - public System.Windows.HorizontalAlignment HorizontalAlignment + /// Thrown when the value is set to either or . + public HorizontalAlignment HorizontalAlignment { get { return horizontalAlignment; } set { - if (value == System.Windows.HorizontalAlignment.Center || value == System.Windows.HorizontalAlignment.Stretch) + if (value == HorizontalAlignment.Center || value == HorizontalAlignment.Stretch) throw new InvalidOperationException("HorizontalAlignment.Center or HorizontalAlignment.Stretch is invalid for the progress bar control."); horizontalAlignment = value; @@ -104,13 +104,13 @@ public System.Windows.HorizontalAlignment HorizontalAlignment /// /// The vertical orientation used when is set to false. /// - /// Thrown when the value is set to either or . - public System.Windows.VerticalAlignment VerticalAlignment + /// Thrown when the value is set to either or . + public VerticalAlignment VerticalAlignment { get { return verticalAlignment; } set { - if (value == System.Windows.VerticalAlignment.Center || value == System.Windows.VerticalAlignment.Stretch) + if (value == VerticalAlignment.Center || value == VerticalAlignment.Stretch) throw new InvalidOperationException("VerticalAlignment.Center or VerticalAlignment.Stretch is invalid for the progress bar control."); verticalAlignment = value; @@ -172,10 +172,10 @@ public float Progress /// Width of the control. /// Height of the control. /// Sets the control to be horizontal, starting from the specified side. Center/Stretch is invalid. - /// Thrown when is set to either or . - public ProgressBar(int width, int height, System.Windows.HorizontalAlignment horizontalAlignment) : base(width, height) + /// Thrown when is set to either or . + public ProgressBar(int width, int height, HorizontalAlignment horizontalAlignment) : base(width, height) { - if (horizontalAlignment == System.Windows.HorizontalAlignment.Center || horizontalAlignment == System.Windows.HorizontalAlignment.Stretch) + if (horizontalAlignment == HorizontalAlignment.Center || horizontalAlignment == HorizontalAlignment.Stretch) throw new InvalidOperationException("HorizontalAlignment.Center or HorizontalAlignment.Stretch is invalid for the progress bar control."); this.horizontalAlignment = horizontalAlignment; @@ -194,10 +194,10 @@ public ProgressBar(int width, int height, System.Windows.HorizontalAlignment hor /// Width of the control. /// Height of the control. /// Sets the control to be vertical, starting from the specified side. Center/Stretch is invalid. - /// Thrown when is set to either or . - public ProgressBar(int width, int height, System.Windows.VerticalAlignment verticalAlignment) : base(width, height) + /// Thrown when is set to either or . + public ProgressBar(int width, int height, VerticalAlignment verticalAlignment) : base(width, height) { - if (verticalAlignment == System.Windows.VerticalAlignment.Center || verticalAlignment == System.Windows.VerticalAlignment.Stretch) + if (verticalAlignment == VerticalAlignment.Center || verticalAlignment == VerticalAlignment.Stretch) throw new InvalidOperationException("VerticalAlignment.Center or VerticalAlignment.Stretch is invalid for the progress bar control."); this.verticalAlignment = verticalAlignment; @@ -281,7 +281,7 @@ public override void Compose() { Rectangle fillRect; - if (horizontalAlignment == System.Windows.HorizontalAlignment.Left) + if (horizontalAlignment == HorizontalAlignment.Left) fillRect = new Rectangle(0, 0, fillSize, Height); else fillRect = new Rectangle(Width - fillSize, 0, fillSize, Height); @@ -293,7 +293,7 @@ public override void Compose() { Rectangle fillRect; - if (verticalAlignment == System.Windows.VerticalAlignment.Top) + if (verticalAlignment == VerticalAlignment.Top) fillRect = new Rectangle(0, 0, Width, fillSize); else fillRect = new Rectangle(0, Height - fillSize, Width, fillSize); diff --git a/src/SadConsole.Shared/Controls/RadioButton.cs b/src/SadConsole.Shared/Controls/RadioButton.cs index 5455b4b7c..bf464b9d6 100644 --- a/src/SadConsole.Shared/Controls/RadioButton.cs +++ b/src/SadConsole.Shared/Controls/RadioButton.cs @@ -25,7 +25,7 @@ public class RadioButton: ControlBase [DataMember(Name = "Text")] protected string _text; [DataMember(Name = "TextAlignment")] - protected System.Windows.HorizontalAlignment _textAlignment; + protected HorizontalAlignment _textAlignment; [DataMember(Name = "IsSelected")] protected bool _isSelected; protected bool _isMouseDown; @@ -64,7 +64,7 @@ public string Text /// /// The alignment of the text, left, center, or right. /// - public System.Windows.HorizontalAlignment TextAlignment + public HorizontalAlignment TextAlignment { get { return _textAlignment; } set { _textAlignment = value; Compose(true); } diff --git a/src/SadConsole.Shared/Controls/ScrollBar.cs b/src/SadConsole.Shared/Controls/ScrollBar.cs index e48eb1293..27e60c491 100644 --- a/src/SadConsole.Shared/Controls/ScrollBar.cs +++ b/src/SadConsole.Shared/Controls/ScrollBar.cs @@ -28,7 +28,7 @@ public class ScrollBar : ControlBase protected int _sliderBarCharacter; [DataMember(Name="Orientation")] - protected System.Windows.Controls.Orientation _barOrientation; + protected Orientation _barOrientation; [DataMember(Name = "Value")] protected int _value; [DataMember(Name = "Minimum")] @@ -175,26 +175,26 @@ public int SliderBarCharacter set { _sliderBarCharacter = value; this.IsDirty = true; } } - public static ScrollBar Create(System.Windows.Controls.Orientation orientation, int size) + public static ScrollBar Create(Orientation orientation, int size) { if (size <= 2) throw new Exception("The scroll bar must be 4 or more in size."); - if (orientation == System.Windows.Controls.Orientation.Vertical) + if (orientation == Orientation.Vertical) return new ScrollBar(orientation, 1, size); else return new ScrollBar(orientation, size, 1); } - private ScrollBar(System.Windows.Controls.Orientation orientation, int width, int height): base(width, height) + private ScrollBar(Orientation orientation, int width, int height): base(width, height) { _initialized = true; _barOrientation = orientation; _sliderCharacter = 219; - if (orientation == System.Windows.Controls.Orientation.Horizontal) + if (orientation == Orientation.Horizontal) { _sliderBarCharacter = 176; _topOrLeftCharacter = 17; @@ -253,7 +253,7 @@ public override void Compose() { if (IsDirty) { - if (_barOrientation == System.Windows.Controls.Orientation.Horizontal) + if (_barOrientation == Orientation.Horizontal) { this.SetCell(0, 0, Theme.Ends.Normal); this.SetGlyph(0, 0, _topOrLeftCharacter); @@ -327,7 +327,7 @@ public override bool ProcessMouse(Input.MouseConsoleState state) if (state.Mouse.LeftClicked) { - if (_barOrientation == System.Windows.Controls.Orientation.Horizontal) + if (_barOrientation == Orientation.Horizontal) { if (mouseControlPosition.X == 0) Value -= Step; @@ -349,7 +349,7 @@ public override bool ProcessMouse(Input.MouseConsoleState state) // When the mouse button is let go, clear the flag. if (state.Mouse.LeftButtonDown) { - if (_barOrientation == System.Windows.Controls.Orientation.Horizontal) + if (_barOrientation == Orientation.Horizontal) { if (mouseControlPosition.Y == 0) if (mouseControlPosition.X == _currentSliderPosition + 1) @@ -379,7 +379,7 @@ public override bool ProcessMouse(Input.MouseConsoleState state) { if (state.Mouse.LeftButtonDown) { - if (_barOrientation == System.Windows.Controls.Orientation.Horizontal) + if (_barOrientation == Orientation.Horizontal) { //if (mouseControlPosition.Y == 0) //{ diff --git a/src/SadConsole.Shared/Extensions/XamlExtensions.cs b/src/SadConsole.Shared/Extensions/XamlExtensions.cs index 495bb67b2..ea669a25b 100644 --- a/src/SadConsole.Shared/Extensions/XamlExtensions.cs +++ b/src/SadConsole.Shared/Extensions/XamlExtensions.cs @@ -1,5 +1,5 @@ #if !SILVERLIGHT && !WPF && !WINDOWS_PHONE -namespace System.Windows +namespace SadConsole { public enum HorizontalAlignment { @@ -18,7 +18,7 @@ public enum VerticalAlignment } } -namespace System.Windows.Controls +namespace SadConsole { public enum Orientation { diff --git a/src/SadConsole.Shared/Themes/InputBoxTheme.cs b/src/SadConsole.Shared/Themes/InputBoxTheme.cs index 2f6c670b7..eea9e379b 100644 --- a/src/SadConsole.Shared/Themes/InputBoxTheme.cs +++ b/src/SadConsole.Shared/Themes/InputBoxTheme.cs @@ -12,7 +12,7 @@ public class InputBoxTheme: ThemePartBase /// The style to use for the carrot. /// [DataMember] - public SadConsole.Effects.ICellEffect CarrotEffect; + public SadConsole.Effects.ICellEffect CaretEffect; /// /// Returns a clone of this object. @@ -25,7 +25,7 @@ public override object Clone() newItem.Focused = this.Focused.Clone(); newItem.MouseOver = this.MouseOver.Clone(); newItem.Disabled = this.Disabled.Clone(); - newItem.CarrotEffect = this.CarrotEffect.Clone(); + newItem.CaretEffect = this.CaretEffect.Clone(); return newItem; } } diff --git a/src/SadConsole.Shared/Themes/Library.cs b/src/SadConsole.Shared/Themes/Library.cs index 749a8c0de..1485ad422 100644 --- a/src/SadConsole.Shared/Themes/Library.cs +++ b/src/SadConsole.Shared/Themes/Library.cs @@ -176,7 +176,7 @@ public Library() InputBoxTheme.Focused = new Cell(ColorHelper.DarkBlue, ColorHelper.DarkGray); InputBoxTheme.MouseOver = new Cell(ColorHelper.DarkBlue, ColorHelper.DarkGray); InputBoxTheme.Disabled = new Cell(ColorHelper.Black, ColorAnsi.White); - InputBoxTheme.CarrotEffect = new Effects.BlinkGlyph() + InputBoxTheme.CaretEffect = new Effects.BlinkGlyph() { GlyphIndex = 95, BlinkSpeed = 0.4f From dd641769ec1a1962167c4d0a7c96ebcecd242107 Mon Sep 17 00:00:00 2001 From: Andy De George Date: Sun, 1 Jul 2018 12:40:55 -0700 Subject: [PATCH 04/44] move to JSON.NET. broken build --- src/SadConsole.Shared/Font.cs | 6 +++ src/SadConsole.Shared/Serializer.cs | 54 +++++++++++++++++++++++++- src/SadConsole/SadConsole.csproj | 5 +++ src/SadConsole/packages.config | 1 + src/SadConsoleFNA/SadConsoleFNA.csproj | 6 +++ src/SadConsoleFNA/packages.config | 4 ++ 6 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 src/SadConsoleFNA/packages.config diff --git a/src/SadConsole.Shared/Font.cs b/src/SadConsole.Shared/Font.cs index fcbdd0e6e..cb700997b 100644 --- a/src/SadConsole.Shared/Font.cs +++ b/src/SadConsole.Shared/Font.cs @@ -289,6 +289,12 @@ public FontMaster(Texture2D fontImage, int glyphWidth, int glyphHeight, int tota ConfigureRects(); } + [Newtonsoft.Json.JsonConstructor] + private FontMaster() + { + + } + #region Methods /// /// After the font has been loaded, (with the , , and fields filled out) this method will create the actual texture. diff --git a/src/SadConsole.Shared/Serializer.cs b/src/SadConsole.Shared/Serializer.cs index 37dab7776..9cbb52a97 100644 --- a/src/SadConsole.Shared/Serializer.cs +++ b/src/SadConsole.Shared/Serializer.cs @@ -46,7 +46,16 @@ public static void Save(T instance, string file, IEnumerable knownTypes var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T), knownTypes); using (var stream = System.IO.File.OpenWrite(file)) - serializer.WriteObject(stream, instance); + //using (var sw = new System.IO.StreamWriter(stream)) + using (var sw = new System.IO.Compression.GZipStream(stream, System.IO.Compression.CompressionMode.Compress)) + { + var bytes = Encoding.UTF32.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(instance, Newtonsoft.Json.Formatting.None)); + + sw.Write(bytes, 0, bytes.Length); + } + + //serializer.WriteObject(stream, instance); + } /// @@ -58,14 +67,55 @@ public static void Save(T instance, string file, IEnumerable knownTypes /// A new object instance. public static T Load(string file, IEnumerable knownTypes = null) { + bool isCompressed = false; + //if (System.IO.File.Exists(file)) //{ Global.SerializerPathHint = System.IO.Path.GetDirectoryName(file); using (var fileObject = Microsoft.Xna.Framework.TitleContainer.OpenStream(file)) { + if (isCompressed) + { + using (var sw = new System.IO.Compression.GZipStream(fileObject, System.IO.Compression.CompressionMode.Decompress)) + { + + using (var stringStream = new System.IO.MemoryStream()) + { + sw.CopyTo(stringStream); + + using (var sr = new System.IO.StreamReader(stringStream)) + { + string content = sr.ReadToEnd(); + + //using (var tr = new System.IO.StringReader(content)) + { + return (T)Newtonsoft.Json.JsonConvert.DeserializeObject(content, typeof(T)); + //return (T)Newtonsoft.Json.JsonSerializer.Create().Deserialize(tr, typeof(T)); + + } + } + } + + + } + } + else + using (var sr = new System.IO.StreamReader(fileObject)) + { + string content = sr.ReadToEnd(); + + //using (var tr = new System.IO.StringReader(content)) + { + return (T)Newtonsoft.Json.JsonConvert.DeserializeObject(content, typeof(T)); + //return (T)Newtonsoft.Json.JsonSerializer.Create().Deserialize(tr, typeof(T)); + + } + } + + + //var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T), knownTypes, int.MaxValue, false, new SerializerSurrogate(), false); var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T), knownTypes); - return (T)serializer.ReadObject(fileObject); } //} diff --git a/src/SadConsole/SadConsole.csproj b/src/SadConsole/SadConsole.csproj index 8bdec1eea..ca990ea96 100644 --- a/src/SadConsole/SadConsole.csproj +++ b/src/SadConsole/SadConsole.csproj @@ -12,6 +12,8 @@ v4.5 512 + + true @@ -37,6 +39,9 @@ ..\..\packages\MonoGame.Framework.WindowsDX.3.6.0.1625\lib\net40\MonoGame.Framework.dll + + ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + diff --git a/src/SadConsole/packages.config b/src/SadConsole/packages.config index 1647dcc69..8134304df 100644 --- a/src/SadConsole/packages.config +++ b/src/SadConsole/packages.config @@ -1,4 +1,5 @@  + \ No newline at end of file diff --git a/src/SadConsoleFNA/SadConsoleFNA.csproj b/src/SadConsoleFNA/SadConsoleFNA.csproj index ad3a67f0a..5c034868c 100644 --- a/src/SadConsoleFNA/SadConsoleFNA.csproj +++ b/src/SadConsoleFNA/SadConsoleFNA.csproj @@ -36,6 +36,9 @@ False ..\..\FNA\library\Release\FNA.dll + + ..\..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + @@ -50,6 +53,9 @@ + + + \ No newline at end of file diff --git a/src/SadConsoleFNA/packages.config b/src/SadConsoleFNA/packages.config new file mode 100644 index 000000000..576275417 --- /dev/null +++ b/src/SadConsoleFNA/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From ff8b161670e9e214d2760b042aa529c7b2dd986f Mon Sep 17 00:00:00 2001 From: Andy De George Date: Sun, 1 Jul 2018 23:33:42 -0700 Subject: [PATCH 05/44] Serialization uses Newtonsoft.JSON; GZip compression supported; Fixes #109 --- ChangeLog.md | 5 +- .../Effects/EffectsManager.cs | 4 +- .../GameHelpers/GameObject.cs | 4 +- src/SadConsole.Shared/GameHelpers/Scene.cs | 4 +- src/SadConsole.Shared/Global.cs | 2 +- src/SadConsole.Shared/Serializer.cs | 93 ++++++------------- src/SadConsole.Shared/Settings.cs | 11 +++ .../Surfaces/AnimatedSurface.cs | 4 +- .../Surfaces/BasicSurface.cs | 4 +- .../Surfaces/LayeredSurface.cs | 9 +- .../Surfaces/NoDrawSurface.cs | 4 +- src/SadConsole.Shared/Surfaces/SurfaceView.cs | 4 +- 12 files changed, 61 insertions(+), 87 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index d909a5546..8161a93f8 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,8 +1,11 @@ -## 06/28/2018 V7.0.0 +## 07/01/2018 V7.0.0 - Draw(SpriteBatch batch, Point position, Point size, Font font) has been removed. - Cell/CellState have a Decorators list which are used to add extra glyph draws to individual cells. - CellDecorator class added that has a color, glyph, and mirror setting. +- SadConsole.Serialization uses Newtonsoft.Json instead of the default .NET classes. +- SadConsole.Serialization supports GZIP compression now. +- Settings.SerializationIsCompressed can be set to true to set all internal save/load to use compression. ## 06/11/2018 diff --git a/src/SadConsole.Shared/Effects/EffectsManager.cs b/src/SadConsole.Shared/Effects/EffectsManager.cs index 9e1d56e16..19ffad623 100644 --- a/src/SadConsole.Shared/Effects/EffectsManager.cs +++ b/src/SadConsole.Shared/Effects/EffectsManager.cs @@ -309,12 +309,12 @@ public static void Save(EffectsManager effectsManager, ISurface surface, string data.Effects.Add(effectData.Effect, effectCellPositions.ToArray()); } - SadConsole.Serializer.Save(data, file); + SadConsole.Serializer.Save(data, file, Settings.SerializationIsCompressed); } public static EffectsManager Load(string file, ISurface surface) { - EffectsManagerSerialized data = Serializer.Load(file); + EffectsManagerSerialized data = Serializer.Load(file, Settings.SerializationIsCompressed); EffectsManager manager = new EffectsManager(surface); foreach (var effect in data.Effects.Keys) diff --git a/src/SadConsole.Shared/GameHelpers/GameObject.cs b/src/SadConsole.Shared/GameHelpers/GameObject.cs index 35a0ed83a..b7bf4aad8 100644 --- a/src/SadConsole.Shared/GameHelpers/GameObject.cs +++ b/src/SadConsole.Shared/GameHelpers/GameObject.cs @@ -177,7 +177,7 @@ public override void Update(TimeSpan timeElapsed) /// The destination file. public void Save(string file) { - Serializer.Save((SerializedTypes.GameObjectSerialized)this, file); + Serializer.Save((SerializedTypes.GameObjectSerialized)this, file, Settings.SerializationIsCompressed); } /// @@ -187,7 +187,7 @@ public void Save(string file) /// public static GameObject Load(string file) { - return Serializer.Load(file); + return Serializer.Load(file, Settings.SerializationIsCompressed); } } diff --git a/src/SadConsole.Shared/GameHelpers/Scene.cs b/src/SadConsole.Shared/GameHelpers/Scene.cs index 14d6a405a..b82fa9385 100644 --- a/src/SadConsole.Shared/GameHelpers/Scene.cs +++ b/src/SadConsole.Shared/GameHelpers/Scene.cs @@ -141,7 +141,7 @@ public override void OnCalculateRenderPosition() /// The destination file. public void Save(string file) { - Serializer.Save((SerializedTypes.SceneSerialized)this, file); + Serializer.Save((SerializedTypes.SceneSerialized)this, file, Settings.SerializationIsCompressed); } /// @@ -153,7 +153,7 @@ public void Save(string file) /// public static Scene Load(string file, ISurface surface, Renderers.ISurfaceRenderer renderer) { - var scene = (Scene)Serializer.Load(file); + var scene = (Scene)Serializer.Load(file, Settings.SerializationIsCompressed); scene.Surface.TextSurface = surface; scene.SurfaceRenderer = renderer; diff --git a/src/SadConsole.Shared/Global.cs b/src/SadConsole.Shared/Global.cs index 1920a87b7..ccdb57f27 100644 --- a/src/SadConsole.Shared/Global.cs +++ b/src/SadConsole.Shared/Global.cs @@ -143,7 +143,7 @@ public static FontMaster LoadFont(string font) //FontPathHint = Path.GetDirectoryName(Path.GetFullPath(font)); try { - var masterFont = SadConsole.Serializer.Load(font); + var masterFont = SadConsole.Serializer.Load(font, false); if (Fonts.ContainsKey(masterFont.Name)) Fonts.Remove(masterFont.Name); diff --git a/src/SadConsole.Shared/Serializer.cs b/src/SadConsole.Shared/Serializer.cs index 9cbb52a97..0016c2210 100644 --- a/src/SadConsole.Shared/Serializer.cs +++ b/src/SadConsole.Shared/Serializer.cs @@ -1,20 +1,9 @@ -using FrameworkColor = Microsoft.Xna.Framework.Color; -using FrameworkPoint = Microsoft.Xna.Framework.Point; -using FrameworkRect = Microsoft.Xna.Framework.Rectangle; -using FrameworkSpriteEffect = Microsoft.Xna.Framework.Graphics.SpriteEffects; - - -namespace SadConsole +namespace SadConsole { using System; - using System.CodeDom; using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.Linq; - using System.Reflection; - using System.Runtime.Serialization; using System.Text; - using System.Threading.Tasks; + using Newtonsoft.Json; /// /// Common serialization tasks for SadConsole. @@ -36,26 +25,30 @@ static Serializer() /// Type of object to serialize /// The object to serialize. /// The file to save the object to. - /// Optional list of known types for serialization. - public static void Save(T instance, string file, IEnumerable knownTypes = null) + /// When true, uses GZIP compression on the json string saved to the + public static void Save(T instance, string file, bool compress) { if (System.IO.File.Exists(file)) System.IO.File.Delete(file); - //var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T), knownTypes, int.MaxValue, false, new SerializerSurrogate(), false); - var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T), knownTypes); - using (var stream = System.IO.File.OpenWrite(file)) - //using (var sw = new System.IO.StreamWriter(stream)) - using (var sw = new System.IO.Compression.GZipStream(stream, System.IO.Compression.CompressionMode.Compress)) { - var bytes = Encoding.UTF32.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(instance, Newtonsoft.Json.Formatting.None)); - - sw.Write(bytes, 0, bytes.Length); + if (compress) + { + using (var sw = new System.IO.Compression.GZipStream(stream, System.IO.Compression.CompressionMode.Compress)) + { + var bytes = Encoding.UTF32.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(instance, Formatting.None, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto })); + sw.Write(bytes, 0, bytes.Length); + } + } + else + { + using (var sw = new System.IO.StreamWriter(stream)) + { + sw.Write(JsonConvert.SerializeObject(instance, Formatting.Indented, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto } )); + } + } } - - //serializer.WriteObject(stream, instance); - } /// @@ -63,64 +56,30 @@ public static void Save(T instance, string file, IEnumerable knownTypes /// /// The type of object to deserialize. /// The file to load from. - /// Known types used during deserialization. + /// When true, indicates that the json should be decompressed with GZIP compression. /// A new object instance. - public static T Load(string file, IEnumerable knownTypes = null) + public static T Load(string file, bool isCompressed) { - bool isCompressed = false; - - //if (System.IO.File.Exists(file)) - //{ Global.SerializerPathHint = System.IO.Path.GetDirectoryName(file); + using (var fileObject = Microsoft.Xna.Framework.TitleContainer.OpenStream(file)) { if (isCompressed) { using (var sw = new System.IO.Compression.GZipStream(fileObject, System.IO.Compression.CompressionMode.Decompress)) { - - using (var stringStream = new System.IO.MemoryStream()) + using (var sr = new System.IO.StreamReader(sw, Encoding.UTF32)) { - sw.CopyTo(stringStream); - - using (var sr = new System.IO.StreamReader(stringStream)) - { - string content = sr.ReadToEnd(); - - //using (var tr = new System.IO.StringReader(content)) - { - return (T)Newtonsoft.Json.JsonConvert.DeserializeObject(content, typeof(T)); - //return (T)Newtonsoft.Json.JsonSerializer.Create().Deserialize(tr, typeof(T)); - - } - } + string value = sr.ReadToEnd(); + return (T)JsonConvert.DeserializeObject(value, typeof(T), new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto }); } - - } } else using (var sr = new System.IO.StreamReader(fileObject)) - { - string content = sr.ReadToEnd(); + return (T)JsonConvert.DeserializeObject(sr.ReadToEnd(), typeof(T), new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto }); - //using (var tr = new System.IO.StringReader(content)) - { - return (T)Newtonsoft.Json.JsonConvert.DeserializeObject(content, typeof(T)); - //return (T)Newtonsoft.Json.JsonSerializer.Create().Deserialize(tr, typeof(T)); - - } - } - - - - //var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T), knownTypes, int.MaxValue, false, new SerializerSurrogate(), false); - var serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T), knownTypes); - return (T)serializer.ReadObject(fileObject); } - //} - - //throw new System.IO.FileNotFoundException("File not found.", file); } } } \ No newline at end of file diff --git a/src/SadConsole.Shared/Settings.cs b/src/SadConsole.Shared/Settings.cs index bcbe89c78..95e1d496f 100644 --- a/src/SadConsole.Shared/Settings.cs +++ b/src/SadConsole.Shared/Settings.cs @@ -5,6 +5,9 @@ namespace SadConsole { + /// + /// Various settings for SadConsole. + /// public static class Settings { /// @@ -59,6 +62,14 @@ public static class Settings /// public static Point WindowMinimumSize { get; set; } = Point.Zero; + /// + /// When set to true, all loading and saving performed by SadConsole uses GZIP. does not use this setting and always runs uncompressed. + /// + public static bool SerializationIsCompressed { get; set; } = false; + + /// + /// Toggles between windowed and fullscreen rendering for SadConsole. + /// public static void ToggleFullScreen() { Global.GraphicsDeviceManager.ApplyChanges(); diff --git a/src/SadConsole.Shared/Surfaces/AnimatedSurface.cs b/src/SadConsole.Shared/Surfaces/AnimatedSurface.cs index 5584636a2..4973c1775 100644 --- a/src/SadConsole.Shared/Surfaces/AnimatedSurface.cs +++ b/src/SadConsole.Shared/Surfaces/AnimatedSurface.cs @@ -303,7 +303,7 @@ public override string ToString() /// The destination file. public void Save(string file) { - Serializer.Save((SerializedTypes.AnimatedSurfaceSerialized)this, file); + Serializer.Save((SerializedTypes.AnimatedSurfaceSerialized)this, file, Settings.SerializationIsCompressed); } /// @@ -313,7 +313,7 @@ public void Save(string file) /// public static AnimatedSurface Load(string file) { - return Serializer.Load(file); + return Serializer.Load(file, Settings.SerializationIsCompressed); } diff --git a/src/SadConsole.Shared/Surfaces/BasicSurface.cs b/src/SadConsole.Shared/Surfaces/BasicSurface.cs index 0b6a68167..2e74d1f86 100644 --- a/src/SadConsole.Shared/Surfaces/BasicSurface.cs +++ b/src/SadConsole.Shared/Surfaces/BasicSurface.cs @@ -356,7 +356,7 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() /// The destination file. public void Save(string file) { - Serializer.Save((SerializedTypes.BasicSurfaceSerialized)this, file); + Serializer.Save((SerializedTypes.BasicSurfaceSerialized)this, file, Settings.SerializationIsCompressed); } /// @@ -366,7 +366,7 @@ public void Save(string file) /// public static BasicSurface Load(string file) { - return Serializer.Load(file); + return Serializer.Load(file, Settings.SerializationIsCompressed); } } } diff --git a/src/SadConsole.Shared/Surfaces/LayeredSurface.cs b/src/SadConsole.Shared/Surfaces/LayeredSurface.cs index f09719c89..c13f7bbc9 100644 --- a/src/SadConsole.Shared/Surfaces/LayeredSurface.cs +++ b/src/SadConsole.Shared/Surfaces/LayeredSurface.cs @@ -17,6 +17,7 @@ public class LayeredSurface: BasicSurface /// A layer. /// [DataContract] + public class Layer { /// @@ -111,7 +112,6 @@ public BasicSurface ToTextSurface(int width, int height, Font font) /// The font. public LayeredSurface(int width, int height, Font font, int layers): this(width, height, font, new Rectangle(0, 0, width, height), layers) { - } /// @@ -399,7 +399,7 @@ public Layer GetLayer(int index) /// Type of . public void Save(string file, Type layerMetadataType) { - Serializer.Save((SerializedTypes.LayeredSurfaceSerialized)this, file, new Type[] { layerMetadataType }); + Serializer.Save((SerializedTypes.LayeredSurfaceSerialized)this, file, Settings.SerializationIsCompressed); } /// @@ -410,7 +410,8 @@ public void Save(string file, Type layerMetadataType) /// The The deserialized surface. public static LayeredSurface Load(string file, Type layerMetadataType) { - return Serializer.Load(file, new Type[] { layerMetadataType }); + //return Serializer.Load(file, new Type[] { layerMetadataType }); + return Serializer.Load(file, Settings.SerializationIsCompressed); } /// @@ -420,7 +421,7 @@ public static LayeredSurface Load(string file, Type layerMetadataType) /// The The deserialized surface. public static new LayeredSurface Load(string file) { - return Serializer.Load(file, new Type[] { typeof(LayerMetadata) }); + return Serializer.Load(file, Settings.SerializationIsCompressed); } /// diff --git a/src/SadConsole.Shared/Surfaces/NoDrawSurface.cs b/src/SadConsole.Shared/Surfaces/NoDrawSurface.cs index 55918d5da..edf92bfbb 100644 --- a/src/SadConsole.Shared/Surfaces/NoDrawSurface.cs +++ b/src/SadConsole.Shared/Surfaces/NoDrawSurface.cs @@ -122,7 +122,7 @@ public override void SetRenderCells() /// The destination file. public new void Save(string file) { - Serializer.Save((SerializedTypes.BasicSurfaceSerialized)this, file); + Serializer.Save((SerializedTypes.BasicSurfaceSerialized)this, file, Settings.SerializationIsCompressed); } /// @@ -132,7 +132,7 @@ public new void Save(string file) /// public static new NoDrawSurface Load(string file) { - return Serializer.Load(file); + return Serializer.Load(file, Settings.SerializationIsCompressed); } } } diff --git a/src/SadConsole.Shared/Surfaces/SurfaceView.cs b/src/SadConsole.Shared/Surfaces/SurfaceView.cs index 6d7ceb9c1..2883c2556 100644 --- a/src/SadConsole.Shared/Surfaces/SurfaceView.cs +++ b/src/SadConsole.Shared/Surfaces/SurfaceView.cs @@ -293,7 +293,7 @@ public void Hydrate(ISurface surface, Rectangle view) /// The destination file. public void Save(string file) { - SadConsole.Serializer.Save((SerializedTypes.SurfaceViewSerialized)this, file); + SadConsole.Serializer.Save((SerializedTypes.SurfaceViewSerialized)this, file, Settings.SerializationIsCompressed); } /// @@ -304,7 +304,7 @@ public void Save(string file) /// A surface view. public static SurfaceView Load(string file, ISurface surfaceHydrate) { - return Serializer.Load(file).ToSurfaceView(surfaceHydrate); + return Serializer.Load(file, Settings.SerializationIsCompressed).ToSurfaceView(surfaceHydrate); } } } From 9cf991706696b120e211cf7185eabe45db42c86f Mon Sep 17 00:00:00 2001 From: Andy De George Date: Mon, 2 Jul 2018 11:31:40 -0700 Subject: [PATCH 06/44] Fix bug with desearlizaing older surfaces. --- src/SadConsole.Shared/SerializedTypes/Cell.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SadConsole.Shared/SerializedTypes/Cell.cs b/src/SadConsole.Shared/SerializedTypes/Cell.cs index 42824d590..c4ef979a0 100644 --- a/src/SadConsole.Shared/SerializedTypes/Cell.cs +++ b/src/SadConsole.Shared/SerializedTypes/Cell.cs @@ -49,7 +49,7 @@ public class CellSerialized var newCell = new Cell(cell.Foreground, cell.Background, cell.Glyph, cell.Mirror) { IsVisible = cell.IsVisible, - Decorators = new List(cell.Decorators) + Decorators = cell.Decorators != null ? new List(cell.Decorators) : new List() }; if (cell.CellState != null) From cb9b688d2f9da45d2b16c9804ac7f30e09886091 Mon Sep 17 00:00:00 2001 From: Andy De George Date: Mon, 2 Jul 2018 11:32:29 -0700 Subject: [PATCH 07/44] Compat fixes for demo project --- src/DemoProject/SharedCode/CustomConsoles/ControlsTest.cs | 6 +++--- .../SharedCode/CustomConsoles/ScrollableConsole.cs | 3 ++- .../SharedCode/CustomConsoles/SerializationTests.cs | 2 +- .../SharedCode/CustomConsoles/ViewsAndSubViews.cs | 2 +- src/DemoProject/SharedCode/Windows/CharacterViewer.cs | 6 +++--- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/DemoProject/SharedCode/CustomConsoles/ControlsTest.cs b/src/DemoProject/SharedCode/CustomConsoles/ControlsTest.cs index eaba79537..9a9c73100 100644 --- a/src/DemoProject/SharedCode/CustomConsoles/ControlsTest.cs +++ b/src/DemoProject/SharedCode/CustomConsoles/ControlsTest.cs @@ -60,7 +60,7 @@ public ControlsTest():base(80, 23) checkbox.Position = new Point(1, 9); Add(checkbox); - var prog = new SadConsole.Controls.ProgressBar(10, 1, System.Windows.HorizontalAlignment.Left); + var prog = new SadConsole.Controls.ProgressBar(10, 1, HorizontalAlignment.Left); prog.Position = new Point(checkbox.Bounds.Left, checkbox.Bounds.Bottom + 1); Add(prog); @@ -79,12 +79,12 @@ public ControlsTest():base(80, 23) listbox.Items.Add("item 8"); Add(listbox); - var slider = SadConsole.Controls.ScrollBar.Create(System.Windows.Controls.Orientation.Horizontal, 20); + var slider = SadConsole.Controls.ScrollBar.Create(Orientation.Horizontal, 20); slider.Position = new Point(25, 7); slider.Maximum = 18; Add(slider); - slider = SadConsole.Controls.ScrollBar.Create(System.Windows.Controls.Orientation.Vertical, 8); + slider = SadConsole.Controls.ScrollBar.Create(Orientation.Vertical, 8); slider.Position = new Point(47, 1); slider.Maximum = 6; Add(slider); diff --git a/src/DemoProject/SharedCode/CustomConsoles/ScrollableConsole.cs b/src/DemoProject/SharedCode/CustomConsoles/ScrollableConsole.cs index 39032f160..31dca4cc0 100644 --- a/src/DemoProject/SharedCode/CustomConsoles/ScrollableConsole.cs +++ b/src/DemoProject/SharedCode/CustomConsoles/ScrollableConsole.cs @@ -5,6 +5,7 @@ using System.Text; using SadConsole.Surfaces; using SadConsole.Input; +using SadConsole; namespace StarterProject.CustomConsoles { @@ -29,7 +30,7 @@ public ScrollableConsole(int width, int height, int bufferHeight) : base(width - textSurface.RenderArea = new Rectangle(0, 0, width, height); - scrollBar = SadConsole.Controls.ScrollBar.Create(System.Windows.Controls.Orientation.Vertical, height); + scrollBar = SadConsole.Controls.ScrollBar.Create(Orientation.Vertical, height); scrollBar.IsEnabled = false; scrollBar.ValueChanged += ScrollBar_ValueChanged; diff --git a/src/DemoProject/SharedCode/CustomConsoles/SerializationTests.cs b/src/DemoProject/SharedCode/CustomConsoles/SerializationTests.cs index ca6717830..f4b73d6f2 100644 --- a/src/DemoProject/SharedCode/CustomConsoles/SerializationTests.cs +++ b/src/DemoProject/SharedCode/CustomConsoles/SerializationTests.cs @@ -116,7 +116,7 @@ private void ButtonSave_Click(object sender, EventArgs e) { if (optionButtonSurface.IsSelected) { - basicSurface.Save("basicsurface.surface"); + //basicSurface.Save("basicsurface.surface"); loadedView.TextSurface = SadConsole.Surfaces.BasicSurface.Load("basicsurface.surface"); } else if (optionButtonView.IsSelected) diff --git a/src/DemoProject/SharedCode/CustomConsoles/ViewsAndSubViews.cs b/src/DemoProject/SharedCode/CustomConsoles/ViewsAndSubViews.cs index 8eb40ad4c..6ee60c319 100644 --- a/src/DemoProject/SharedCode/CustomConsoles/ViewsAndSubViews.cs +++ b/src/DemoProject/SharedCode/CustomConsoles/ViewsAndSubViews.cs @@ -33,7 +33,7 @@ public ViewsAndSubViews() IsVisible = false; UseMouse = true; - //titleAndLine.Print(0, 0, " View and Sub View".Align(System.Windows.HorizontalAlignment.Left, 80), ColorHelper.GreenYellow, ColorHelper.DarkGreen); + //titleAndLine.Print(0, 0, " View and Sub View".Align(HorizontalAlignment.Left, 80), ColorHelper.GreenYellow, ColorHelper.DarkGreen); SadConsole.Shapes.Line line = new SadConsole.Shapes.Line(); line.UseStartingCell = false; line.UseEndingCell = false; diff --git a/src/DemoProject/SharedCode/Windows/CharacterViewer.cs b/src/DemoProject/SharedCode/Windows/CharacterViewer.cs index 63f8b377e..06a133bab 100644 --- a/src/DemoProject/SharedCode/Windows/CharacterViewer.cs +++ b/src/DemoProject/SharedCode/Windows/CharacterViewer.cs @@ -34,13 +34,13 @@ public CharacterViewer() //DefaultShowLocation = StartupLocation.CenterScreen; //Fill(Color.White, Color.Black, 0, null); Title = (char)198 + "Character" + (char)198; - TitleAlignment = System.Windows.HorizontalAlignment.Left; - //SetTitle(" Characters ", System.Windows.HorizontalAlignment.Center, Color.Blue, Color.LightGray); + TitleAlignment = HorizontalAlignment.Left; + //SetTitle(" Characters ", HorizontalAlignment.Center, Color.Blue, Color.LightGray); CloseOnESC = true; UsePixelPositioning = true; // CHARACTER SCROLL - _charScrollBar = ScrollBar.Create(System.Windows.Controls.Orientation.Vertical, 16); + _charScrollBar = ScrollBar.Create(Orientation.Vertical, 16); _charScrollBar.Position = new Point(17, 1); _charScrollBar.Name = "ScrollBar"; _charScrollBar.Maximum = textSurface.Font.Rows - 16; From 19ca1bce6dd4589b232baa6788d7ba33fc5e5ac2 Mon Sep 17 00:00:00 2001 From: Andy De George Date: Mon, 2 Jul 2018 11:33:09 -0700 Subject: [PATCH 08/44] Another fix for deserialize older console --- src/SadConsole.Shared/CellState.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SadConsole.Shared/CellState.cs b/src/SadConsole.Shared/CellState.cs index 0becff0db..c21343833 100644 --- a/src/SadConsole.Shared/CellState.cs +++ b/src/SadConsole.Shared/CellState.cs @@ -66,7 +66,7 @@ public CellState(Color foreground, Color background, int glyph, SpriteEffects mi Glyph = glyph; Mirror = mirror; IsVisible = isVisible; - Decorators = new List(decorators).ToArray(); + Decorators = decorators == null ? new CellDecorator[] { } : new List(decorators).ToArray(); } /// From 80084ec670d4885b426b2e0d26b8788b563cff6e Mon Sep 17 00:00:00 2001 From: Andy De George Date: Mon, 2 Jul 2018 11:33:31 -0700 Subject: [PATCH 09/44] Dependency for newtonsoft json on UWP --- src/SadConsole.Universal/project.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/SadConsole.Universal/project.json b/src/SadConsole.Universal/project.json index 41cf9171c..520d78c7d 100644 --- a/src/SadConsole.Universal/project.json +++ b/src/SadConsole.Universal/project.json @@ -1,10 +1,11 @@ { "dependencies": { "Microsoft.NETCore.UniversalWindowsPlatform": "5.3.1", - "MonoGame.Framework.WindowsUniversal": "3.6.0.1625" + "MonoGame.Framework.WindowsUniversal": "3.6.0.1625", + "Newtonsoft.Json": "11.0.2" }, "frameworks": { - "uap10.0": {} + "uap10.0.10240": {} }, "runtimes": { "win10-arm": {}, From de669a6db7ad9584efe2d36f95c5c83a754acf0e Mon Sep 17 00:00:00 2001 From: Andy De George Date: Sat, 7 Jul 2018 15:02:36 -0700 Subject: [PATCH 10/44] Started work on extended character set --- Fonts/IBM8x16_NoPadding_extended.pdn | Bin 0 -> 16169 bytes Fonts/IBM8x16_NoPadding_extended.png | Bin 0 -> 4752 bytes Fonts/IBM_ext.font | 1 + 3 files changed, 1 insertion(+) create mode 100644 Fonts/IBM8x16_NoPadding_extended.pdn create mode 100644 Fonts/IBM8x16_NoPadding_extended.png create mode 100644 Fonts/IBM_ext.font diff --git a/Fonts/IBM8x16_NoPadding_extended.pdn b/Fonts/IBM8x16_NoPadding_extended.pdn new file mode 100644 index 0000000000000000000000000000000000000000..7f5507b2b51ee13609cb964044c5f4359fcc9cbd GIT binary patch literal 16169 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 literal 0 HcmV?d00001 diff --git a/Fonts/IBM_ext.font b/Fonts/IBM_ext.font new file mode 100644 index 000000000..b13bdd3e2 --- /dev/null +++ b/Fonts/IBM_ext.font @@ -0,0 +1 @@ +{"FilePath":"IBM8x16_NoPadding_extended.png","GlyphHeight":16,"GlyphPadding":0,"GlyphWidth":8,"Name":"IBM-extended","SolidGlyphIndex":219} \ No newline at end of file From 856a549ef7c4c7a1327e13f53b9db023e3160d83 Mon Sep 17 00:00:00 2001 From: Andy De George Date: Sat, 7 Jul 2018 15:48:21 -0700 Subject: [PATCH 11/44] Added random glyph to string parser glyph command. Fixes #35 --- .../StringParser/ParseCommandGlyph.cs | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/SadConsole.Shared/StringParser/ParseCommandGlyph.cs b/src/SadConsole.Shared/StringParser/ParseCommandGlyph.cs index 087f67883..f9911c7ad 100644 --- a/src/SadConsole.Shared/StringParser/ParseCommandGlyph.cs +++ b/src/SadConsole.Shared/StringParser/ParseCommandGlyph.cs @@ -13,24 +13,42 @@ class ParseCommandSetGlyph : ParseCommandBase { public int Counter; public char Glyph; + public bool RandomGlyph; + public int RandomGlyphMin; + public int RandomGlyphMax; public ParseCommandSetGlyph(string parameters) { - string[] parts = parameters.Split(new char[] { ':' }, 2); + string[] parts = parameters.Split(new char[] { ':' }, 3); + // Random glyph requested + if (parts.Length == 3) + { + RandomGlyph = true; + if (parts[0] == "*") + Counter = -1; + else + Counter = int.Parse(parts[0]); + + RandomGlyphMin = int.Parse(parts[1]); + RandomGlyphMax = int.Parse(parts[2]); + } // Count and glyph type provided - if (parts.Length == 2) + else if (parts.Length == 2) { if (parts[1] == "*") Counter = -1; else Counter = int.Parse(parts[1]); + + Glyph = (char)int.Parse(parts[0]); } else + { Counter = 1; + Glyph = (char)int.Parse(parts[0]); + } - // Get character - Glyph = (char)int.Parse(parts[0]); // No exceptions, set the type CommandType = CommandTypes.Glyph; @@ -38,7 +56,10 @@ public ParseCommandSetGlyph(string parameters) public override void Build(ref ColoredGlyph glyphState, ColoredGlyph[] glyphString, int surfaceIndex, ISurface surface, SurfaceEditor editor, ref int stringIndex, string processedString, ParseCommandStacks commandStack) { - glyphState.GlyphCharacter = Glyph; + if (RandomGlyph) + glyphState.GlyphCharacter = (char)SadConsole.Global.Random.Next(RandomGlyphMin, RandomGlyphMax); + else + glyphState.GlyphCharacter = Glyph; if (Counter != -1) { From cdc1f4bb2372d498d0d6b7b84f332778d3f4ed04 Mon Sep 17 00:00:00 2001 From: Andy De George Date: Sun, 8 Jul 2018 23:27:04 -0700 Subject: [PATCH 12/44] Cursor draws in correct position when RenderView changes. Fixes #74 --- src/SadConsole.Shared/ConsoleTypes/Console.cs | 16 ++---------- src/SadConsole.Shared/DrawCalls.cs | 25 ------------------- 2 files changed, 2 insertions(+), 39 deletions(-) diff --git a/src/SadConsole.Shared/ConsoleTypes/Console.cs b/src/SadConsole.Shared/ConsoleTypes/Console.cs index 3fc9a723f..7f8885600 100644 --- a/src/SadConsole.Shared/ConsoleTypes/Console.cs +++ b/src/SadConsole.Shared/ConsoleTypes/Console.cs @@ -557,20 +557,8 @@ protected virtual void OnFocused() protected virtual void OnBeforeRenderTint(SpriteBatch batch) { if (VirtualCursor.IsVisible) - { - // Bug - Virtual cursor position index is incorrectly positioned in the render area when the render area - // is smaller than width. - // Render - - int virtualCursorLocationIndex = BasicSurface.GetIndexFromPoint( - new Point(VirtualCursor.Position.X - TextSurface.RenderArea.Left, - VirtualCursor.Position.Y - TextSurface.RenderArea.Top), TextSurface.RenderArea.Width); - - if (virtualCursorLocationIndex >= 0 && virtualCursorLocationIndex < textSurface.RenderRects.Length) - { - VirtualCursor.Render(batch, textSurface.Font, textSurface.RenderRects[virtualCursorLocationIndex]); - } - } + if (textSurface.RenderArea.Contains(virtualCursor.Position)) + VirtualCursor.Render(batch, textSurface.Font, textSurface.Font.GetRenderRect(virtualCursor.Position.X - textSurface.RenderArea.Location.X, virtualCursor.Position.Y - textSurface.RenderArea.Location.Y)); } /// diff --git a/src/SadConsole.Shared/DrawCalls.cs b/src/SadConsole.Shared/DrawCalls.cs index de6c25e89..ac3df873a 100644 --- a/src/SadConsole.Shared/DrawCalls.cs +++ b/src/SadConsole.Shared/DrawCalls.cs @@ -78,29 +78,4 @@ public void Draw() Global.SpriteBatch.Draw(Global.FontDefault.FontImage, Rectangle, Global.FontDefault.SolidGlyphRectangle, Shade); } } - - public class DrawCallCursor : IDrawCall - { - public Console Console; - public Vector2 Position; - - public DrawCallCursor(Console console) - { - Console = console; - } - - public void Draw() - { - int virtualCursorLocationIndex = BasicSurface.GetIndexFromPoint( - new Point(Console.VirtualCursor.Position.X - Console.TextSurface.RenderArea.Left, - Console.VirtualCursor.Position.Y - Console.TextSurface.RenderArea.Top), Console.TextSurface.RenderArea.Width); - - if (virtualCursorLocationIndex >= 0 && virtualCursorLocationIndex < Console.TextSurface.RenderRects.Length) - { - var rect = Console.TextSurface.RenderRects[virtualCursorLocationIndex]; - rect.Offset(Console.Position.ConsoleLocationToPixel(Console.TextSurface.Font.Size.X, Console.TextSurface.Font.Size.Y)); - Console.VirtualCursor.Render(Global.SpriteBatch, Console.TextSurface.Font, rect); - } - } - } } From 9d648e35a22212e1bba900d14eef8e75ead5ca9e Mon Sep 17 00:00:00 2001 From: Andy De George Date: Mon, 9 Jul 2018 22:10:52 -0700 Subject: [PATCH 13/44] Added SetGlyph overload with decorators --- src/SadConsole.Shared/ColoredGlyph.cs | 2 +- .../Surfaces/SurfaceEditor.cs | 28 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/SadConsole.Shared/ColoredGlyph.cs b/src/SadConsole.Shared/ColoredGlyph.cs index 15816ab5c..69333d25c 100644 --- a/src/SadConsole.Shared/ColoredGlyph.cs +++ b/src/SadConsole.Shared/ColoredGlyph.cs @@ -50,7 +50,7 @@ public new int Glyph /// Creates a new colored glyph based on the provided cell. /// /// The cell. - public ColoredGlyph(Cell cell) : base(cell.Foreground, cell.Background, cell.Glyph) + public ColoredGlyph(Cell cell) : base(cell.Foreground, cell.Background, cell.Glyph, cell.Mirror) { GlyphCharacter = (char)cell.Glyph; } diff --git a/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs b/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs index 549e858de..7c0a0b482 100644 --- a/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs +++ b/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs @@ -198,8 +198,9 @@ public void SetGlyph(int x, int y, int glyph) textSurface.Cells[y * textSurface.Width + x].Glyph = glyph; textSurface.IsDirty = true; } + /// - /// Changes the glyph, foreground, and background of a cell. + /// Changes the glyph and foreground of a cell. /// /// The x location of the cell. /// The y location of the cell. @@ -213,6 +214,7 @@ public void SetGlyph(int x, int y, int glyph, Color foreground) textSurface.Cells[index].Glyph = glyph; textSurface.IsDirty = true; } + /// /// Changes the glyph, foreground, and background of a cell. /// @@ -252,6 +254,30 @@ public void SetGlyph(int x, int y, int glyph, Color foreground, Color background textSurface.IsDirty = true; } + /// + /// Changes the glyph, foreground, background, and effect of a cell. + /// + /// The x location of the cell. + /// The y location of the cell. + /// The desired glyph. + /// The desired foreground. + /// The desired background. + /// Sets how the glyph will be mirrored. + /// Decorators to set on the cell. Will clear existing decorators first. + public void SetGlyph(int x, int y, int glyph, Color foreground, Color background, SpriteEffects mirror, IEnumerable decorators) + { + int index = y * textSurface.Width + x; + + textSurface.Cells[index].Background = background; + textSurface.Cells[index].Foreground = foreground; + textSurface.Cells[index].Glyph = glyph; + textSurface.Cells[index].Mirror = mirror; + textSurface.Cells[index].Decorators.Clear(); + textSurface.Cells[index].Decorators.AddRange(decorators); + + textSurface.IsDirty = true; + } + /// /// Gets the glyph of a specified cell. /// From 6fe0746f5f6037779ab5e3cfd2acea8b0431b05e Mon Sep 17 00:00:00 2001 From: Andy De George Date: Thu, 12 Jul 2018 20:16:17 -0700 Subject: [PATCH 14/44] Move decorator to font; add id to decorator --- src/SadConsole.Shared/CellDecorator.cs | 22 ++++++++++++++++++++++ src/SadConsole.Shared/Font.cs | 8 +++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/SadConsole.Shared/CellDecorator.cs b/src/SadConsole.Shared/CellDecorator.cs index da7bb0d98..2167a12a8 100644 --- a/src/SadConsole.Shared/CellDecorator.cs +++ b/src/SadConsole.Shared/CellDecorator.cs @@ -36,6 +36,12 @@ public struct CellDecorator : IEquatable [DataMember] public readonly SpriteEffects Mirror; + /// + /// Identifier assigned by a font. + /// + [DataMember] + public readonly int Id; + /// /// Creates a new decorator with the specified colors, glyph, visiblity, and mirror settings. /// @@ -47,6 +53,22 @@ public CellDecorator(Color color, int glyph, SpriteEffects mirror) Color = color; Glyph = glyph; Mirror = mirror; + Id = -1; + } + + /// + /// Creates a new decorator with the specified colors, glyph, visiblity, and mirror settings. + /// + /// Foreground color. + /// Glyph value. + /// Mirror setting. + /// Id assigned by a font. + internal CellDecorator(Color color, int glyph, SpriteEffects mirror, int id) + { + Color = color; + Glyph = glyph; + Mirror = mirror; + Id = id; } /// diff --git a/src/SadConsole.Shared/Font.cs b/src/SadConsole.Shared/Font.cs index cb700997b..865757742 100644 --- a/src/SadConsole.Shared/Font.cs +++ b/src/SadConsole.Shared/Font.cs @@ -105,7 +105,7 @@ public enum FontSizes /// The that created this instance. /// public FontMaster Master { get; private set; } - + internal Font() { } internal Font(FontMaster masterFont, FontSizes fontMultiple) @@ -270,6 +270,12 @@ public class FontMaster /// public Rectangle[] GlyphIndexRects; + + /// + /// Standard decorators used by your app. + /// + public Dictionary Decorators { get; } = new Dictionary(); + /// /// Creates a SadConsole font using an existing image. /// From a0cc702558045fdbdcf111ac7fc2fd215463dc1f Mon Sep 17 00:00:00 2001 From: Andy De George Date: Mon, 16 Jul 2018 21:37:11 -0700 Subject: [PATCH 15/44] Cell decorators is a plain array now. Font/Master split into single files. --- src/SadConsole.Shared/Cell.cs | 2 +- src/SadConsole.Shared/CellDecorator.cs | 2 +- src/SadConsole.Shared/Font.cs | 178 ------------- src/SadConsole.Shared/FontMaster.cs | 239 ++++++++++++++++++ .../SadConsole.Shared.projitems | 1 + .../Surfaces/SurfaceEditor.cs | 38 ++- 6 files changed, 278 insertions(+), 182 deletions(-) create mode 100644 src/SadConsole.Shared/FontMaster.cs diff --git a/src/SadConsole.Shared/Cell.cs b/src/SadConsole.Shared/Cell.cs index 94856010d..6cb44e405 100644 --- a/src/SadConsole.Shared/Cell.cs +++ b/src/SadConsole.Shared/Cell.cs @@ -23,7 +23,7 @@ public class Cell /// Modifies the look of a cell with additional character. /// [DataMember] - public List Decorators { get; internal set; } = new List(); + public CellDecorator[] Decorators { get; internal set; } = new CellDecorator[0]; /// /// The foreground color of this cell. diff --git a/src/SadConsole.Shared/CellDecorator.cs b/src/SadConsole.Shared/CellDecorator.cs index 2167a12a8..6166ea02e 100644 --- a/src/SadConsole.Shared/CellDecorator.cs +++ b/src/SadConsole.Shared/CellDecorator.cs @@ -16,7 +16,7 @@ public struct CellDecorator : IEquatable /// /// An empty cell decorator. /// - public static CellDecorator Empty { get; } + public static CellDecorator Empty => default; /// /// Foreground color of the decorator. diff --git a/src/SadConsole.Shared/Font.cs b/src/SadConsole.Shared/Font.cs index 865757742..551be9f9f 100644 --- a/src/SadConsole.Shared/Font.cs +++ b/src/SadConsole.Shared/Font.cs @@ -2,8 +2,6 @@ using Microsoft.Xna.Framework.Graphics; using System; -using System.Collections.Generic; -using System.Runtime.Serialization; namespace SadConsole { @@ -200,180 +198,4 @@ public Point GetWorldPosition(Point position) } - - /// - /// The font stored by the engine. Used to generate the type used by the engine. - /// - [DataContract] - public class FontMaster - { - private Dictionary cachedFonts = new Dictionary(); - - /// - /// The name of this font family. - /// - [DataMember] - public string Name { get; set; } - - /// - /// The name of the image file as defined in the .font file. - /// - [DataMember] - public string FilePath { get; set; } - - /// - /// The path to the file per . - /// - public string LoadedFilePath { get; private set; } - - /// - /// The height of each glyph in pixels. - /// - [DataMember] - public int GlyphHeight { get; set; } - - /// - /// The width of each glyph in pixels. - /// - [DataMember] - public int GlyphWidth { get; set; } - - /// - /// The amount of pixels between glyphs. - /// - [DataMember] - public int GlyphPadding { get; set; } - - /// - /// Which glyph index is considered completely solid. Used for shading. - /// - [DataMember] - public int SolidGlyphIndex { get; set; } = 219; - - /// - /// The amount of columns the font uses, defaults to 16. - /// - [DataMember] - public int Columns { get; set; } = 16; - - /// - /// The total rows in the font. - /// - public int Rows { get { return Image.Height / (GlyphHeight + GlyphPadding); } } - /// - /// The texture used by the font. - /// - public Texture2D Image { get; private set; } - - /// - /// A cached array of rectangles of individual glyphs. - /// - public Rectangle[] GlyphIndexRects; - - - /// - /// Standard decorators used by your app. - /// - public Dictionary Decorators { get; } = new Dictionary(); - - /// - /// Creates a SadConsole font using an existing image. - /// - /// The image for the font. - /// The width of each glyph. - /// The height of each glyph. - /// Glyph columns in the font texture, defaults to 16. - /// Pixels between each glyph, defaults to 0. - public FontMaster(Texture2D fontImage, int glyphWidth, int glyphHeight, int totalColumns = 16, int glyphPadding = 0) - { - Image = fontImage; - GlyphWidth = glyphWidth; - GlyphHeight = glyphHeight; - Columns = totalColumns; - GlyphPadding = glyphPadding; - - ConfigureRects(); - } - - [Newtonsoft.Json.JsonConstructor] - private FontMaster() - { - - } - -#region Methods - /// - /// After the font has been loaded, (with the , , and fields filled out) this method will create the actual texture. - /// - public void Generate() - { - cachedFonts = new Dictionary(); - - LoadedFilePath = System.IO.Path.Combine(Global.SerializerPathHint, FilePath); - - - using (System.IO.Stream fontStream = TitleContainer.OpenStream(LoadedFilePath)) - Image = Texture2D.FromStream(Global.GraphicsDevice, fontStream); - - ConfigureRects(); - } - - /// - /// Builds the array based on the current font settings. - /// - public void ConfigureRects() - { - GlyphIndexRects = new Rectangle[Rows * Columns]; - - for (int i = 0; i < GlyphIndexRects.Length; i++) - { - var cx = i % Columns; - var cy = i / Columns; - - if (GlyphPadding != 0) - GlyphIndexRects[i] = new Rectangle((cx * GlyphWidth) + ((cx + 1) * GlyphPadding), - (cy * GlyphHeight) + ((cy + 1) * GlyphPadding), GlyphWidth, GlyphHeight); - else - GlyphIndexRects[i] = new Rectangle(cx * GlyphWidth, cy * GlyphHeight, GlyphWidth, GlyphHeight); - } - } - - /// - /// Gets a sized font. - /// - /// How much to multiple the font size by. - /// A font. - public Font GetFont(Font.FontSizes multiple) - { - if (cachedFonts.ContainsKey(multiple)) - return cachedFonts[multiple]; - - var font = new Font(this, multiple); - cachedFonts.Add(multiple, font); - return font; - } - - ///// - ///// Not used... I think I was going to do something with this... - ///// - //private void GetImageMask() - //{ - // Texture2D texture = new Texture2D(Engine.Device, Image.Width, Image.Height, - // false, SurfaceFormat.Color); - // Color[] newPixels = new Color[texture.Width * texture.Height]; - // Color[] oldPixels = new Color[texture.Width * texture.Height]; - // texture.GetData(newPixels); - // Image.GetData(oldPixels); - //} - - [OnDeserialized] - private void AfterDeserialized(System.Runtime.Serialization.StreamingContext context) - { - if (Columns == 0) - Columns = 16; - - Generate(); - } -#endregion - } } diff --git a/src/SadConsole.Shared/FontMaster.cs b/src/SadConsole.Shared/FontMaster.cs new file mode 100644 index 000000000..8ce030f8c --- /dev/null +++ b/src/SadConsole.Shared/FontMaster.cs @@ -0,0 +1,239 @@ +using System.Collections.Generic; +using System.Runtime.Serialization; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace SadConsole +{ + /// + /// The font stored by the engine. Used to generate the type used by the engine. + /// + [DataContract] + public class FontMaster + { + private Dictionary cachedFonts = new Dictionary(); + + /// + /// The name of this font family. + /// + [DataMember] + public string Name { get; set; } + + /// + /// The name of the image file as defined in the .font file. + /// + [DataMember] + public string FilePath { get; set; } + + /// + /// The path to the file per . + /// + public string LoadedFilePath { get; private set; } + + /// + /// The height of each glyph in pixels. + /// + [DataMember] + public int GlyphHeight { get; set; } + + /// + /// The width of each glyph in pixels. + /// + [DataMember] + public int GlyphWidth { get; set; } + + /// + /// The amount of pixels between glyphs. + /// + [DataMember] + public int GlyphPadding { get; set; } + + /// + /// Which glyph index is considered completely solid. Used for shading. + /// + [DataMember] + public int SolidGlyphIndex { get; set; } = 219; + + /// + /// The amount of columns the font uses, defaults to 16. + /// + [DataMember] + public int Columns { get; set; } = 16; + + /// + /// True when the font supports SadConsole extended decorators; otherwise false. + /// + [DataMember] + public bool IsSadExtended { get; set; } + + /// + /// The total rows in the font. + /// + public int Rows { get { return Image.Height / (GlyphHeight + GlyphPadding); } } + /// + /// The texture used by the font. + /// + public Texture2D Image { get; private set; } + + /// + /// A cached array of rectangles of individual glyphs. + /// + public Rectangle[] GlyphIndexRects; + + + /// + /// Standard decorators used by your app. + /// + [DataMember] + public Dictionary Decorators { get; } = new Dictionary(); + + /// + /// Creates a SadConsole font using an existing image. + /// + /// The image for the font. + /// The width of each glyph. + /// The height of each glyph. + /// Glyph columns in the font texture, defaults to 16. + /// Pixels between each glyph, defaults to 0. + public FontMaster(Texture2D fontImage, int glyphWidth, int glyphHeight, int totalColumns = 16, int glyphPadding = 0) + { + Image = fontImage; + GlyphWidth = glyphWidth; + GlyphHeight = glyphHeight; + Columns = totalColumns; + GlyphPadding = glyphPadding; + + ConfigureRects(); + } + + [Newtonsoft.Json.JsonConstructor] + private FontMaster() + { + + } + + /// + /// Gets a by name from the dictionary. + /// + /// The name of the decorator to get. + /// The color to apply to the decorator. + /// The decorator instance. + /// If the decorator does not exist, is returned. + public CellDecorator GetDecorator(string name, Color color) + { + if (Decorators.ContainsKey(name)) + return Decorators[name].CreateCellDecorator(color); + + return CellDecorator.Empty; + } + + /// + /// Represents a decorator (glyph and mirror) defined by a font. + /// + public class CellDecoratorDefinition + { + /// + /// The glyph of the decorator. + /// + public int Glyph { get; } + + /// + /// The mirror effect of the decorator. + /// + public SpriteEffects Mirror { get; } + + /// + /// Creates a new cell decorator instance. + /// + /// + /// + public CellDecoratorDefinition(int glyph, SpriteEffects mirror) + { + Glyph = glyph; + Mirror = mirror; + } + + /// + /// Creates a from this definition. + /// + /// The color of the decorator. + /// A new decorator instance. + public CellDecorator CreateCellDecorator(Color foreground) => new CellDecorator(foreground, Glyph, Mirror); + } + + #region Methods + /// + /// After the font has been loaded, (with the , , and fields filled out) this method will create the actual texture. + /// + public void Generate() + { + cachedFonts = new Dictionary(); + + LoadedFilePath = System.IO.Path.Combine(Global.SerializerPathHint, FilePath); + + + using (System.IO.Stream fontStream = TitleContainer.OpenStream(LoadedFilePath)) + Image = Texture2D.FromStream(Global.GraphicsDevice, fontStream); + + ConfigureRects(); + } + + /// + /// Builds the array based on the current font settings. + /// + public void ConfigureRects() + { + GlyphIndexRects = new Rectangle[Rows * Columns]; + + for (int i = 0; i < GlyphIndexRects.Length; i++) + { + var cx = i % Columns; + var cy = i / Columns; + + if (GlyphPadding != 0) + GlyphIndexRects[i] = new Rectangle((cx * GlyphWidth) + ((cx + 1) * GlyphPadding), + (cy * GlyphHeight) + ((cy + 1) * GlyphPadding), GlyphWidth, GlyphHeight); + else + GlyphIndexRects[i] = new Rectangle(cx * GlyphWidth, cy * GlyphHeight, GlyphWidth, GlyphHeight); + } + } + + /// + /// Gets a sized font. + /// + /// How much to multiple the font size by. + /// A font. + public Font GetFont(Font.FontSizes multiple) + { + if (cachedFonts.ContainsKey(multiple)) + return cachedFonts[multiple]; + + var font = new Font(this, multiple); + cachedFonts.Add(multiple, font); + return font; + } + + ///// + ///// Not used... I think I was going to do something with this... + ///// + //private void GetImageMask() + //{ + // Texture2D texture = new Texture2D(Engine.Device, Image.Width, Image.Height, + // false, SurfaceFormat.Color); + // Color[] newPixels = new Color[texture.Width * texture.Height]; + // Color[] oldPixels = new Color[texture.Width * texture.Height]; + // texture.GetData(newPixels); + // Image.GetData(oldPixels); + //} + + [OnDeserialized] + private void AfterDeserialized(System.Runtime.Serialization.StreamingContext context) + { + if (Columns == 0) + Columns = 16; + + Generate(); + } + #endregion + } +} \ No newline at end of file diff --git a/src/SadConsole.Shared/SadConsole.Shared.projitems b/src/SadConsole.Shared/SadConsole.Shared.projitems index fa6f2fec5..208839a36 100644 --- a/src/SadConsole.Shared/SadConsole.Shared.projitems +++ b/src/SadConsole.Shared/SadConsole.Shared.projitems @@ -66,6 +66,7 @@ + diff --git a/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs b/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs index 7c0a0b482..b7cacb16d 100644 --- a/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs +++ b/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs @@ -3,7 +3,9 @@ using SpriteEffects = Microsoft.Xna.Framework.Graphics.SpriteEffects; using System; +using System.Collections; using System.Collections.Generic; +using System.Linq; using System.Text; using SadConsole.Effects; using System.Runtime.Serialization; @@ -266,14 +268,18 @@ public void SetGlyph(int x, int y, int glyph, Color foreground, Color background /// Decorators to set on the cell. Will clear existing decorators first. public void SetGlyph(int x, int y, int glyph, Color foreground, Color background, SpriteEffects mirror, IEnumerable decorators) { - int index = y * textSurface.Width + x; + var index = y * textSurface.Width + x; textSurface.Cells[index].Background = background; textSurface.Cells[index].Foreground = foreground; textSurface.Cells[index].Glyph = glyph; textSurface.Cells[index].Mirror = mirror; textSurface.Cells[index].Decorators.Clear(); - textSurface.Cells[index].Decorators.AddRange(decorators); + + if (decorators != null) + textSurface.Cells[index].Decorators = decorators.ToArray(); + else + textSurface.Cells[index].Decorators = new CellDecorator[0]; textSurface.IsDirty = true; } @@ -424,6 +430,34 @@ public void SetMirror(int x, int y, SpriteEffects mirror) textSurface.IsDirty = true; } + /// + /// Sets the decorator of one or more cells. + /// + /// The x coordinate of the cell. + /// The y coordinate of the cell. + /// The count of cells to use from the x,y cooridnate (inclusive). + /// The decorators. Use null to clear. + public void SetDecorator(int x, int y, int count, params CellDecorator[] decorators) + => SetDecorator(y * textSurface.Width + x, count, decorators); + + /// + /// Sets the decorator of one or more cells. + /// + /// The index of the cell to start applying. + /// The count of cells to use from the index (inclusive). + /// The decorators. Use null to clear. + public void SetDecorator(int index, int count, params CellDecorator[] decorators) + { + if (!IsValidCell(index) || index + count >= textSurface.Cells.Length) return; + for (var i = index; i < index + count; i++) + { + textSurface[i].Decorators = new CellDecorator[decorators.Length]; + + if(decorators.Length != 0) + decorators.CopyTo(textSurface[i].Decorators, 0) + } + } + /// /// Fills a console with random colors and glyphs. /// From 7d0a79b68cdde24eec07cb8be81b47c911698793 Mon Sep 17 00:00:00 2001 From: Andy De George Date: Mon, 16 Jul 2018 21:38:18 -0700 Subject: [PATCH 16/44] Update sadconsole to framework 4.6.1 (standard 2.0) --- src/SadConsole/SadConsole.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/SadConsole/SadConsole.csproj b/src/SadConsole/SadConsole.csproj index ca990ea96..6f6799415 100644 --- a/src/SadConsole/SadConsole.csproj +++ b/src/SadConsole/SadConsole.csproj @@ -9,7 +9,7 @@ Properties SadConsole SadConsole - v4.5 + v4.6.1 512 @@ -25,6 +25,7 @@ 4 true bin\Debug\SadConsole.xml + 7.1 pdbonly @@ -34,6 +35,7 @@ prompt 4 bin\Release\SadConsole.xml + 7.1 From 81e49f766ec000f50e75a9638e1815bb587c7232 Mon Sep 17 00:00:00 2001 From: Andy De George Date: Mon, 16 Jul 2018 21:39:30 -0700 Subject: [PATCH 17/44] Fixed missing ; --- src/SadConsole.Shared/Surfaces/SurfaceEditor.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs b/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs index b7cacb16d..2f2d2d2bd 100644 --- a/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs +++ b/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs @@ -274,12 +274,7 @@ public void SetGlyph(int x, int y, int glyph, Color foreground, Color background textSurface.Cells[index].Foreground = foreground; textSurface.Cells[index].Glyph = glyph; textSurface.Cells[index].Mirror = mirror; - textSurface.Cells[index].Decorators.Clear(); - - if (decorators != null) - textSurface.Cells[index].Decorators = decorators.ToArray(); - else - textSurface.Cells[index].Decorators = new CellDecorator[0]; + textSurface.Cells[index].Decorators = decorators != null ? decorators.ToArray() : new CellDecorator[0]; textSurface.IsDirty = true; } @@ -453,8 +448,8 @@ public void SetDecorator(int index, int count, params CellDecorator[] decorators { textSurface[i].Decorators = new CellDecorator[decorators.Length]; - if(decorators.Length != 0) - decorators.CopyTo(textSurface[i].Decorators, 0) + if (decorators.Length != 0) + decorators.CopyTo(textSurface[i].Decorators, 0); } } From 89d08e6b13fb7b50bcdcf650f9cd9002c43f7829 Mon Sep 17 00:00:00 2001 From: Andy De George Date: Mon, 16 Jul 2018 22:20:30 -0700 Subject: [PATCH 18/44] Fixed compile error for cell. Set lang to c#7.2. --- SadConsole - Desktop.sln | 49 +++++++++++++++++++ src/SadConsole.Shared/Cell.cs | 13 ++--- .../Renderers/ControlsConsoleRenderer.cs | 2 +- .../Renderers/LayeredSurfaceRenderer.cs | 2 +- .../Renderers/SurfaceRenderer.cs | 2 +- src/SadConsole.Shared/SerializedTypes/Cell.cs | 4 +- src/SadConsole/SadConsole.csproj | 4 +- src/SadConsoleFNA/SadConsoleFNA.csproj | 2 + 8 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 SadConsole - Desktop.sln diff --git a/SadConsole - Desktop.sln b/SadConsole - Desktop.sln new file mode 100644 index 000000000..839ae73b5 --- /dev/null +++ b/SadConsole - Desktop.sln @@ -0,0 +1,49 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2042 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "00 Misc", "00 Misc", "{D011790C-9E77-4E56-AA1F-8683AA1B89FD}" + ProjectSection(SolutionItems) = preProject + .gitattributes = .gitattributes + .gitignore = .gitignore + ChangeLog.md = ChangeLog.md + README.md = README.md + EndProjectSection +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SadConsole.Shared", "src\SadConsole.Shared\SadConsole.Shared.shproj", "{111F8273-2EAD-47D3-88EC-CB0CD6122BE8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SadConsole", "src\SadConsole\SadConsole.csproj", "{F44A9E76-B19D-4219-AFAE-561089354280}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "DemoProject", "src\DemoProject\SharedCode\DemoProject.shproj", "{B41A356C-4BA6-40CC-AC03-0E5D46B0B981}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DemoProject.OpenGL", "src\DemoProject\DesktopGL\DemoProject.OpenGL.csproj", "{D6129AE5-B519-4368-B080-805A73405EDA}" +EndProject +Global + GlobalSection(SharedMSBuildProjectFiles) = preSolution + src\SadConsole.Shared\SadConsole.Shared.projitems*{111f8273-2ead-47d3-88ec-cb0cd6122be8}*SharedItemsImports = 13 + src\DemoProject\SharedCode\DemoProject.projitems*{b41a356c-4ba6-40cc-ac03-0e5d46b0b981}*SharedItemsImports = 13 + src\DemoProject\SharedCode\DemoProject.projitems*{d6129ae5-b519-4368-b080-805a73405eda}*SharedItemsImports = 4 + src\SadConsole.Shared\SadConsole.Shared.projitems*{f44a9e76-b19d-4219-afae-561089354280}*SharedItemsImports = 4 + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F44A9E76-B19D-4219-AFAE-561089354280}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F44A9E76-B19D-4219-AFAE-561089354280}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F44A9E76-B19D-4219-AFAE-561089354280}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F44A9E76-B19D-4219-AFAE-561089354280}.Release|Any CPU.Build.0 = Release|Any CPU + {D6129AE5-B519-4368-B080-805A73405EDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D6129AE5-B519-4368-B080-805A73405EDA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D6129AE5-B519-4368-B080-805A73405EDA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D6129AE5-B519-4368-B080-805A73405EDA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9ABB685B-DC99-44D7-A42A-CB3644BB5324} + EndGlobalSection +EndGlobal diff --git a/src/SadConsole.Shared/Cell.cs b/src/SadConsole.Shared/Cell.cs index 6cb44e405..bd82ac4aa 100644 --- a/src/SadConsole.Shared/Cell.cs +++ b/src/SadConsole.Shared/Cell.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; +using System.Security.Cryptography; using System.Text; #if MONOGAME @@ -112,7 +113,7 @@ public void CopyAppearanceTo(Cell cell) cell.Background = this.Background; cell.Glyph = this.Glyph; cell.Mirror = this.Mirror; - cell.Decorators = new List(this.Decorators); + cell.Decorators = Decorators.Length != 0 ? Decorators.ToArray() : new CellDecorator[0]; } /// @@ -125,7 +126,7 @@ public void CopyAppearanceFrom(Cell cell) this.Background = cell.Background; this.Glyph = cell.Glyph; this.Mirror = cell.Mirror; - this.Decorators = new List(cell.Decorators); + this.Decorators = cell.Decorators.ToArray(); } /// @@ -137,7 +138,7 @@ public void Clear() Background = Color.Black; Glyph = 0; Mirror = SpriteEffects.None; - Decorators.Clear(); + Decorators = new CellDecorator[0]; } /// @@ -193,7 +194,7 @@ public void RestoreState() Glyph = State.Value.Glyph; Mirror = State.Value.Mirror; IsVisible = State.Value.IsVisible; - Decorators = new List(State.Value.Decorators); + Decorators = State.Value.Decorators.ToArray(); State = null; } } @@ -208,7 +209,7 @@ public void RestoreState(ref CellState state) Glyph = state.Glyph; Mirror = state.Mirror; IsVisible = state.IsVisible; - Decorators = new List(state.Decorators); + Decorators = state.Decorators.ToArray(); } /// @@ -220,7 +221,7 @@ public void RestoreState(ref CellState state) /// Returns a new cell with the same properties as this one. /// /// The new cell. - public Cell Clone() => new Cell(Foreground, Background, Glyph, Mirror) { IsVisible = this.IsVisible, Decorators = new List(this.Decorators) }; + public Cell Clone() => new Cell(Foreground, Background, Glyph, Mirror) { IsVisible = this.IsVisible, Decorators = Decorators.ToArray() }; /// /// Compares if the cell is the same as the state. diff --git a/src/SadConsole.Shared/Renderers/ControlsConsoleRenderer.cs b/src/SadConsole.Shared/Renderers/ControlsConsoleRenderer.cs index 071ad3020..88012ab18 100644 --- a/src/SadConsole.Shared/Renderers/ControlsConsoleRenderer.cs +++ b/src/SadConsole.Shared/Renderers/ControlsConsoleRenderer.cs @@ -74,7 +74,7 @@ public virtual void RenderControls(ISurface surface, bool force = false) if (cell.Foreground != Color.Transparent) Global.SpriteBatch.Draw(font.FontImage, rect, font.GlyphRects[cell.Glyph], cell.Foreground, 0f, Vector2.Zero, cell.Mirror, 0.26f); - for (int d = 0; d < cell.Decorators.Count; d++) + for (int d = 0; d < cell.Decorators.Length; d++) { decorator = cell.Decorators[d]; diff --git a/src/SadConsole.Shared/Renderers/LayeredSurfaceRenderer.cs b/src/SadConsole.Shared/Renderers/LayeredSurfaceRenderer.cs index dda3fafcc..9585e799b 100644 --- a/src/SadConsole.Shared/Renderers/LayeredSurfaceRenderer.cs +++ b/src/SadConsole.Shared/Renderers/LayeredSurfaceRenderer.cs @@ -57,7 +57,7 @@ public override void RenderCells(ISurface surface, bool force = false) if (cell.Foreground != Color.Transparent) Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[cell.Glyph], cell.Foreground, 0f, Vector2.Zero, cell.Mirror, 0.4f); - for (int d = 0; d < cell.Decorators.Count; d++) + for (int d = 0; d < cell.Decorators.Length; d++) { decorator = cell.Decorators[d]; diff --git a/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs b/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs index 73a7a8fd6..e38e40280 100644 --- a/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs +++ b/src/SadConsole.Shared/Renderers/SurfaceRenderer.cs @@ -91,7 +91,7 @@ public virtual void RenderCells(Surfaces.ISurface surface, bool force = false) if (cell.Foreground != Color.Transparent) Global.SpriteBatch.Draw(surface.Font.FontImage, surface.RenderRects[i], surface.Font.GlyphRects[cell.Glyph], cell.Foreground, 0f, Vector2.Zero, cell.Mirror, 0.4f); - for (int d = 0; d < cell.Decorators.Count; d++) + for (int d = 0; d < cell.Decorators.Length; d++) { decorator = cell.Decorators[d]; diff --git a/src/SadConsole.Shared/SerializedTypes/Cell.cs b/src/SadConsole.Shared/SerializedTypes/Cell.cs index c4ef979a0..64bd0c1b6 100644 --- a/src/SadConsole.Shared/SerializedTypes/Cell.cs +++ b/src/SadConsole.Shared/SerializedTypes/Cell.cs @@ -40,7 +40,7 @@ public class CellSerialized IsVisible = cell.IsVisible, Mirror = cell.Mirror, Decorators = cell.Decorators.ToArray(), - CellState = cell.State == null ? null : cell.State + CellState = cell.State }; } @@ -49,7 +49,7 @@ public class CellSerialized var newCell = new Cell(cell.Foreground, cell.Background, cell.Glyph, cell.Mirror) { IsVisible = cell.IsVisible, - Decorators = cell.Decorators != null ? new List(cell.Decorators) : new List() + Decorators = cell.Decorators != null ? cell.Decorators.ToArray() : new CellDecorator[0] }; if (cell.CellState != null) diff --git a/src/SadConsole/SadConsole.csproj b/src/SadConsole/SadConsole.csproj index 6f6799415..ad24dbd54 100644 --- a/src/SadConsole/SadConsole.csproj +++ b/src/SadConsole/SadConsole.csproj @@ -25,7 +25,7 @@ 4 true bin\Debug\SadConsole.xml - 7.1 + 7.2 pdbonly @@ -35,7 +35,7 @@ prompt 4 bin\Release\SadConsole.xml - 7.1 + 7.2 diff --git a/src/SadConsoleFNA/SadConsoleFNA.csproj b/src/SadConsoleFNA/SadConsoleFNA.csproj index 5c034868c..b2b1b1053 100644 --- a/src/SadConsoleFNA/SadConsoleFNA.csproj +++ b/src/SadConsoleFNA/SadConsoleFNA.csproj @@ -21,6 +21,7 @@ prompt 4 bin\Debug\SadConsoleFNA.xml + 7.2 pdbonly @@ -30,6 +31,7 @@ prompt 4 bin\Release\SadConsoleFNA.xml + 7.2 From ba88df2c30f404f0e14825ca8e3b75cb0c70e049 Mon Sep 17 00:00:00 2001 From: Andy De George Date: Mon, 16 Jul 2018 22:58:54 -0700 Subject: [PATCH 19/44] Cleaned up decorator; made readonly --- src/SadConsole.Shared/CellDecorator.cs | 56 +++++++++++++++----------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/src/SadConsole.Shared/CellDecorator.cs b/src/SadConsole.Shared/CellDecorator.cs index 6166ea02e..117440819 100644 --- a/src/SadConsole.Shared/CellDecorator.cs +++ b/src/SadConsole.Shared/CellDecorator.cs @@ -11,7 +11,7 @@ namespace SadConsole /// Decorates a cell with a colored glyph. /// [DataContract] - public struct CellDecorator : IEquatable + public readonly struct CellDecorator : IEquatable { /// /// An empty cell decorator. @@ -36,12 +36,6 @@ public struct CellDecorator : IEquatable [DataMember] public readonly SpriteEffects Mirror; - /// - /// Identifier assigned by a font. - /// - [DataMember] - public readonly int Id; - /// /// Creates a new decorator with the specified colors, glyph, visiblity, and mirror settings. /// @@ -53,22 +47,6 @@ public CellDecorator(Color color, int glyph, SpriteEffects mirror) Color = color; Glyph = glyph; Mirror = mirror; - Id = -1; - } - - /// - /// Creates a new decorator with the specified colors, glyph, visiblity, and mirror settings. - /// - /// Foreground color. - /// Glyph value. - /// Mirror setting. - /// Id assigned by a font. - internal CellDecorator(Color color, int glyph, SpriteEffects mirror, int id) - { - Color = color; - Glyph = glyph; - Mirror = mirror; - Id = id; } /// @@ -78,6 +56,12 @@ internal CellDecorator(Color color, int glyph, SpriteEffects mirror, int id) /// True if the objects have the same values. public bool Equals(CellDecorator other) => other == this; + /// + /// Checks that the left and right objects match. + /// + /// The first object to test. + /// The second object to test. + /// True when the , , and match. public static bool operator ==(CellDecorator left, CellDecorator right) { return left.Color == right.Color && @@ -85,11 +69,37 @@ internal CellDecorator(Color color, int glyph, SpriteEffects mirror, int id) left.Mirror == right.Mirror; } + /// + /// Checks that the left and right objects do not match. + /// + /// The first object to test. + /// The second object to test. + /// True when the , , and do not match. public static bool operator !=(CellDecorator left, CellDecorator right) { return left.Color != right.Color || left.Glyph != right.Glyph || left.Mirror != right.Mirror; } + + + /// + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + return obj is CellDecorator decorator && Equals(decorator); + } + + /// + public override int GetHashCode() + { + unchecked + { + var hashCode = Color.GetHashCode(); + hashCode = (hashCode * 397) ^ Glyph; + hashCode = (hashCode * 397) ^ (int)Mirror; + return hashCode; + } + } } } From b6d804ecc77775dee43ac1ddf44359e92ce2dc1b Mon Sep 17 00:00:00 2001 From: Andy De George Date: Thu, 19 Jul 2018 22:07:18 -0700 Subject: [PATCH 20/44] Finishing up cell decorator. Changed from list to array. --- src/SadConsole.Shared/Cell.cs | 6 ++- src/SadConsole.Shared/CellDecorator.cs | 1 - src/SadConsole.Shared/CellState.cs | 2 +- src/SadConsole.Shared/FontMaster.cs | 44 +++++++++---------- src/SadConsole.Shared/SerializedTypes/Cell.cs | 2 +- .../Surfaces/SurfaceEditor.cs | 14 +++--- 6 files changed, 36 insertions(+), 33 deletions(-) diff --git a/src/SadConsole.Shared/Cell.cs b/src/SadConsole.Shared/Cell.cs index bd82ac4aa..6accdb6b6 100644 --- a/src/SadConsole.Shared/Cell.cs +++ b/src/SadConsole.Shared/Cell.cs @@ -231,7 +231,8 @@ public void RestoreState(ref CellState state) /// True when they match. public static bool operator ==(Cell left, CellState right) { - return left.Background == right.Background && + return left != null && + left.Background == right.Background && left.Foreground == right.Foreground && left.Glyph == right.Glyph && left.Mirror == right.Mirror && @@ -247,7 +248,8 @@ public void RestoreState(ref CellState state) /// True when are different. public static bool operator !=(Cell left, CellState right) { - return left.Background != right.Background || + return left == null || + left.Background != right.Background || left.Foreground != right.Foreground || left.Glyph != right.Glyph || left.Mirror != right.Mirror || diff --git a/src/SadConsole.Shared/CellDecorator.cs b/src/SadConsole.Shared/CellDecorator.cs index 117440819..ff2bf20ea 100644 --- a/src/SadConsole.Shared/CellDecorator.cs +++ b/src/SadConsole.Shared/CellDecorator.cs @@ -82,7 +82,6 @@ public CellDecorator(Color color, int glyph, SpriteEffects mirror) left.Mirror != right.Mirror; } - /// public override bool Equals(object obj) { diff --git a/src/SadConsole.Shared/CellState.cs b/src/SadConsole.Shared/CellState.cs index c21343833..aa161c1b6 100644 --- a/src/SadConsole.Shared/CellState.cs +++ b/src/SadConsole.Shared/CellState.cs @@ -66,7 +66,7 @@ public CellState(Color foreground, Color background, int glyph, SpriteEffects mi Glyph = glyph; Mirror = mirror; IsVisible = isVisible; - Decorators = decorators == null ? new CellDecorator[] { } : new List(decorators).ToArray(); + Decorators = decorators == null ? new CellDecorator[0] { } : new List(decorators).ToArray(); } /// diff --git a/src/SadConsole.Shared/FontMaster.cs b/src/SadConsole.Shared/FontMaster.cs index 8ce030f8c..d51cbb949 100644 --- a/src/SadConsole.Shared/FontMaster.cs +++ b/src/SadConsole.Shared/FontMaster.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Runtime.Serialization; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -9,7 +10,7 @@ namespace SadConsole /// The font stored by the engine. Used to generate the type used by the engine. /// [DataContract] - public class FontMaster + public sealed class FontMaster { private Dictionary cachedFonts = new Dictionary(); @@ -69,7 +70,8 @@ public class FontMaster /// /// The total rows in the font. /// - public int Rows { get { return Image.Height / (GlyphHeight + GlyphPadding); } } + public int Rows => Image.Height / (GlyphHeight + GlyphPadding); + /// /// The texture used by the font. /// @@ -85,7 +87,7 @@ public class FontMaster /// Standard decorators used by your app. /// [DataMember] - public Dictionary Decorators { get; } = new Dictionary(); + private Dictionary GlyphDefinitions { get; } = new Dictionary(); /// /// Creates a SadConsole font using an existing image. @@ -113,7 +115,7 @@ private FontMaster() } /// - /// Gets a by name from the dictionary. + /// Gets a by name from the dictionary. /// /// The name of the decorator to get. /// The color to apply to the decorator. @@ -121,16 +123,16 @@ private FontMaster() /// If the decorator does not exist, is returned. public CellDecorator GetDecorator(string name, Color color) { - if (Decorators.ContainsKey(name)) - return Decorators[name].CreateCellDecorator(color); + if (GlyphDefinitions.ContainsKey(name)) + return GlyphDefinitions[name].CreateCellDecorator(color); - return CellDecorator.Empty; + throw new Exception("Cell decorator does not exist"); } /// /// Represents a decorator (glyph and mirror) defined by a font. /// - public class CellDecoratorDefinition + public readonly struct GlyphDefinition { /// /// The glyph of the decorator. @@ -147,7 +149,7 @@ public class CellDecoratorDefinition /// /// /// - public CellDecoratorDefinition(int glyph, SpriteEffects mirror) + public GlyphDefinition(int glyph, SpriteEffects mirror) { Glyph = glyph; Mirror = mirror; @@ -159,6 +161,14 @@ public CellDecoratorDefinition(int glyph, SpriteEffects mirror) /// The color of the decorator. /// A new decorator instance. public CellDecorator CreateCellDecorator(Color foreground) => new CellDecorator(foreground, Glyph, Mirror); + + /// + /// Creates a from this definition. + /// + /// The foreground color of the cell. + /// The background color of the cell. + /// A new cell instance. + public Cell CreateCell(Color foreground, Color background) => new Cell(foreground, background, Glyph, Mirror); } #region Methods @@ -212,19 +222,7 @@ public Font GetFont(Font.FontSizes multiple) cachedFonts.Add(multiple, font); return font; } - - ///// - ///// Not used... I think I was going to do something with this... - ///// - //private void GetImageMask() - //{ - // Texture2D texture = new Texture2D(Engine.Device, Image.Width, Image.Height, - // false, SurfaceFormat.Color); - // Color[] newPixels = new Color[texture.Width * texture.Height]; - // Color[] oldPixels = new Color[texture.Width * texture.Height]; - // texture.GetData(newPixels); - // Image.GetData(oldPixels); - //} + [OnDeserialized] private void AfterDeserialized(System.Runtime.Serialization.StreamingContext context) diff --git a/src/SadConsole.Shared/SerializedTypes/Cell.cs b/src/SadConsole.Shared/SerializedTypes/Cell.cs index 64bd0c1b6..38b661eff 100644 --- a/src/SadConsole.Shared/SerializedTypes/Cell.cs +++ b/src/SadConsole.Shared/SerializedTypes/Cell.cs @@ -90,7 +90,7 @@ public class CellStateSerialized Glyph = cell.Glyph, IsVisible = cell.IsVisible, Mirror = cell.Mirror, - Decorators = cell.Decorators.ToArray() + Decorators = cell.Decorators }; } diff --git a/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs b/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs index 2f2d2d2bd..cd8a1c4e6 100644 --- a/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs +++ b/src/SadConsole.Shared/Surfaces/SurfaceEditor.cs @@ -432,7 +432,7 @@ public void SetMirror(int x, int y, SpriteEffects mirror) /// The y coordinate of the cell. /// The count of cells to use from the x,y cooridnate (inclusive). /// The decorators. Use null to clear. - public void SetDecorator(int x, int y, int count, params CellDecorator[] decorators) + public void SetDecorator(int x, int y, int count, CellDecorator[] decorators) => SetDecorator(y * textSurface.Width + x, count, decorators); /// @@ -441,15 +441,19 @@ public void SetDecorator(int x, int y, int count, params CellDecorator[] decorat /// The index of the cell to start applying. /// The count of cells to use from the index (inclusive). /// The decorators. Use null to clear. - public void SetDecorator(int index, int count, params CellDecorator[] decorators) + public void SetDecorator(int index, int count, CellDecorator[] decorators) { if (!IsValidCell(index) || index + count >= textSurface.Cells.Length) return; + + if (decorators == null) + decorators = new CellDecorator[0]; + for (var i = index; i < index + count; i++) { - textSurface[i].Decorators = new CellDecorator[decorators.Length]; - if (decorators.Length != 0) - decorators.CopyTo(textSurface[i].Decorators, 0); + textSurface[i].Decorators = (CellDecorator[]) decorators.Clone(); + else + textSurface[i].Decorators = new CellDecorator[0]; } } From 9ad7fef602b4f1f0a4c983e587b40a2afcd4e4c0 Mon Sep 17 00:00:00 2001 From: Andy De George Date: Fri, 20 Jul 2018 14:26:41 -0700 Subject: [PATCH 21/44] Sample Project: Playing with decorators; extended font --- .../DesktopGL/DemoProject.OpenGL.csproj | 16 +- src/DemoProject/DesktopGL/Program.cs | 5 +- src/DemoProject/DesktopGL/app.config | 2 +- .../CustomConsoles/StringParsingConsole.cs | 22 +- .../SharedCode/DemoProject.projitems | 6 + .../Fonts/IBM8x16_NoPadding_extended.png | Bin 0 -> 4752 bytes src/DemoProject/SharedCode/Fonts/IBM_ext.font | 236 ++++++++++++++++++ 7 files changed, 272 insertions(+), 15 deletions(-) create mode 100644 src/DemoProject/SharedCode/Fonts/IBM8x16_NoPadding_extended.png create mode 100644 src/DemoProject/SharedCode/Fonts/IBM_ext.font diff --git a/src/DemoProject/DesktopGL/DemoProject.OpenGL.csproj b/src/DemoProject/DesktopGL/DemoProject.OpenGL.csproj index 089fcb1ff..0d3f307ad 100644 --- a/src/DemoProject/DesktopGL/DemoProject.OpenGL.csproj +++ b/src/DemoProject/DesktopGL/DemoProject.OpenGL.csproj @@ -9,7 +9,7 @@ Properties StarterProject StarterProject.MonoGL - v4.5 + v4.6.1 512 SAK SAK @@ -66,22 +66,24 @@ - + + Designer + + + + PreserveNewest + + {f44a9e76-b19d-4219-afae-561089354280} SadConsole - - - PreserveNewest - -