Overlay generator (pure, tested) — RioJoy.Core/Overlay:
- FontFitter ports the legacy calc-fontsize auto-fit search (validated against a
brute-force oracle); OverlayLayoutEngine ports create-data-layer's fit + h/v
justification and adds per-region 90 deg CCW rotation; OverlayTemplate/Region +
OverlayTemplateStore hold cell geometry/colour/rotation (regions.json).
- GoobieDataImporter parses the legacy .data label sheet into label rows.
- src/RioJoy.Overlay: SkiaSharp rasterizer (SkiaTextMeasurer shared with the engine
so measured layout == drawn output; SkiaOverlayRenderer -> PNG;
ProfileWallpaperGenerator). Verified end-to-end on the real cockpit art
(regions.json + riojoy.png + TEST.data) by OverlayRenderIntegrationTests.
- RioJoy.Tray/WallpaperApplier applies via SystemParametersInfo; RioCoordinator
generates+applies on profile activation (opt-in via AppConfig.OverlayTemplatePath).
Region geometry — tools/XcfRegionExtract parses riojoy.xcf (a GIMP-format binary
reader, no GIMP needed) into the 119-cell regions.json: per-layer offsets/size/
font/colour, with 90 deg CCW rotation on a-00 + b-10..b-1F. Base image riojoy.png.
NOTE: the wallpaper positions are a VGA chroma-split display artifact (6 displays),
not the cockpit's logical layout.
Mapping editor (first cut) — RioJoy.Tray/Editor/ProfileEditorForm renders the
config sheet's logical grid (SheetLayout parses the sheet CSV export). The iRIO
word is edited via ButtonBinding <-> RioMapEntry.Create (no hex bit-twiddling), with
a context-sensitive picker: keyboard keys by name (KeyCatalog VK names), joystick
Button N, hat direction, mouse/RIO-command enum names; modifiers only for keyboard.
Opened from the tray ("Edit profile..."). The sheet-grid layout is a starting point
that needs rework from a better-formatted source.
~220 xUnit tests green. Docs (PLAN.md, README) updated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
85 lines
2.6 KiB
C#
85 lines
2.6 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);
|
|
}
|
|
}
|