Reworked the profile/mapping editor to mirror the original unfinished Win32 RIO driver's control-panel design (docs/Win32RIO, by FASA / Michel Lowrance) instead of the flat config-sheet grid. The wallpaper region positions are a VGA chroma-split display artifact, not the cockpit's logical shape. - RioJoy.Core.Editing.CockpitPanel: the functional layout — five MFD clusters, four board columns (Throttle/Secondary/Screen/Joystick-Hat), an encoder-gauge strip, and the two later-added 4x4 keypads (Internal/External). Places every address 0x00-0x47 / 0x50-0x6F exactly once (unit-tested). - Tray PanelView/PanelCanvas render the panel; ProfileEditorForm drives it. Buttons show label + assigned function (ButtonBinding.Describe -> CTL-N, JOY1, POV-U, Mse LB, RIO command names; unit-tested). Lamp shade is driven by the IsLit flag (not by whether a function is assigned); keypads are neutral blue with no Lit checkbox. Added an Unassign button next to Apply. - Removed the superseded sheet-grid UI (SheetView/SheetCanvas); SheetLayout + config-sheet.csv stay as reference data. docs/Win32RIO: the original driver (tasgame.sys, a 32-bit kernel HID minidriver that opened the serial port, set baud/8N1/DTR, and spoke the *identical* RIO protocol -- AnalogRequest/Reply, Button Pressed/Released, Check/Lamp/Reset/ Version -- validating our protocol port), oemsetup.inf, RemoteDriver.doc, and the extracted control-panel / game-controllers mockups. ~236 xUnit tests green. PLAN.md updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
98 lines
3.5 KiB
C#
98 lines
3.5 KiB
C#
using RioJoy.Core.Mapping;
|
|
using Xunit;
|
|
|
|
namespace RioJoy.Core.Tests.Mapping;
|
|
|
|
public class ButtonBindingTests
|
|
{
|
|
[Theory]
|
|
[InlineData(RioRouteKind.Keyboard, 0x47, 0x0047)]
|
|
[InlineData(RioRouteKind.Joystick, 0x58, 0x1058)]
|
|
[InlineData(RioRouteKind.Hat, 0x01, 0x2001)]
|
|
[InlineData(RioRouteKind.Mouse, 0x10, 0x4010)]
|
|
[InlineData(RioRouteKind.RioCommand, 0x60, 0x7060)]
|
|
public void Create_PacksRoutingFlagsAndValue(RioRouteKind kind, byte value, ushort expected)
|
|
{
|
|
RioMapEntry e = RioMapEntry.Create(kind, value);
|
|
Assert.Equal(expected, e.Raw);
|
|
Assert.Equal(kind, e.Kind);
|
|
Assert.Equal(value, e.Value);
|
|
}
|
|
|
|
[Fact]
|
|
public void Create_SetsHighByteBits()
|
|
{
|
|
RioMapEntry e = RioMapEntry.Create(
|
|
RioRouteKind.Keyboard, 0x41, lit: true, shift: true, ctrl: true, alt: true, extended: true);
|
|
|
|
Assert.True(e.HasLamp);
|
|
Assert.True(e.Shift);
|
|
Assert.True(e.Ctrl);
|
|
Assert.True(e.Alt);
|
|
Assert.True(e.Extended);
|
|
Assert.Equal(0x41, e.Value);
|
|
// 0x8000|0x0800|0x0400|0x0200|0x0100|0x41
|
|
Assert.Equal(0x8F41, e.Raw);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(RioRouteKind.Keyboard)]
|
|
[InlineData(RioRouteKind.Joystick)]
|
|
[InlineData(RioRouteKind.Hat)]
|
|
[InlineData(RioRouteKind.Mouse)]
|
|
[InlineData(RioRouteKind.RioCommand)]
|
|
public void Binding_RoundTripsThroughWord(RioRouteKind kind)
|
|
{
|
|
var b = new ButtonBinding
|
|
{
|
|
Kind = kind,
|
|
Value = 0x2A,
|
|
IsLit = true,
|
|
Shift = true,
|
|
Alt = true,
|
|
};
|
|
|
|
ushort word = b.ToWord();
|
|
ButtonBinding back = ButtonBinding.FromWord(word);
|
|
|
|
Assert.Equal(b.Kind, back.Kind);
|
|
Assert.Equal(b.Value, back.Value);
|
|
Assert.Equal(b.IsLit, back.IsLit);
|
|
Assert.Equal(b.Shift, back.Shift);
|
|
Assert.Equal(b.Ctrl, back.Ctrl);
|
|
Assert.Equal(b.Alt, back.Alt);
|
|
Assert.Equal(b.Extended, back.Extended);
|
|
Assert.Equal(word, back.ToWord());
|
|
}
|
|
|
|
[Fact]
|
|
public void Binding_FromWord_DecodesLegacyValue()
|
|
{
|
|
// 0x8F41 from the encode test -> lit keyboard 'A' with all modifiers.
|
|
ButtonBinding b = ButtonBinding.FromWord(0x8F41);
|
|
Assert.Equal(RioRouteKind.Keyboard, b.Kind);
|
|
Assert.Equal(0x41, b.Value);
|
|
Assert.True(b.IsLit && b.Shift && b.Ctrl && b.Alt && b.Extended);
|
|
}
|
|
|
|
[Fact]
|
|
public void Binding_Default_IsUnmapped()
|
|
{
|
|
Assert.True(new ButtonBinding().IsUnmapped);
|
|
Assert.False(new ButtonBinding { Value = 0x41 }.IsUnmapped);
|
|
}
|
|
|
|
[Fact]
|
|
public void Describe_FormatsEachKind()
|
|
{
|
|
Assert.Equal("", new ButtonBinding().Describe());
|
|
Assert.Equal("K", new ButtonBinding { Value = 0x4B }.Describe());
|
|
Assert.Equal("CTL-N", new ButtonBinding { Value = 0x4E, Ctrl = true }.Describe());
|
|
Assert.Equal("CTL-SFT-K", new ButtonBinding { Value = 0x4B, Ctrl = true, Shift = true }.Describe());
|
|
Assert.Equal("JOY1", new ButtonBinding { Kind = RioRouteKind.Joystick, Value = 1 }.Describe());
|
|
Assert.Equal("POV-U", new ButtonBinding { Kind = RioRouteKind.Hat, Value = (byte)(int)RioHat.Up }.Describe());
|
|
Assert.Equal("Mse LB", new ButtonBinding { Kind = RioRouteKind.Mouse, Value = (byte)MouseAction.LeftClick }.Describe());
|
|
Assert.Equal("ResetThrottle", new ButtonBinding { Kind = RioRouteKind.RioCommand, Value = (byte)RioCommandCode.ResetThrottle }.Describe());
|
|
}
|
|
}
|