Skip to content

Commit 69301f5

Browse files
author
devpossible
committed
Display Driver Refactor + Virtual Display
1 parent 3135c04 commit 69301f5

47 files changed

Lines changed: 8836 additions & 27 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CLAUDE.md

Lines changed: 99 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
66

77
**LCDPossible** is a cross-platform .NET 10 LCD controller service for HID-based LCD screens such as the Thermalright Trofeo Vision 360 ARGB (1280x480 LCD). The project uses a plugin-based driver architecture to support multiple devices and aims to be an open-source alternative to vendor-specific Windows-only software.
88

9-
**Current State:** Phase 1-2 complete. Core infrastructure and Trofeo Vision LCD driver implemented and verified working.
9+
**Current State:** Core infrastructure complete with plugin-based driver architecture. Trofeo Vision LCD driver implemented and verified working. VirtualLcd simulator available for testing without hardware.
1010

1111
## Key Documentation
1212

@@ -38,15 +38,20 @@ LCDPossible/
3838
│ ├── LCDPossible.sln # Solution file
3939
│ ├── LCDPossible.Core/ # Core library (net10.0)
4040
│ │ ├── Devices/ # Device abstraction & drivers
41+
│ │ ├── Plugins/ # Device plugin interfaces & manager
4142
│ │ ├── Rendering/ # Image encoding (JPEG, RGB565)
4243
│ │ └── Usb/ # USB HID layer (HidSharp)
43-
│ └── LCDPossible/ # Main executable - service + CLI (net10.0)
44-
│ ├── Cli/ # CLI commands (debug, etc.)
45-
│ ├── Monitoring/ # Hardware monitoring providers
46-
│ ├── Panels/ # Display panel implementations
47-
│ └── Rendering/ # System info rendering
44+
│ ├── LCDPossible/ # Main executable - service + CLI (net10.0)
45+
│ │ ├── Cli/ # CLI commands (debug, etc.)
46+
│ │ ├── Monitoring/ # Hardware monitoring providers
47+
│ │ ├── Panels/ # Display panel implementations
48+
│ │ └── Rendering/ # System info rendering
49+
│ ├── LCDPossible.VirtualLcd/ # Virtual LCD simulator (Avalonia GUI)
50+
│ │ └── Protocols/ # Protocol handlers for simulator
51+
│ └── Plugins/
52+
│ └── LCDPossible.Plugins.Thermalright/ # Thermalright device drivers
4853
├── tests/
49-
│ └── LCDPossible.Core.Tests/ # Unit tests (20 tests passing)
54+
│ └── LCDPossible.Core.Tests/ # Unit tests
5055
├── build.ps1 # Build script (auto-installs tools)
5156
├── package.ps1 # Package for distribution
5257
├── start-app.ps1 # Run service
@@ -341,8 +346,95 @@ public interface IDisplayPanel : IDisposable
341346
Task InitializeAsync(CancellationToken ct);
342347
Task<Image<Rgba32>> RenderFrameAsync(int width, int height, CancellationToken ct);
343348
}
349+
350+
// Device plugin interface (for driver plugins)
351+
public interface IDevicePlugin : IDisposable
352+
{
353+
string PluginId { get; }
354+
string DisplayName { get; }
355+
IReadOnlyList<SupportedDeviceInfo> SupportedDevices { get; }
356+
IReadOnlyList<DeviceProtocolInfo> Protocols { get; }
357+
ILcdDevice? CreatePhysicalDevice(HidDeviceInfo hidInfo, IDeviceEnumerator enumerator);
358+
IVirtualDeviceHandler? CreateSimulatorHandler(string protocolId);
359+
}
344360
```
345361

362+
## Device Driver Plugin Architecture
363+
364+
Device drivers are organized into plugins by manufacturer (e.g., `LCDPossible.Plugins.Thermalright`). Each plugin can provide:
365+
366+
- **Physical device drivers** - For real USB HID devices
367+
- **Virtual device handlers** - For the VirtualLcd simulator to decode protocols
368+
369+
### Plugin Structure
370+
371+
```
372+
src/Plugins/LCDPossible.Plugins.{Manufacturer}/
373+
├── {Manufacturer}Plugin.cs # IDevicePlugin implementation
374+
├── Drivers/
375+
│ └── {Device}Driver.cs # Physical HID driver
376+
├── Handlers/
377+
│ └── {Device}Handler.cs # Simulator handler (IVirtualDeviceHandler)
378+
└── plugin.json # Plugin manifest
379+
```
380+
381+
### Creating a New Device Plugin
382+
383+
1. Create a new class library project in `src/Plugins/`
384+
2. Reference `LCDPossible.Core`
385+
3. Implement `IDevicePlugin` interface
386+
4. Create a `plugin.json` manifest with `"type": "device"`
387+
388+
```json
389+
{
390+
"id": "lcdpossible.devices.{manufacturer}",
391+
"type": "device",
392+
"name": "{Manufacturer} LCD Devices",
393+
"version": "1.0.0",
394+
"assemblyName": "LCDPossible.Plugins.{Manufacturer}.dll"
395+
}
396+
```
397+
398+
## VirtualLcd Simulator
399+
400+
The VirtualLcd simulator (`src/LCDPossible.VirtualLcd/`) is an Avalonia GUI application that simulates LCD hardware for testing without physical devices. It:
401+
402+
- Receives HID packets over UDP
403+
- Decodes frames using plugin-provided protocol handlers
404+
- Displays the decoded images in a window
405+
406+
### Running the Simulator
407+
408+
```bash
409+
# Build and run (from solution root)
410+
dotnet run --project src/LCDPossible.VirtualLcd -- --help
411+
412+
# Start with default protocol (Trofeo Vision)
413+
dotnet run --project src/LCDPossible.VirtualLcd
414+
415+
# Start with specific protocol
416+
dotnet run --project src/LCDPossible.VirtualLcd -- -d trofeo-vision -p 5302
417+
418+
# List available protocols
419+
dotnet run --project src/LCDPossible.VirtualLcd -- --list-drivers
420+
421+
# Window options
422+
dotnet run --project src/LCDPossible.VirtualLcd -- --always-on-top --borderless --scale 0.5
423+
```
424+
425+
### Simulator CLI Options
426+
427+
| Option | Description |
428+
|--------|-------------|
429+
| `-d, --driver` | Protocol to simulate (default: trofeo-vision) |
430+
| `-p, --port` | UDP port to listen on (default: auto 5302-5399) |
431+
| `-b, --bind` | IP address to bind to (default: 0.0.0.0) |
432+
| `--stats` | Show statistics overlay |
433+
| `--always-on-top` | Keep window above other windows |
434+
| `--borderless` | Hide window decorations |
435+
| `--scale` | Window scale factor (0.1-10.0) |
436+
| `--list-drivers` | List available protocols and exit |
437+
346438
## Creating New Panels
347439

348440
When implementing new display panels, choose the appropriate base class based on the panel's content type.

0 commit comments

Comments
 (0)