Docs: reflect net48; convert tools projects to net48
Documentation now describes the .NET Framework 4.8 stack (was .NET 8): - README build prerequisites + framework-dependent/no-runtime-install note, test count 136 -> 241. - PLAN.md architecture diagram, stack decision (with PolySharp/shims note), suite total 136 -> 241. - deploy/README-DEPLOY.txt: app is net48 framework-dependent (4.8 is in-box on Win10/11), and build prerequisites. Also migrate the three tools (RioJoySmokeTest, RioSerialMonitor, XcfRegionExtract) to net48 so they keep building against the now-net48 RioJoy.Core (a net8 project cannot reference a net48 one). Added PolySharp + System.Memory/System.Text.Json shims and replaced net-core-only APIs (string.Contains/IndexOf with comparison, Array.Fill, generic Enum.IsDefined, int.TryParse(span)). All three build clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -27,8 +27,11 @@ Red Planet — talk to the RIO directly and do not use this app.)
|
||||
|
||||
## Building
|
||||
|
||||
Requires the **.NET 8 SDK** and Windows. The driver builds separately with the
|
||||
**WDK** (see [`driver/README.md`](driver/README.md)).
|
||||
Requires the **.NET SDK** (8.0 or newer) plus the **.NET Framework 4.8
|
||||
targeting/developer pack**, on Windows. The apps target **.NET Framework 4.8**,
|
||||
which is in-box on every Windows 10/11 machine — so deployed builds are
|
||||
framework-dependent and need **no runtime install** on the target. The driver
|
||||
builds separately with the **WDK** (see [`driver/README.md`](driver/README.md)).
|
||||
|
||||
```sh
|
||||
dotnet build RioJoy.sln -c Release
|
||||
@@ -37,7 +40,7 @@ dotnet test RioJoy.sln
|
||||
|
||||
## Status
|
||||
|
||||
Phases 1–5 are implemented and tested (136 unit tests). The `RioGamepad` virtual
|
||||
Phases 1–5 are implemented and tested (241 unit tests). The `RioGamepad` virtual
|
||||
HID driver is built (KMDF + VHF), **test-signed, installed, and verified**: it
|
||||
enumerates in `joy.cpl`, and the C# HID feeder (`DeviceIoControl` →
|
||||
`RioGamepad.sys`) drives its axes, buttons, and hat end-to-end (see
|
||||
|
||||
@@ -11,8 +11,9 @@ Contents
|
||||
postinstall.bat Entry point (at the root). Elevates, then runs
|
||||
RIOJoy\install-rio.ps1.
|
||||
RIOJoy\ The payload folder:
|
||||
app\ The RIOJoy tray application (self-contained .NET 8 — no runtime
|
||||
install required on the target machine).
|
||||
app\ The RIOJoy tray application (.NET Framework 4.8, framework-
|
||||
dependent). .NET Framework 4.8 is in-box on Windows 10/11, so
|
||||
no runtime install is required on the target machine.
|
||||
vendor\ The signed ViGEmBus installer (Nefarius, WHQL/attestation-signed).
|
||||
install-rio.ps1 The actual install steps (idempotent).
|
||||
pre-uninstall.bat Cleanup entry point. Elevates, then runs uninstall-rio.ps1.
|
||||
@@ -57,7 +58,8 @@ After install
|
||||
|
||||
Building this package (on a dev machine)
|
||||
-----------------------------------------
|
||||
Requires the .NET 8 SDK and the signed ViGEmBus installer.
|
||||
Requires the .NET SDK (8.0+) with the .NET Framework 4.8 targeting/developer
|
||||
pack, and the signed ViGEmBus installer.
|
||||
|
||||
powershell -ExecutionPolicy Bypass -File deploy\build-package.ps1 `
|
||||
-VigemInstaller <path-to-ViGEmBus_x.y.z_x64_x86_arm64.exe>
|
||||
|
||||
+7
-3
@@ -25,7 +25,7 @@ cockpit's outputs on their behalf.
|
||||
## Target architecture
|
||||
|
||||
```
|
||||
┌─────────────────────── C# / .NET 8 tray app (x64) ───────────────────────┐
|
||||
┌────────────────── C# / .NET Framework 4.8 tray app (x64) ─────────────────┐
|
||||
│ Serial (RIO protocol) → Input mapper (profile) → Output router │
|
||||
│ COM port, 9600 8N1 72 inputs + keypads ├─ Keyboard/Mouse: SendInput (P/Invoke)
|
||||
│ packet parse + ACK/NAK decode iRIO bitfield ├─ Joystick: HID report → DeviceIoControl ↓
|
||||
@@ -46,7 +46,11 @@ cockpit's outputs on their behalf.
|
||||
- **Virtual joystick:** custom **VHF/UMDF HID driver** (full fidelity: 6 axes,
|
||||
96 buttons, 1 hat — exactly the legacy vJoy layout). Not ViGEm (can't hold 96
|
||||
buttons).
|
||||
- **Stack:** C# / **.NET 8** (LTS), x64. Driver is C (WDK), separate toolchain.
|
||||
- **Stack:** C# / **.NET Framework 4.8**, x64 — in-box on Windows 10/11, so
|
||||
deployed builds are framework-dependent with no runtime to install. (Modern C#
|
||||
language features that net48 lacks are supplied by the PolySharp source
|
||||
generator + a few NuGet shims; see `src/RioJoy.Core/Compat/`.) Driver is C
|
||||
(WDK), separate toolchain.
|
||||
- **Form:** background **tray app** (NotifyIcon), auto-start with Windows.
|
||||
- **Targets:** Windows 10/11 **x64 only**. The legacy x86 / WinXP targets are
|
||||
dropped.
|
||||
@@ -183,7 +187,7 @@ Implemented in `src/RioJoy.Core/Calibration` + `Plasma` (105 xUnit tests total):
|
||||
|
||||
### Phase 5 — Tray app + profiles — code-complete ✅
|
||||
Core logic in `src/RioJoy.Core/Profiles` + `RioRuntime`; UI/OS in `src/RioJoy.Tray`
|
||||
(136 xUnit tests total across the suite):
|
||||
(241 xUnit tests total across the suite):
|
||||
- `RioProfile` + `AppConfig` model; `ConfigStore` JSON persistence (round-trip
|
||||
tested); `RioIniImporter` ports the legacy `RIO.ini` (buttons/inverts/greeting).
|
||||
- `AutoSwitchResolver` + `AutoSwitchWatcher`: the three-state decision
|
||||
|
||||
@@ -105,7 +105,7 @@ int FindJoyId()
|
||||
if (firstPresent < 0) { firstPresent = id; lastName = name; }
|
||||
// RioGamepad identity (Public.h: RIO_VENDOR_ID 0x1209 / RIO_PRODUCT_ID 0x5249).
|
||||
if (caps.wMid == 0x1209 && caps.wPid == 0x5249) { lastName = name; return id; }
|
||||
if (name.Contains("RIOJoy", StringComparison.OrdinalIgnoreCase)) { lastName = name; return id; }
|
||||
if (name.IndexOf("RIOJoy", StringComparison.OrdinalIgnoreCase) >= 0) { lastName = name; return id; }
|
||||
}
|
||||
return firstPresent;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<AssemblyName>RioJoySmokeTest</AssemblyName>
|
||||
@@ -12,4 +13,10 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\RioJoy.Core\RioJoy.Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="PolySharp" Version="1.14.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -52,7 +52,7 @@ AnalogReport lastLogged = default;
|
||||
bool haveAnalog = false;
|
||||
TimeSpan lastAnalogLog = TimeSpan.Zero;
|
||||
var min = new short[5]; var max = new short[5];
|
||||
Array.Fill(min, short.MaxValue); Array.Fill(max, short.MinValue);
|
||||
for (int i = 0; i < min.Length; i++) { min[i] = short.MaxValue; max[i] = short.MinValue; }
|
||||
|
||||
void Track(AnalogReport r)
|
||||
{
|
||||
@@ -113,7 +113,7 @@ link.AnalogReceived += r =>
|
||||
|
||||
link.VersionReceived += v => { version = v; Log($"VERSION reply: firmware {v}"); };
|
||||
link.CheckReceived += c => { checks.Add(c); Log($"CHECK reply: {c}"); };
|
||||
link.ControlReceived += b => { controls++; Log($"control byte 0x{b:X2} ({(Enum.IsDefined((RioControl)b) ? (RioControl)b : (object)"?")})"); };
|
||||
link.ControlReceived += b => { controls++; Log($"control byte 0x{b:X2} ({(Enum.IsDefined(typeof(RioControl), (RioControl)b) ? (RioControl)b : (object)"?")})"); };
|
||||
link.FramingError += () => { framing++; Log("FRAMING ERROR (resync)"); };
|
||||
|
||||
using var cts = new CancellationTokenSource();
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Platforms>x64</Platforms>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<AssemblyName>RioSerialMonitor</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -12,4 +15,12 @@
|
||||
<ProjectReference Include="..\..\src\RioJoy.Core\RioJoy.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Memory" Version="4.5.5" />
|
||||
<PackageReference Include="PolySharp" Version="1.14.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -30,7 +30,7 @@ ulong U64() { ulong v = 0; for (int i = 0; i < 8; i++) v = (v << 8) | d[pos++];
|
||||
string magic = Encoding.ASCII.GetString(d, 0, 9); // "gimp xcf "
|
||||
string ver = Encoding.ASCII.GetString(d, 9, 4); // "file" (=v0) or "vNNN"
|
||||
if (magic != "gimp xcf ") { Console.Error.WriteLine($"Not an XCF file: '{magic}'"); return 1; }
|
||||
bool ptr64 = ver[0] == 'v' && int.TryParse(ver.AsSpan(1, 3), out int vn) && vn >= 11;
|
||||
bool ptr64 = ver[0] == 'v' && int.TryParse(ver.Substring(1, 3), out int vn) && vn >= 11;
|
||||
long Ptr() => ptr64 ? (long)U64() : U32();
|
||||
|
||||
pos = 14;
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<AssemblyName>XcfRegionExtract</AssemblyName>
|
||||
<!-- Dev utility; not part of RioJoy.sln. -->
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Text.Json" Version="8.0.5" />
|
||||
<PackageReference Include="PolySharp" Version="1.14.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user