Files
riojoy/tests/RioJoy.Core.Tests/Plasma/PlasmaCommandsTests.cs
T
CydandClaude Fable 5 44b636ddd3 plasma: ESC P bitmap rows through the feedback endpoint (plasma row)
PlasmaCommands.GraphicsWrite/GraphicsRow port the display firmware graphics
command (ESC P s y x w h, MSB-left); PlasmaDisplay.RowAsync writes a locked
whole-row update; the line protocol gains `plasma row <y> <hex32>`. The
router plasma slot becomes a bounded FIFO queue: rows stream in order (a
frame must not tear), texts still coalesce to the newest, clear flushes, cap
128 with counted drops. Docs updated; 442 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 20:45:38 -05:00

108 lines
4.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using RioJoy.Core.Plasma;
using Xunit;
namespace RioJoy.Core.Tests.Plasma;
public class PlasmaCommandsTests
{
[Fact]
public void EscSequences_AreCorrect()
{
Assert.Equal(new byte[] { 27, (byte)'@' }, PlasmaCommands.Clear());
Assert.Equal(new byte[] { 27, (byte)'L' }, PlasmaCommands.CursorHome());
Assert.Equal(new byte[] { 27, (byte)'R', 10 }, PlasmaCommands.CursorX(10));
Assert.Equal(new byte[] { 27, (byte)'Q', 20 }, PlasmaCommands.CursorY(20));
Assert.Equal(new byte[] { 27, (byte)'H', 3 }, PlasmaCommands.FontAttr(3));
Assert.Equal(new byte[] { 27, (byte)'K', 5 }, PlasmaCommands.Font(5));
}
[Fact]
public void Box_DrawAndFill_HaveExpectedLayout()
{
Assert.Equal(new byte[] { 27, (byte)'X', 1, 2, 3, 4 }, PlasmaCommands.BoxDraw(1, 2, 3, 4));
// Fill inserts a leading 0 parameter.
Assert.Equal(new byte[] { 27, (byte)'x', 0, 1, 2, 3, 4 }, PlasmaCommands.BoxFill(1, 2, 3, 4));
}
[Fact]
public void Text_EncodesOneBytePerChar()
{
Assert.Equal(new byte[] { (byte)'A', (byte)'B', (byte)'C' }, PlasmaCommands.Text("ABC"));
}
[Fact]
public void GraphicsWrite_LaysOutHeaderThenData()
{
// ESC P s y x w h data… (s=0, single-screen hardware).
byte[] cmd = PlasmaCommands.GraphicsWrite(5, 2, 2, 2, new byte[] { 0xAA, 0xBB, 0xCC, 0xDD });
Assert.Equal(new byte[] { 27, (byte)'P', 0, 5, 2, 2, 2, 0xAA, 0xBB, 0xCC, 0xDD }, cmd);
}
[Fact]
public void GraphicsRow_IsAWholeRowWrite()
{
// The native game's shape: x=0, w=16, h=1 — one full 128-px row.
var row = new byte[16];
row[0] = 0x80; // leftmost pixel (MSB-first)
byte[] cmd = PlasmaCommands.GraphicsRow(31, row);
byte[] expected = new byte[] { 27, (byte)'P', 0, 31, 0, 16, 1 }.Concat(row).ToArray();
Assert.Equal(expected, cmd);
}
[Fact]
public void GraphicsWrite_RejectsOutOfPanelSpans()
{
Assert.Throws<ArgumentOutOfRangeException>(() => PlasmaCommands.GraphicsRow(32, new byte[16]));
Assert.Throws<ArgumentOutOfRangeException>(
() => PlasmaCommands.GraphicsWrite(0, 15, 2, 1, new byte[2])); // spills past byte column 15
Assert.Throws<ArgumentOutOfRangeException>(
() => PlasmaCommands.GraphicsWrite(31, 0, 16, 2, new byte[32])); // spills past row 31
Assert.Throws<ArgumentException>(
() => PlasmaCommands.GraphicsWrite(0, 0, 16, 1, new byte[15])); // data length mismatch
}
[Theory]
[InlineData(0, 5, 7)]
[InlineData(3, 5, 7)]
[InlineData(4, 10, 14)]
[InlineData(5, 10, 14)]
[InlineData(7, 5, 7)]
public void GetFontSize_MatchesLegacy(int font, int w, int h)
{
Assert.Equal(new FontSize(w, h), PlasmaCommands.GetFontSize(font));
}
[Fact]
public void ResolvePosText_ShortText_PicksFont5_AndCenters()
{
// "HELLO" (5) is non-score and ≤9 → font 5 (10×14). Centered around (56,15).
(byte x, byte y, byte font, int len) = PlasmaCommands.ResolvePosText("HELLO", 0, 0, 0);
Assert.Equal(5, font);
Assert.Equal(5, len);
Assert.Equal(31, x); // 56 - (5*10/2)
Assert.Equal(8, y); // 15 - (14/2)
}
[Fact]
public void ResolvePosText_LongText_Font2_AndCapsLength()
{
string text = new string('1', 24);
(byte x, byte y, byte font, int len) = PlasmaCommands.ResolvePosText(text, 0, 0, 0);
Assert.Equal(2, font);
Assert.Equal(20, len); // capped
Assert.Equal(6, x); // 56 - (20*5/2)
Assert.Equal(12, y); // 15 - (7/2)
}
[Fact]
public void ResolvePosText_ScoreFont_AndExplicitPosition_Unchanged()
{
// font 2 (score) keeps its font; non-zero position is not re-centered.
(byte x, byte y, byte font, int len) = PlasmaCommands.ResolvePosText("AB", 5, 6, 2);
Assert.Equal(2, font);
Assert.Equal(2, len);
Assert.Equal(5, x);
Assert.Equal(6, y);
}
}