Skip to content

Commit

Permalink
Merge pull request #345 from Thraka/develop
Browse files Browse the repository at this point in the history
10.0.3 release
  • Loading branch information
Thraka authored Mar 14, 2024
2 parents 03627ff + 4d8a4fb commit 2ccb1bf
Show file tree
Hide file tree
Showing 137 changed files with 5,801 additions and 2,991 deletions.
137 changes: 137 additions & 0 deletions MiscCodeFragments/DemoControlsScrollbarTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
using SadConsole.Input;
using SadConsole.UI.Controls;

namespace SadConsole.Examples;

internal class DemoControlsScrollbarTests : IDemo
{
public string Title => "Controls (Scrollbar)";

public string Description => "Test area";

public string CodeFile => "DemoControlsScrollbarTests.cs";

public IScreenSurface CreateDemoScreen() =>
new ControlsTest3();

public override string ToString() =>
Title;
}

class ControlsTest3 : SadConsole.UI.ControlsConsole
{
public ControlsTest3() : base(GameSettings.ScreenDemoBounds.Width, GameSettings.ScreenDemoBounds.Height)
{
Controls.ThemeColors = GameSettings.ControlColorScheme;

CreateBox((1, 1), 10, 10);
CreateBox((3, 3), 5, 10);
CreateBox((6, 5), 10, 5);

CreateBox2((20, 1), 10, 1);
CreateBox2((22, 3), 10, 2);
CreateBox2((24, 5), 10, 5);
CreateBox2((26, 7), 10, 10);
CreateBox2((28, 9), 10, 15);
CreateBox2((30, 11), 10, 7);
CreateBox2((32, 13), 2, 7);
CreateBox2((34, 15), 3, 7);
CreateBox2((36, 17), 4, 7);
CreateBox2((38, 19), 5, 7);

CreateBox3((54, 2), 10, 1);
CreateBox3((54, 5), 10, 2);
CreateBox3((54, 8), 10, 5);
CreateBox3((54, 11), 10, 10);
CreateBox3((54, 14), 10, 15);
CreateBox3((54, 17), 10, 7);
CreateBox3((54, 20), 2, 7);
CreateBox3((54, 23), 3, 1);
CreateBox3((65, 2), 4, 1);
CreateBox3((65, 5), 5, 1);
CreateBox3((65, 8), 6, 1);
}

private (ScrollBar bar, Label label) CreateBox3(Point position, int height, int max)
{
ScrollBar bar1 = new(Orientation.Horizontal, height);
Label label1 = new(10);
bar1.Position = position;
bar1.MaximumValue = max;
bar1.ArrowsMoveGrip = true;
bar1.Tag = label1;
label1.PlaceRelativeTo(bar1, Direction.Types.Up, 0);
label1.DisplayText = "Label";

bar1.ValueChanged += Bar2_ValueChanged;

Controls.Add(bar1);
Controls.Add(label1);

Bar2_ValueChanged(bar1, EventArgs.Empty);

return (bar1, label1);
}

private (ScrollBar bar, Label label) CreateBox2(Point position, int height, int max)
{
ScrollBar bar1 = new(Orientation.Vertical, height);
Label label1 = new(10);
bar1.Position = position;
bar1.MaximumValue = max;
bar1.MouseWheelMovesGrip = true;
bar1.Tag = label1;
label1.PlaceRelativeTo(bar1, Direction.Types.Right);
label1.DisplayText = "Label";

bar1.ValueChanged += Bar2_ValueChanged;

Controls.Add(bar1);
Controls.Add(label1);

Bar2_ValueChanged(bar1, EventArgs.Empty);

return (bar1, label1);
}

private (ScrollBar bar, Label label) CreateBox(Point position, int height, int max)
{
ScrollBar bar1 = new(Orientation.Vertical, height);
Label label1 = new(10);
bar1.Position = position;
bar1.MaximumValue = max;
bar1.Tag = label1;
label1.PlaceRelativeTo(bar1, Direction.Types.Right);
label1.DisplayText = "Label";

bar1.ValueChanged += Bar1_ValueChanged;

Controls.Add(bar1);
Controls.Add(label1);

Bar1_ValueChanged(bar1, EventArgs.Empty);

return (bar1, label1);
}

private void Bar1_ValueChanged(object? sender, EventArgs e)
{
ScrollBar control = (ScrollBar)sender!;
((Label)control.Tag!).DisplayText = $"{control.Value}/{control.MaximumValue} {control.Style.GripStart}";
}

private void Bar2_ValueChanged(object? sender, EventArgs e)
{
ScrollBar control = (ScrollBar)sender!;
((Label)control.Tag!).DisplayText = $"{control.Value}/{control.MaximumValue} {control.Style.GripStart}";
}

public override bool ProcessMouse(MouseScreenObjectState state)
{
return base.ProcessMouse(state);
}
}




7 changes: 5 additions & 2 deletions PerformanceTests/SadConsole.PerformanceTests/BasicGameHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ public override IRenderStep GetRendererStep(string name)
return new RenderStep();
}

public override void ResizeWindow(int width, int height) => throw new NotImplementedException();

public override void Run()
{
throw new NotImplementedException();
Expand All @@ -114,5 +112,10 @@ public override ITexture CreateTexture(int width, int height)
{
throw new NotImplementedException();
}

public override void ResizeWindow(int width, int height, bool resizeOutputSurface = false)
{
throw new NotImplementedException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.7" />
</ItemGroup>

<ItemGroup>
Expand Down
68 changes: 40 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,29 @@
[![NuGet](https://img.shields.io/nuget/v/SadConsole.svg)][nuget]
[![kandi X-Ray](https://kandi.openweaver.com/badges/xray.svg)](https://kandi.openweaver.com/csharp/Thraka/SadConsole)

SadConsole is a generic library that emulates old-school console game systems. It provides command prompt-style graphics where one or more tile textures are used to represent an ASCII character set. Console's are made up of a grid of cells, each of which can have its own foreground, background, glyph, and special effect applied to it.
SadConsole is a C#-based .NET cross-platform terminal, ascii, console, game engine. It simulates these types of programs and with it you can make ascii-styled games for modern platforms. At its heart, SadConsole is really a giant tile-based game engine. However, its object model is conceptually similar to a traditional console app.

While SadConsole is a generic library that doesn't provide any rendering capabilities, "host" libraries are provided that add renderers to SadConsole. The two hosts provided by this library are for **MonoGame** and **SFML**.
While SadConsole is a generic library that doesn't provide any rendering capabilities, "host" libraries are provided that add renderers to SadConsole. The two hosts provided by this library are for **SadConsole.Host.MonoGame** and **SadConsole.Host.SFML**. When adding a host library to your project, you don't need to reference the base **SadConsole** package. If you use MonoGame, you'll also need to add a rendering NuGet package, such as **MonoGame.Framework.DesktopGL**.

_SadConsole currently targets .NET 6 and .NET 7_
_SadConsole currently targets .NET 6, .NET 7, and .NET 8_

For the latest changes in this release, see the [notes below](#latest-changes)

## Features

Here are some of the features SadConsole supports:

- Show any number of consoles.
- Show any number of consoles of any size.
- Uses graphical tile-based images to build out an ASCII-character font with support for more than 256 characters.
- Fonts are simply sprite sheet tilesets tied to ascii codes, you can use full graphical tiles if you want.
- Use more than one font file. However, each console is restricted to a single font.
- Independently controlled entities for game objects.
- Keyboard and Mouse support.
- Text UI control framework with windowing support.
- Full GUI system for interactive controls such as list boxes, buttons, and text fields.
- Importers for [DOS ANSI files](https://wikipedia.org/wiki/ANSI_art), [TheDraw text fonts](https://en.wikipedia.org/wiki/TheDraw), [RexPaint](https://www.gridsagegames.com/rexpaint/), and [Playscii](http://vectorpoem.com/playscii/).
- Animated consoles.
- Animated consoles and instruction system to chain commands together.
- String encoding system for colors and effects while printing.
- Entity support for drawing thousands of movable objects on the screen
- Translating images to text-blocks.
- Keyboard and mouse support.
- Highly customizable framework.

#### String display and parsing
Expand Down Expand Up @@ -64,7 +66,7 @@ Builder startup = new Builder()
.UseDefaultConsole()
.OnStart(Game_Started)
.IsStartingScreenFocused(true)
.ConfigureFonts((config, game) => config.UseBuiltinFontExtended())
.ConfigureFonts(true)
;

// Setup the engine and start the game
Expand Down Expand Up @@ -100,9 +102,7 @@ Module Module1
startup.UseDefaultConsole()
startup.OnStart(AddressOf Game_Started)
startup.IsStartingScreenFocused(True)
startup.ConfigureFonts(Sub(config As FontConfig, gameObject As Game)
config.UseBuiltinFontExtended()
End Sub)
startup.ConfigureFonts(True)

' Setup the engine and start the game
SadConsole.Game.Create(startup)
Expand All @@ -125,19 +125,31 @@ Module Module1
End Module
```

## Latest changes v10.0.0 Beta 1 and 2 (10/11/2023)

- OnStart startup config is no longer an Action but is now an event.
- Startup config changed again from the last alpha. Types were renamed and rewritten to be extensible. It works the same way as before except that everything is in the SadConsole.Configuration namespace. You must import that namespace to enable the extension methods that build the config. The type to build the config is Builder.
- Tabs orientated left/right didn't display the text properly.
- ColoredGlyph was renamed to ColoredGlyphBase and a new ColoredGlyph that inherits from the base class was added.
- Scrollbars didn't behave properly when in a CompositeControl.
- ListBox mouse logic was improved to use an "ItemsArea" property that designates when the mouse is over the items list specifically.
- StringParser supports variables. There's a dictionary that invokes a delegate which returns a value for the variable. So the value can be determined as the variable is used. See DemoStringParsing.cs in the sample template.
- AnimatedScreenObject's weren't rendering correctly.
- Decorators are no longer array's but rented from a list pool. Use the CellDecoratorHelpers class to manage them. SadConsole does its best to rent and return from the pool as you add or remove decorators.
- Default font used the wrong name. It's been corrected from "IBM_16x8" to "IBM_8x16".
- The ToggleSwitch control wasn't drawing properly.
- NumberBox supports cultured number parsing.
- CellDecorator, as a readonly struct, now declares the properties with "get; init;" which allows mutation with the the "with" keyword.
- EntityManager.AlternativeFont added to support different fonts for entities.
## Latest changes

v10.0.3 (03/13/2024)

- [UI] `ScrollBar` has been completely rewritten. Minor breaking changes.
- `.Maximum` has been changed to `.MaximumValue`.
- Properties related to the style, such as `BarGlyph`, were moved to a `Style` property which controls how the control looks. Some property names have changed
- [UI] `NumberBox` improvements.
- Rendering code split from `Textbox`.
- Added `ShowUpDownButtons` to show up\down buttons.
- Fixed bug with `UseMinMax` messing up the value and setting it back to 0 when the control loses focus.
- [UI] `ControlBase.FindThemeFont` helper method added.
- [UI] Minor bug fixed where captured controls (such as a scroll bar) wouldn't process the mouse if the control was parented to a composite control and the mouse left the parent area.
- [Core] Fixed `EffectSet` bug where the last effect wasn't applied.
- [Core] `GlyphDefinition` has an init accessor now.
- [Core] Added `ShapeParameter` docs and `CreateFilled` supports ignoring the border.
- [Core] Added `RootComponent` class that can be added to `SadConsole.Game.Instance.RootComponents`. These components run logic before the keyboard and screen updates.
- [Core] Splash screen collection is nulled after it runs, freeing memory.
- [Extended] Classic keyboard handler has `IsReady` flag now to control when it's active.
- [Extended] `ColorPickerPopup` would crash on invalid textbox values.
- [Extended] `GlyphSelectPopup` added. You can use this to display a list of glyphs in your font while debugging your app.
- [Extended] Fixed a bug in the table control that prevented the scroll bars from being displayed.
- [Extended] Cleaned up code and enabled nullable.
- [Host - SFML] Fix bug where it was always running at unlimited FPS.
- [Host - MonoGame] Renderers can set backing texture usage.
- [Host - FNA] Fix bug where the screen clear wasn't working and would default to violet.
- [Host - All] Add `OptimizedScreenSurfaceRenderer` which renders.
- [Host - All] Surface render step can accept an alternative surface with the `SetData` method.
40 changes: 40 additions & 0 deletions SadConsole.Debug.MonoGame/ConfigurationBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using System;
using SadConsole.Components;
using SadConsole.Input;

namespace SadConsole.Configuration;

/// <summary>
/// Extensions to enable the ImGui debug UI.
/// </summary>
public static class DebugExtensions
{
/// <summary>
/// Adds a <see cref="GameHost.RootComponents"/> component that uses the specified hotkey to invoke <see cref="Debug.MonoGame.Debugger.Start"/>.
/// </summary>
/// <param name="builder">The config builder.</param>
/// <param name="hotkey">The keyboard key to start the debugger.</param>
/// <returns>The config builder.</returns>
public static Builder EnableImGuiDebug(this Builder builder, Keys hotkey)
{
ImGuiDebugConfig config = builder.GetOrCreateConfig<ImGuiDebugConfig>();
config.HotKey = hotkey;
return builder;
}
}

internal class ImGuiDebugConfig : RootComponent, IConfigurator
{
public Keys HotKey { get; set; }

public void Run(Builder config, Game game)
{
game.RootComponents.Add(this);
}

public override void Run(TimeSpan delta)
{
if (Game.Instance.FrameNumber != 0 && Game.Instance.Keyboard.IsKeyReleased(HotKey) && !Debug.MonoGame.Debugger.IsOpened)
Debug.MonoGame.Debugger.Start();
}
}
4 changes: 2 additions & 2 deletions SadConsole.Debug.MonoGame/Debugger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ public static void Start()
_imGui.UIComponents.Add(new ScreenObjectsPanel());
_imGui.UIComponents.Add(new GuiSurfacePreview());

ScreenObjectDetailsPanel.RegisteredPanels.Add(typeof(SadConsole.UI.Window), new WindowConsolePanel());
ComponentsPanel.RegisteredPanels.Add(typeof(SadConsole.Components.Cursor), new ComponentEditorCursor());
ScreenObjectDetailsPanel.RegisteredPanels.Add(typeof(SadConsole.UI.Window), new ScreenObjectEditors.WindowConsolePanel());
ComponentsPanel.RegisteredPanels.Add(typeof(SadConsole.Components.Cursor), new SadComponentEditors.ComponentEditorCursor());

GuiState.GuiFinalOutputWindow = new FinalOutputWindow("Output preview", true);
_imGui.UIComponents.Add(GuiState.GuiFinalOutputWindow);
Expand Down
2 changes: 1 addition & 1 deletion SadConsole.Debug.MonoGame/GuiOutputPreview.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public override void BuildUI(ImGuiRenderer renderer)
{
ImGui.SetNextWindowBgAlpha(1f);

if (ImGui.Begin(Title, ref IsOpen))
if (ImGui.Begin(Title, ref IsOpen, ImGuiWindowFlags.HorizontalScrollbar))
{
if (SadConsole.Host.Global.RenderOutput != null)
{
Expand Down
4 changes: 2 additions & 2 deletions SadConsole.Debug.MonoGame/GuiSurfacePreview.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public override void BuildUI(ImGuiRenderer renderer)
{
ImGui.SetNextWindowBgAlpha(1f);
//ImGui.SetNextWindowSizeConstraints(new Vector2(200, 200), new Vector2(10000, 10000));
if (ImGui.Begin("Surface preview", ref GuiState.ShowSurfacePreview))
if (ImGui.Begin("Surface preview", ref GuiState.ShowSurfacePreview, ImGuiWindowFlags.HorizontalScrollbar))
{
// TODO:
// New window that is an editor type for the parent object
Expand Down Expand Up @@ -55,7 +55,7 @@ public override void BuildUI(ImGuiRenderer renderer)
}

// Render the target texture
ImGuiExt.DrawTextureChild("output_preview_surface1", true, _zoom ? ImGuiExt.Zoom2x : ImGuiExt.ZoomNormal, targetTexture, renderer, out var isActive, out var isHovered);
ImGuiExt.DrawTextureChild("output_preview_surface1", false, _zoom ? ImGuiExt.Zoom2x : ImGuiExt.ZoomNormal, targetTexture, renderer, out var isActive, out var isHovered);

// Peek the cell if the target type is the final
if (GuiState._selectedScreenObjectState.SurfaceState.RenderStepSelectedItem == 0)
Expand Down
Loading

0 comments on commit 2ccb1bf

Please sign in to comment.