Port the analog calibration math and the plasma/VFD command set: - Calibration/: AxisCalibrator ports UpdateThrottle/UpdatePadal/UpdateJoystick (riovjoy2.cpp#L1504+) — throttle deadzone + ratchet field, pedal deadzones, joystick X/Y auto-ranging from observed min/max, rudder mixing (enableZR), and the per-axis invert flags. Stateful (start positions, last outputs, observed extremes) like the legacy globals, with the RIOcmd axis resets. Final outputs clamp to the documented 0..32766 range (also guards a legacy compounding quirk). AxisOutputs carries the six values; IJoystickSink gains SetAxis(JoyAxis,value) so calibrated axes reach the HID feeder. - Plasma/: PlasmaCommands builds the CPlasma ESC sequences (clear/cursor/font/ attr/box draw+fill/text) + GetFontSize + the PlasmaPosText auto-fit/centering; PlasmaDisplay writes them over the secondary COM transport. - tests: 21 new xUnit tests (105 total) for throttle proportional/saturation/ invert, pedal ZR mix vs. direct, joystick centering/direction/invert/reset, the output clamp, and plasma byte sequences/font sizes/auto-fit positioning. Hardware verification of axis feel + plasma output remains; the game-specific PlasmaScoreDraw layout is deferred to profile content (Phase 5/7). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
77 lines
2.6 KiB
C#
77 lines
2.6 KiB
C#
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"));
|
||
}
|
||
|
||
[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);
|
||
}
|
||
}
|