Phase 0: scaffold modern RIOJoy solution + plan
Modernization of the legacy vJoy-based RIO cockpit interface for Win10/11, removing the vJoy dependency in favor of a custom VHF/UMDF HID driver, rewritten in C#/.NET 8 as a background tray app with per-game profiles. - Reorganize: legacy C++ -> legacy/, cockpit art -> docs/reference/ - RioJoy.sln: src/RioJoy.Core (lib) + src/RioJoy.Tray (tray app), net8.0-windows x64 - driver/ placeholder for the RioGamepad WDK driver - docs/PLAN.md (7-phase plan; profiles + serial-yield model) - docs/PROTOCOL.md (RIO wire format + iRIO input-map reference) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
+372
@@ -0,0 +1,372 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
#[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
###############################################################################
|
||||
# RIOJoy additions
|
||||
###############################################################################
|
||||
# WDK / driver build outputs
|
||||
[Dd]river/**/[Xx]64/
|
||||
*.cer
|
||||
*.pvk
|
||||
# Local run-time config that shouldn't be versioned
|
||||
*.local.json
|
||||
@@ -0,0 +1,36 @@
|
||||
# RIOJoy
|
||||
|
||||
Modern Windows 10/11 interface between the cockpit **RIO** (Remote Input/Output)
|
||||
board and Windows, as a virtual **joystick / keyboard / mouse** — the successor
|
||||
to the legacy vJoy-based app, with **no vJoy dependency**.
|
||||
|
||||
The RIO has 72 digital inputs and outputs (lighted buttons) and 5 analog axes
|
||||
(joystick X/Y, throttle, left pedal, right pedal), connected over RS-232 at
|
||||
9600 8N1. RIOJoy exposes these to games that don't natively know about the
|
||||
cockpit hardware, with **per-game profiles**. (The native games — Firestorm,
|
||||
Red Planet — talk to the RIO directly and do not use this app.)
|
||||
|
||||
## Repository layout
|
||||
|
||||
| Path | Contents |
|
||||
|------|----------|
|
||||
| [`src/RioJoy.Core`](src/RioJoy.Core/) | Protocol, profile model, input mapper, HID feeder (class library) |
|
||||
| [`src/RioJoy.Tray`](src/RioJoy.Tray/) | Background tray application |
|
||||
| [`driver/`](driver/) | `RioGamepad` virtual HID driver (KMDF + VHF) — replaces vJoy |
|
||||
| [`docs/PLAN.md`](docs/PLAN.md) | Full modernization plan (7 phases) |
|
||||
| [`docs/PROTOCOL.md`](docs/PROTOCOL.md) | RIO wire format + `iRIO` input-map reference |
|
||||
| [`docs/reference/`](docs/reference/) | Cockpit overlay art & the legacy labeling pipeline |
|
||||
| [`legacy/`](legacy/) | Original C++/vJoy implementation, kept as reference |
|
||||
|
||||
## Building
|
||||
|
||||
Requires the **.NET 8 SDK** and Windows. The driver builds separately with the
|
||||
**WDK** (see [`driver/README.md`](driver/README.md)).
|
||||
|
||||
```sh
|
||||
dotnet build RioJoy.sln -c Release
|
||||
```
|
||||
|
||||
## Status
|
||||
|
||||
Phase 0 (scaffold + plan). See [`docs/PLAN.md`](docs/PLAN.md) for what's next.
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CDDAA3FE-6A05-40A0-85CC-4DB0B3EEEA9C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RioJoy.Core", "src\RioJoy.Core\RioJoy.Core.csproj", "{C81FEF57-A33B-4529-BDB7-02787407A545}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RioJoy.Tray", "src\RioJoy.Tray\RioJoy.Tray.csproj", "{FA2BAEAC-D8D5-47D9-B5EC-C9D10530D351}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C81FEF57-A33B-4529-BDB7-02787407A545}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C81FEF57-A33B-4529-BDB7-02787407A545}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C81FEF57-A33B-4529-BDB7-02787407A545}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C81FEF57-A33B-4529-BDB7-02787407A545}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FA2BAEAC-D8D5-47D9-B5EC-C9D10530D351}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FA2BAEAC-D8D5-47D9-B5EC-C9D10530D351}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FA2BAEAC-D8D5-47D9-B5EC-C9D10530D351}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FA2BAEAC-D8D5-47D9-B5EC-C9D10530D351}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{C81FEF57-A33B-4529-BDB7-02787407A545} = {CDDAA3FE-6A05-40A0-85CC-4DB0B3EEEA9C}
|
||||
{FA2BAEAC-D8D5-47D9-B5EC-C9D10530D351} = {CDDAA3FE-6A05-40A0-85CC-4DB0B3EEEA9C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
# RIOJoy — modernization plan
|
||||
|
||||
Modernize the cockpit RIO interface app for Windows 10/11, **removing the vJoy
|
||||
dependency** and replacing it with a custom virtual HID device, rewritten in
|
||||
C#/.NET as a background tray app with **per-game profiles**.
|
||||
|
||||
The legacy app is preserved under [`legacy/`](../legacy/) as the behavioral
|
||||
reference. The RIO wire format and input map are documented in
|
||||
[PROTOCOL.md](PROTOCOL.md).
|
||||
|
||||
---
|
||||
|
||||
## Purpose
|
||||
|
||||
The cockpits run two native games (**Firestorm**, **Red Planet**) that talk to
|
||||
the RIO hardware **directly** and never use this app. RIOJoy exists to **broaden
|
||||
which other games can run in the cockpits**: arbitrary games don't know about the
|
||||
cockpit's extra hardware (5 analog axes, 96 lighted buttons, the plasma/VFD
|
||||
display, the labeled wallpaper), so RIOJoy bridges the RIO to whatever input
|
||||
those games *do* understand — joystick, keyboard, and mouse — and drives the
|
||||
cockpit's outputs on their behalf.
|
||||
|
||||
---
|
||||
|
||||
## Target architecture
|
||||
|
||||
```
|
||||
┌─────────────────────── C# / .NET 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 ↓
|
||||
│ analog poll + recovery axis calibration └─ Lamps: LampRequest back over serial
|
||||
│ Plasma/VFD on 2nd COM · Profiles + auto-switch + tray UI + logging │
|
||||
└───────────────────────────────────────────────┬───────────────────────────┘
|
||||
│ IOCTL (input report bytes)
|
||||
┌─────────────────────────────────────────────────▼──────────────────────────┐
|
||||
│ RioGamepad.sys — KMDF + VHF (vhf.sys) virtual HID device │
|
||||
│ Report descriptor: X,Y,Z,Rx,Ry,Rz (16-bit) · 1 hat · 96 buttons │
|
||||
│ Control device + custom IOCTL → VhfReadReportSubmit() → Windows sees │
|
||||
│ a HID gamepad │
|
||||
└─────────────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Decisions (confirmed)
|
||||
|
||||
- **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.
|
||||
- **Form:** background **tray app** (NotifyIcon), auto-start with Windows.
|
||||
- **Targets:** Windows 10/11 **x64 only**. The legacy x86 / WinXP targets are
|
||||
dropped.
|
||||
|
||||
### What ports over vs. what's new
|
||||
|
||||
| Concern | Legacy | Modern |
|
||||
|---|---|---|
|
||||
| Serial + RIO protocol | overlapped I/O + watch thread | `SerialPort` + async loop; faithful port of the packet state machine |
|
||||
| Input decode | `iRIO[]` bitfield + `Press_V2` | same semantics, ported to C# |
|
||||
| Keyboard/mouse | `SendInput` scancode | `SendInput` via P/Invoke (≈verbatim) |
|
||||
| Joystick | vJoy `SetAxis/SetBtn/SetDiscPov` | **HID report → IOCTL → RioGamepad.sys** |
|
||||
| Lamps | `LampRequest` over serial | same |
|
||||
| Axis calibration | `UpdateJoystick/Throttle/Padal` | ported math |
|
||||
| Plasma display | `CPlasma` (COM2) | ported; content per-profile |
|
||||
| Config | SimpleIni, single file, hard-coded COM1 | profile library (JSON), configurable ports; importer for legacy `RIO.ini` |
|
||||
|
||||
---
|
||||
|
||||
## Profiles (the core abstraction)
|
||||
|
||||
A **profile** fully describes how the cockpit behaves for **one non-native
|
||||
game**. Everything is per-profile, not global:
|
||||
|
||||
- Button/keypad mapping (the decoded `iRIO` table for this game)
|
||||
- Axis calibration, curves, and invert flags
|
||||
- Lamp behavior
|
||||
- Plasma/VFD content (or "off")
|
||||
- Cockpit overlay labels + the generated wallpaper (Phase 7)
|
||||
- Display/resolution targets
|
||||
|
||||
Profiles **never** describe the native games — those are the "hands-off" case.
|
||||
|
||||
### Serial-port yield & the auto-switch state machine
|
||||
|
||||
Because the native games own the RIO's COM port directly, RIOJoy must yield it.
|
||||
A process/window watcher drives three states:
|
||||
|
||||
| Detected running app | RIOJoy behavior |
|
||||
|---|---|
|
||||
| **Native game** (Firestorm, Red Planet) | **Release COM port, go fully dormant** — no serial, no HID, no overlay |
|
||||
| **Supported non-native game** | Acquire port, load that game's profile, drive HID / keyboard / mouse / lamps / plasma / wallpaper |
|
||||
| **Nothing / desktop** | Idle — port released or a configurable neutral default |
|
||||
|
||||
Config therefore holds: the per-game profile library, a **list of native games
|
||||
to yield to**, and the executable→profile match rules. Manual override from the
|
||||
tray menu is always available.
|
||||
|
||||
---
|
||||
|
||||
## Phases
|
||||
|
||||
### Phase 0 — Repo & scaffold ✅ (this commit)
|
||||
- `git init`, remote `https://gitea.mysticmachines.com/VWE/riovjoy2.git`.
|
||||
- Legacy C++ moved to `legacy/`; cockpit art to `docs/reference/`.
|
||||
- Solution `RioJoy.sln` with `src/RioJoy.Core` (lib) + `src/RioJoy.Tray`
|
||||
(tray app); `driver/` placeholder for the WDK project.
|
||||
- This plan + [PROTOCOL.md](PROTOCOL.md).
|
||||
|
||||
### Phase 1 — Virtual HID driver (highest risk; do first)
|
||||
- KMDF + VHF virtual HID gamepad: report descriptor = 6×16-bit axes, 1 hat,
|
||||
96 buttons.
|
||||
- Control device + custom IOCTL → `VhfReadReportSubmit`.
|
||||
- Test harness (throwaway C#) wiggles axes/buttons; verify in `joy.cpl`.
|
||||
- Test-signing setup for the cabinets.
|
||||
|
||||
### Phase 2 — Serial + RIO protocol core (`RioJoy.Core`)
|
||||
- `SerialPort` wrapper; packet parser/builder (length table, 7-bit checksum,
|
||||
ACK/NAK, framing resync).
|
||||
- Analog poll timer + >5 s reset-recovery.
|
||||
- **Clean COM-port acquire/release** (foundation for serial yield).
|
||||
- Verify against hardware: version reply, check reply, analog stream.
|
||||
|
||||
### Phase 3 — Input mapping + output routing
|
||||
- Port `iRIO` decode and routing precedence (keyboard/mouse/joy/hat/RIO-command).
|
||||
- Keyboard/mouse via `SendInput` P/Invoke; lamp feedback over serial.
|
||||
- HID-report feeder → the Phase 1 driver via `DeviceIoControl`.
|
||||
|
||||
### Phase 4 — Axis calibration + plasma display
|
||||
- Port `UpdateJoystick/Throttle/Padal` math (deadzones, ratchet, rudder).
|
||||
- Port the `CPlasma` ESC command set on the secondary COM port.
|
||||
|
||||
### Phase 5 — Tray app + profiles
|
||||
- NotifyIcon + menu mirroring the legacy console menu (reset/recalibrate axes,
|
||||
version/status, toggle raw-axis & poll-rate readouts, quit) + status/log window.
|
||||
- **Profile library**, manual selection, and the **three-state auto-switch
|
||||
watcher** (incl. native-game yield).
|
||||
- Config persistence; auto-start.
|
||||
|
||||
### Phase 6 — Packaging / signing / deploy
|
||||
- Driver install via `pnputil`; app installer; test-signing script.
|
||||
- Cabinet deployment doc. (Production option: attestation signing.)
|
||||
|
||||
### Phase 7 — Profile/mapping editor + cockpit overlay generator
|
||||
Replaces the legacy Google-Sheet → `.data` → GIMP → Script-Fu pipeline
|
||||
(see [`docs/reference/customBackground/`](reference/customBackground/)).
|
||||
- **Mapping editor:** per-button UI to set action + label + lamp, no hex
|
||||
bit-twiddling; clone-from-existing profile.
|
||||
- **Overlay generator:** render labels into named regions over a base cockpit
|
||||
image using **SkiaSharp**, porting the auto-fit/justification logic from
|
||||
`sg-goobie-MFD.scm`; export the per-profile wallpaper and re-apply via
|
||||
`SystemParametersInfo`.
|
||||
- **Region authoring:** extract the label rectangles from `riojoy.xcf` into a
|
||||
`regions.json`; in-app box editor for future tweaks.
|
||||
- The unified profile JSON supersedes both `RIO.ini` and the Google Sheet, with
|
||||
importers for each.
|
||||
- To confirm at Phase 7: target wallpaper resolution(s); static wallpaper vs.
|
||||
live overlay (e.g. lit-button highlighting mirroring lamp state).
|
||||
|
||||
---
|
||||
|
||||
## Open items / risks
|
||||
|
||||
- **Driver signing** is the main friction point. Test-signing is fine for owned
|
||||
cabinets; redistribution needs attestation signing (EV cert + Partner Center).
|
||||
- **Input injection vs. session:** `SendInput` targets the interactive session —
|
||||
fine for a tray app, which is why a Windows service was rejected.
|
||||
- **Legacy quirks to decide on** (see PROTOCOL.md ⚠️ notes): disabled inbound
|
||||
checksum verification; odd mouse-move deltas.
|
||||
@@ -0,0 +1,230 @@
|
||||
# RIO serial protocol & `iRIO` input map
|
||||
|
||||
Reverse-engineered from the legacy implementation in
|
||||
[`legacy/riovjoy2.cpp`](../legacy/riovjoy2.cpp). This is the authoritative
|
||||
reference for the Phase 2 C# port. Line references point into the legacy file.
|
||||
|
||||
> ⚠️ Where the legacy code looks buggy, this document describes **what it
|
||||
> actually does** and flags the suspect behavior. Port the documented behavior,
|
||||
> then decide intentionally whether to fix the flagged items.
|
||||
|
||||
---
|
||||
|
||||
## 1. Physical link
|
||||
|
||||
- **RS-232, 9600 baud, 8 data bits, no parity, 1 stop bit (8N1).**
|
||||
- The RIO is on one COM port (legacy hard-codes **COM1**, [`OpenConnection`](../legacy/riovjoy2.cpp#L747)).
|
||||
- An optional **plasma / VFD text display** is on a second COM port (legacy
|
||||
hard-codes **COM2**, [`CPlasma`](../legacy/riovjoy2.cpp#L41)).
|
||||
- DTR is pulsed on open (SETDTR, 50 ms, CLRDTR) as a board reset/handshake.
|
||||
- Both ports must be **configurable** in the modern app (no hard-coded COM
|
||||
numbers).
|
||||
|
||||
### Serial-port ownership (critical)
|
||||
|
||||
The native games (Firestorm, Red Planet) talk to the RIO **directly over this
|
||||
same port**. Only one process can own it at a time, so the modern app must
|
||||
**release the COM port and go dormant whenever a native game is running**, and
|
||||
re-acquire it when a supported non-native game is active. See PLAN.md §Profiles.
|
||||
|
||||
---
|
||||
|
||||
## 2. Framing
|
||||
|
||||
Every message is a packet:
|
||||
|
||||
```
|
||||
[ command byte ] [ payload byte ... ] [ checksum byte ]
|
||||
0x80-0x8C high bit clear 7-bit checksum
|
||||
```
|
||||
|
||||
- **Command byte:** high bit set (`0x80`+). Value identifies the message; see
|
||||
the command table. The valid range is `0x80 .. 0x80 + N` where `N` is the
|
||||
command count.
|
||||
- **Payload length** is fixed per command (the length table below), excluding
|
||||
the command byte and checksum byte.
|
||||
- **Payload bytes** always have the high bit **clear** (7-bit data). Receiving a
|
||||
byte with the high bit set mid-packet means a framing error → **abort the
|
||||
current packet and resync** ([`ReadCommBlock`](../legacy/riovjoy2.cpp#L871)).
|
||||
- **Checksum byte:** `(sum of (b & 0x7F) for each byte in command+payload) & 0x7F`
|
||||
([build: `SendCommand`](../legacy/riovjoy2.cpp#L1217),
|
||||
[verify: `ReadCommBlock`](../legacy/riovjoy2.cpp#L884)).
|
||||
|
||||
### Control characters (single bytes, outside packet framing)
|
||||
|
||||
| Name | Byte | Meaning |
|
||||
|-------------|------|---------|
|
||||
| `ACK` | 0xFC | Packet accepted |
|
||||
| `NAK` | 0xFD | Packet rejected (resend) |
|
||||
| `RESTART` | 0xFE | Restart / also used as an in-payload "invalid" sentinel |
|
||||
| `IDLE` | 0xFF | Idle |
|
||||
|
||||
After a valid received packet, the PC replies `ACK` (when its output queue is
|
||||
empty). For **button** packets with a bad checksum it replies `NAK`; for other
|
||||
packet types with a bad checksum it still `ACK`s.
|
||||
|
||||
> ⚠️ The legacy receive path force-accepts every packet regardless of checksum
|
||||
> (`static bool s_bool = true;` at [riovjoy2.cpp#L887](../legacy/riovjoy2.cpp#L887)),
|
||||
> so checksum verification is effectively disabled inbound. Decide whether to
|
||||
> enable real verification in the port.
|
||||
|
||||
---
|
||||
|
||||
## 3. Command table
|
||||
|
||||
Enum base `0x80` ([`RIOCommand`](../legacy/riovjoy2.cpp#L189)); payload lengths
|
||||
from [`g_baRIOLengthsA`](../legacy/riovjoy2.cpp#L171).
|
||||
|
||||
| Code | Name | Dir | Payload len | Payload |
|
||||
|------|-------------------|---------|-------------|---------|
|
||||
| 0x80 | CheckRequest | PC→RIO | 0 | — |
|
||||
| 0x81 | VersionRequest | PC→RIO | 0 | — |
|
||||
| 0x82 | AnalogRequest | PC→RIO | 0 | — |
|
||||
| 0x83 | ResetRequest | PC→RIO | 1 | `target` (see §Reset) |
|
||||
| 0x84 | LampRequest | PC→RIO | 2 | `lamp#`, `state` |
|
||||
| 0x85 | CheckReply | RIO→PC | 2 | `statusType`, `number` |
|
||||
| 0x86 | VersionReply | RIO→PC | 2 | `major`, `minor` |
|
||||
| 0x87 | AnalogReply | RIO→PC | 10 | 5 axes × (low, high) |
|
||||
| 0x88 | ButtonPressed | RIO→PC | 1 | `index` (0x00–0x47) |
|
||||
| 0x89 | ButtonReleased | RIO→PC | 1 | `index` (0x00–0x47) |
|
||||
| 0x8A | KeyPressed | RIO→PC | 2 | `pad`, `index` |
|
||||
| 0x8B | KeyReleased | RIO→PC | 2 | `pad`, `index` |
|
||||
| 0x8C | TestModeChange | RIO→PC | 1 | `mode` (0 = exit) |
|
||||
|
||||
### Reset targets (ResetRequest payload)
|
||||
|
||||
`0` = general/all, `1` = throttle, `2` = left pedal, `3` = right pedal,
|
||||
`4` = vertical joystick (Y), `5` = horizontal joystick (X)
|
||||
([`ResetThrottle`](../legacy/riovjoy2.cpp#L1273) etc.).
|
||||
|
||||
### Lamp state byte (LampRequest)
|
||||
|
||||
Composed of flash + two brightness fields
|
||||
([`LampState`](../legacy/riovjoy2.cpp#L213)):
|
||||
|
||||
- Flash: `solid=0, flashSlow=1, flashMed=2, flashFast=3`
|
||||
- Field 1: `Off=0x00, Dim=0x04, Bright=0x0C`
|
||||
- Field 2: `Off=0x00, Dim=0x10, Bright=0x30`
|
||||
- Common combos: `SolidOff=0x00`, `SolidDim=0x14`, `SolidBright=0x3C`
|
||||
|
||||
---
|
||||
|
||||
## 4. Analog values
|
||||
|
||||
`AnalogReply` carries 5 axes, each 2 bytes (low then high), in this order:
|
||||
|
||||
1. **Throttle**, 2. **LeftPedal**, 3. **RightPedal**, 4. **JoystickY**, 5. **JoystickX**
|
||||
([`AnalogEvent`](../legacy/riovjoy2.cpp#L1127)).
|
||||
|
||||
Each axis is a **14-bit signed** value packed as two 7-bit bytes
|
||||
([`CombinePair`](../legacy/riovjoy2.cpp#L1116)):
|
||||
|
||||
```
|
||||
raw = (low & 0x7F) | (high << 7); // 14 bits
|
||||
if (raw & 0x2000) raw |= ~0x3FFF; // sign-extend bit 13
|
||||
```
|
||||
|
||||
If any payload byte equals `0xFE`, the reply is treated as invalid and ignored.
|
||||
|
||||
### Polling & recovery
|
||||
|
||||
The legacy watch thread requests an analog update on a ~**55 ms** timeout
|
||||
([`CommWatchProc`](../legacy/riovjoy2.cpp#L1069)). If **>5 s** elapse with no
|
||||
`AnalogReply`, it issues a general reset to recover
|
||||
([riovjoy2.cpp#L1096](../legacy/riovjoy2.cpp#L1096)).
|
||||
|
||||
### Axis → virtual-device mapping (range 0..32766, center 16383)
|
||||
|
||||
Calibration/deadzone math lives in
|
||||
[`UpdateJoystick`](../legacy/riovjoy2.cpp#L1722),
|
||||
[`UpdateThrottle`](../legacy/riovjoy2.cpp#L1637),
|
||||
[`UpdatePadal`](../legacy/riovjoy2.cpp#L1504):
|
||||
|
||||
| RIO axis | Virtual axis | Notes |
|
||||
|---------------|--------------|-------|
|
||||
| JoystickX | X | auto-ranging rate from observed min/max, ±5 deadzone |
|
||||
| JoystickY | Y | same |
|
||||
| Throttle | Z | range ±800, deadzone 50, ratchet via `g_ThrottleResult` |
|
||||
| LeftPedal | Rx | range ±500, deadzone 10 (only when `enableZR` off) |
|
||||
| RightPedal | Ry | same |
|
||||
| (computed) | Rz | rudder = `16383 - leftPedal/2 + rightPedal/2` (when `enableZR` on) |
|
||||
|
||||
Per-axis invert flags (`invertX/Y/Z/XR/YR/ZR`) and `enableZR` come from config.
|
||||
|
||||
---
|
||||
|
||||
## 5. Digital inputs → the `iRIO` map
|
||||
|
||||
The RIO reports button/keypad events by **address**; the app translates each
|
||||
address to a Windows action via a 112-entry table `iRIO[]`
|
||||
([load](../legacy/riovjoy2.cpp#L352), [decode `Press_V2`](../legacy/riovjoy2.cpp#L1944)).
|
||||
|
||||
### Address space (index into `iRIO`)
|
||||
|
||||
| Range | Source |
|
||||
|------------------|--------|
|
||||
| `0x00`–`0x47` (0–71) | the 72 digital button inputs (`ButtonPressed/Released` index) |
|
||||
| `0x50`–`0x5F` (80–95) | keypad **pad 0** (`KeyPressed` with `pad=0`, app adds 0x50) |
|
||||
| `0x60`–`0x6F` (96–111) | keypad **pad 1** (`KeyPressed` with `pad=1`, app adds 0x60) |
|
||||
|
||||
(`0x48`–`0x4F` unused.) Keypad offset logic:
|
||||
[`KeypadEvent`](../legacy/riovjoy2.cpp#L1185).
|
||||
|
||||
### Per-entry 16-bit encoding
|
||||
|
||||
Each `iRIO[addr]` is a 16-bit word. High byte = routing flags, low byte =
|
||||
payload:
|
||||
|
||||
| Bit | Name | Meaning |
|
||||
|--------|-----------|---------|
|
||||
| 0x8000 | hasLamp | This input drives a lighted button (lamp feedback on press/release) |
|
||||
| 0x4000 | mouse | Route payload to **mouse** |
|
||||
| 0x2000 | hat | Route payload to **POV hat** |
|
||||
| 0x1000 | joy | Route payload to **joystick button** |
|
||||
| 0x0800 | extended | Keyboard: set `KEYEVENTF_EXTENDEDKEY` |
|
||||
| 0x0400 | alt | Keyboard: hold ALT around the key |
|
||||
| 0x0200 | ctrl | Keyboard: hold CTRL around the key |
|
||||
| 0x0100 | shift | Keyboard: hold SHIFT around the key |
|
||||
| 0x00FF | value | VK code / button# / hat direction / mouse action |
|
||||
|
||||
### Routing precedence (`Press_V2` / `Release_V2`)
|
||||
|
||||
1. If **none** of joy/hat/mouse set → **keyboard**: press modifiers, then send
|
||||
the key by **scancode** (`MapVirtualKey(VK, MAPVK_VK_TO_VSC)` +
|
||||
`KEYEVENTF_SCANCODE`, plus extended flag). VK list:
|
||||
[`legacy/hbb_vkey.cpp`](../legacy/hbb_vkey.cpp).
|
||||
2. If **joy && hat && mouse all set** (`0x7000`) → it's a **RIO command**, not an
|
||||
output: calls `RIOcmd(value)` (axis resets, recalibrate, status, etc. — see
|
||||
[`RIOcmd`](../legacy/riovjoy2.cpp#L1852)).
|
||||
3. Else if **joy** → set joystick button `value`.
|
||||
4. Else if **hat** → set POV to direction `value` (release → center).
|
||||
5. Else if **mouse** → mouse action `value`.
|
||||
|
||||
Lamp feedback: on press `SolidBright`, on release `SolidDim`; lamps initialized
|
||||
to `SolidDim` at startup for entries with `hasLamp`.
|
||||
|
||||
### Mouse action codes (low byte when `mouse` set)
|
||||
|
||||
`0`=move up, `1`=move right, `2`=move down, `3`=move left, `4`=left click,
|
||||
`5`=right click ([`Mouse`](../legacy/riovjoy2.cpp#L2075)).
|
||||
|
||||
> ⚠️ The legacy move directions mix `dx`/`dy` oddly (e.g. "up" sets `dx=-50`).
|
||||
> Treat the codes as the contract; fix the actual movement deltas in the port.
|
||||
|
||||
---
|
||||
|
||||
## 6. Lighted-button & board name tables
|
||||
|
||||
Human-readable lamp and board names (useful for the config UI and diagnostics)
|
||||
are in [`GetLampName`](../legacy/riovjoy2.cpp#L1332) and
|
||||
[`GetBoardName`](../legacy/riovjoy2.cpp#L1413).
|
||||
|
||||
---
|
||||
|
||||
## 7. Plasma / VFD display (secondary COM port)
|
||||
|
||||
ESC-based command set ([`CPlasma`](../legacy/riovjoy2.cpp#L2146)): clear (`ESC @`),
|
||||
cursor X/Y (`ESC R`/`ESC Q`), font (`ESC K`), attribute (`ESC H`), box draw/fill
|
||||
(`ESC X`/`ESC x`), plus text. Fonts and sizes:
|
||||
[`GetFontSize`](../legacy/riovjoy2.cpp#L2198). Port for Phase 4; content becomes
|
||||
per-profile.
|
||||
@@ -0,0 +1,3 @@
|
||||
; This is the Data to be used with gimp RIO template, copy the first three lines into a data file, install GIMP run gimp script sg-goobie-MFD.scm
|
||||
( a-00 b-00 b-01 b-02 b-03 b-04 b-05 b-06 b-07 b-08 b-09 b-0A b-0B b-0C b-0D b-0E b-0F b-10 b-11 b-12 b-13 b-14 b-15 b-16 b-17 b-18 b-19 b-1A b-1B b-1C b-1D b-1E b-1F b-20 b-21 b-22 b-23 b-24 b-25 b-26 b-27 b-28 b-29 b-2A b-2B b-2C b-2D b-2E b-2F b-30 b-31 b-32 b-33 b-34 b-35 b-36 b-37 b-38 b-39 b-3A b-3B b-3C b-3D b-3E b-3F b-40 b-41 b-42 b-43 b-44 b-45 b-46 b-47 b-50 b-51 b-52 b-53 b-54 b-55 b-56 b-57 b-58 b-59 b-5A b-5B b-5C b-5D b-5E b-5F b-60 b-61 b-62 b-63 b-64 b-65 b-66 b-67 b-68 b-69 b-6A b-6B b-6C b-6D b-6E b-6F )
|
||||
( "defalt" "LSDI" "ZOOM" "UNDOCK" "LDS" "BALANCE" "DRIVE" "DEFENCE" "OFFENCE" "LAST AGGESSOR" "SUB TARGET" "NEXT ENEMY" "NEAR ENEMY" "LAST CONTACT" "DOWN CON" "UP CONTACT" "TOP CONTACT" "M U" "M R" "M D" "M L" "MLC" "TAB" "" "" "ENTER" "ALT" "CTRL" "SHIFT" "VL U" "VL D" "" "" ">" "v" "^" "<" "N" "M" "L" "K" "V" "U" "T" "S" "J" "I" "H" "G" "Z" "Y" "X" "W" "R" "Q" "P" "O" "M ^" "M >" "M v" "M <" "ML" "ESC" "MR" "REVERSE" "FIRE/ACCEPT" "H v" "H ^" "H >" "H <" "NEXT PRIMEARY" "NEXT SECOND" "TARGET/BACK" "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "A" "B" "C" "D" "E" "F" "RIO_0" "RIO_1" "RIO_2" "RIO_3" "RIO_4" "RIO_5" "RIO_6" "RIO_7" "RIO_8" "RIO_9" "RIO_A" "RIO_B" "RIO_C" "RIO_D" "RIO_E" "RIO_F" )
|
||||
@@ -0,0 +1 @@
|
||||
https://docs.google.com/spreadsheets/d/1TkWsk0xXA4rPArQvldmQiWhGd77eB3NUm0Q3XpW5cEU/edit?usp=sharing
|
||||
Binary file not shown.
@@ -0,0 +1,212 @@
|
||||
; This program is free software; you can redistribute it and/or modify
|
||||
; it under the terms of the GNU General Public License as published by
|
||||
; the Free Software Foundation; either version 2 of the License, or
|
||||
; (at your option) any later version.
|
||||
;
|
||||
; This program is distributed in the hope that it will be useful,
|
||||
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
; GNU General Public License for more details.
|
||||
|
||||
; This script reads in a data file containing a list of
|
||||
; RIO button information.
|
||||
|
||||
; The data file uses Lisp/Scheme style lists and commenting (comments
|
||||
; start with a semi-colon and extend to the end of the line).
|
||||
|
||||
; The first non-comment line of the data file should be a list containing
|
||||
; the field names of the RIO button addresses wrapped in parentheses.
|
||||
; For example:
|
||||
;
|
||||
; ; THIS IS A COMMENT AND IGNORED
|
||||
; ( 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F )
|
||||
;
|
||||
; This "header" list should be followed by the LINE containing the
|
||||
; actual data to be substituted into the template file. The data should
|
||||
; be text strings and appear in the same order as the fields specified in
|
||||
; the header list.
|
||||
;
|
||||
; ("A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "CTRL" "ALT")
|
||||
;
|
||||
;
|
||||
; The currently open image is used as a template with the upper layers having
|
||||
; names that match the field names. These field layers are used to determine
|
||||
; the location and size of the text (this layer is otherwise ignored).
|
||||
; The name text is centered within the bounds of this field template layer.
|
||||
;
|
||||
;
|
||||
(define (script-fu-sg-goobie image
|
||||
datafilename
|
||||
save-xcf
|
||||
save-jpeg
|
||||
save-png
|
||||
save-dir
|
||||
vert-justification
|
||||
size-handling)
|
||||
|
||||
;; Perform a search for the largest font that will fit within
|
||||
;; the cell.
|
||||
;
|
||||
(define (calc-fontsize text font width height)
|
||||
(let loop ((fontsize 6) ;; minimum possible fontsize
|
||||
(last-extents nil)
|
||||
(last-fontsize 3)
|
||||
(adjust 2)
|
||||
)
|
||||
(let ((extents (gimp-text-get-extents-fontname text fontsize PIXELS font)))
|
||||
(if (or (= last-fontsize fontsize) (equal? extents last-extents))
|
||||
(max fontsize 6)
|
||||
(if (or (> (car extents) width) (> (cadr extents) height))
|
||||
(loop (truncate (* last-fontsize (+ (* (- adjust 1) 0.5) 1)))
|
||||
last-extents
|
||||
last-fontsize
|
||||
(+ (* (- adjust 1) 0.5) 1) )
|
||||
(loop (truncate (* fontsize adjust))
|
||||
extents
|
||||
fontsize
|
||||
adjust ))))))
|
||||
|
||||
(define (create-data-layer image field-name field-data)
|
||||
(let ((frame-layer
|
||||
(let loop ((layers (vector->list (cadr (gimp-image-get-layers image)))))
|
||||
(if (null? layers)
|
||||
#f
|
||||
(if (string=? field-name (car (gimp-drawable-get-name (car layers))))
|
||||
(car layers)
|
||||
(loop (cdr layers)) )))))
|
||||
(if frame-layer
|
||||
(if (= (car (gimp-drawable-is-text-layer frame-layer)) 1)
|
||||
(let ((x (car (gimp-drawable-offsets frame-layer)))
|
||||
(y (cadr (gimp-drawable-offsets frame-layer)))
|
||||
(w (car (gimp-drawable-width frame-layer)))
|
||||
(h (car (gimp-drawable-height frame-layer)))
|
||||
(font (car (gimp-text-layer-get-font frame-layer)))
|
||||
(size (car (gimp-text-layer-get-font-size frame-layer)))
|
||||
)
|
||||
(gimp-image-set-active-layer image frame-layer)
|
||||
(gimp-text-layer-set-text frame-layer field-data)
|
||||
(let ((extents (gimp-text-get-extents-fontname field-data
|
||||
size
|
||||
PIXELS
|
||||
font )))
|
||||
(when (and (zero? size-handling)
|
||||
(or (> (car extents) w)
|
||||
(> (cadr extents) h) ))
|
||||
(gimp-text-layer-set-font-size frame-layer (calc-fontsize field-data font w h) PIXELS) )
|
||||
(case vert-justification
|
||||
((0) ; center
|
||||
(gimp-layer-set-offsets frame-layer
|
||||
x
|
||||
(+ y (/ (- h (cadr extents)) 2)) ))
|
||||
((1) ; top
|
||||
(gimp-layer-set-offsets frame-layer
|
||||
x
|
||||
y ))
|
||||
((2) ; bottom
|
||||
(gimp-layer-set-offsets frame-layer
|
||||
x
|
||||
(- (+ y h) (cadr extents)) )))))
|
||||
(gimp-message "Field layer is not a text layer")
|
||||
)
|
||||
(begin
|
||||
(gimp-message (string-append "Field layer not found: " field-name)) ))
|
||||
frame-layer ))
|
||||
|
||||
;; ----------------------------------------------------------------------
|
||||
;; Main processing start here
|
||||
;
|
||||
(let* ((inport (open-input-file datafilename))
|
||||
(field-names (map symbol->string (read inport)))
|
||||
(filetag (car field-names)) )
|
||||
(gimp-image-undo-freeze image)
|
||||
(gimp-context-push)
|
||||
(let entry-loop ((fields (read inport)))
|
||||
(unless (eof-object? fields)
|
||||
(let ((temp-image (car (gimp-image-duplicate image)))
|
||||
(filename #f) )
|
||||
(let field-loop ((field-names field-names)
|
||||
(field-values fields) )
|
||||
(unless (null? field-values)
|
||||
(when (string=? (car field-names) filetag)
|
||||
(set! filename (car field-values)) )
|
||||
(create-data-layer temp-image (car field-names) (car field-values))
|
||||
(field-loop (cdr field-names) (cdr field-values)) ))
|
||||
(if filename
|
||||
(let ((fullname (string-append save-dir
|
||||
DIR-SEPARATOR
|
||||
filename )))
|
||||
(unless (zero? save-xcf)
|
||||
(let ((filename (string-append fullname ".xcf")))
|
||||
(gimp-xcf-save TRUE
|
||||
temp-image
|
||||
(car (gimp-image-get-active-layer image))
|
||||
filename
|
||||
filename )))
|
||||
(unless (zero? save-png)
|
||||
(let ((layer (car (gimp-image-merge-visible-layers temp-image
|
||||
CLIP-TO-IMAGE )))
|
||||
(filename (string-append fullname ".png")) )
|
||||
(file-png-save2 RUN-NONINTERACTIVE
|
||||
temp-image
|
||||
layer
|
||||
filename
|
||||
filename
|
||||
FALSE ; interlace
|
||||
9
|
||||
FALSE ; bkgd
|
||||
(car (gimp-drawable-has-alpha layer))
|
||||
FALSE ; offs
|
||||
FALSE ; phys
|
||||
FALSE ; time
|
||||
TRUE ; comment
|
||||
FALSE ; svtrans
|
||||
)))
|
||||
(unless (zero? save-jpeg)
|
||||
(let ((layer (car (gimp-image-flatten temp-image)))
|
||||
(filename (string-append fullname ".jpg")) )
|
||||
(file-jpeg-save RUN-NONINTERACTIVE
|
||||
temp-image
|
||||
layer
|
||||
filename
|
||||
filename
|
||||
0.93
|
||||
0 ; smoothing
|
||||
1 ; optimize
|
||||
1 ; progressive
|
||||
"" ; comment
|
||||
0 ; subsmp (0-4)
|
||||
1 ; baseline
|
||||
0 ; restart
|
||||
0 ;dct
|
||||
))))
|
||||
(gimp-message "Error encountered") )
|
||||
; (gimp-image-delete temp-image)
|
||||
)
|
||||
(entry-loop (read inport)) ))
|
||||
(close-input-port inport)
|
||||
(gimp-context-pop)
|
||||
(gimp-image-undo-thaw image)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(script-fu-register "script-fu-sg-goobie"
|
||||
"Goobie (MFD)..."
|
||||
"Create MFD image based on template image"
|
||||
"Frank Galatis"
|
||||
"Saul Goode"
|
||||
"June 2012"
|
||||
"*"
|
||||
SF-IMAGE "Image" 0
|
||||
SF-FILENAME "Data file" "example.data"
|
||||
SF-TOGGLE "Save as XCF" FALSE
|
||||
SF-TOGGLE "Save as JPEG" TRUE
|
||||
SF-TOGGLE "Save as PNG" FALSE
|
||||
SF-DIRNAME "Save directory" ""
|
||||
SF-OPTION "Vertical justification" '("Center" "Top" "Bottom")
|
||||
SF-OPTION "Font sizing (if too large)" '("Fit" "Crop" "Overflow")
|
||||
)
|
||||
(script-fu-menu-register "script-fu-sg-goobie"
|
||||
"<Image>/File"
|
||||
)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# RioGamepad — virtual HID driver
|
||||
|
||||
The `RioGamepad` virtual HID device replaces the legacy **vJoy** dependency. It
|
||||
is a KMDF driver built on the Windows **Virtual HID Framework (VHF, `vhf.sys`)**
|
||||
that presents a single HID game controller to Windows matching the layout the
|
||||
old app drove through vJoy:
|
||||
|
||||
| Report field | Count | Notes |
|
||||
|--------------|-------|-------|
|
||||
| Axes | 6 | X, Y, Z, Rx, Ry, Rz — 16-bit |
|
||||
| Hat switch | 1 | 4-direction POV with null state |
|
||||
| Buttons | 96 | 12 bytes of button bits |
|
||||
|
||||
The C# tray app feeds input reports to the driver through a custom
|
||||
`DeviceIoControl` IOCTL on the driver's control device; the driver relays them
|
||||
to Windows via `VhfReadReportSubmit`.
|
||||
|
||||
## Status
|
||||
|
||||
Phase 0 placeholder. Implementation is **Phase 1** in [../docs/PLAN.md](../docs/PLAN.md).
|
||||
|
||||
## Build prerequisites (Phase 1)
|
||||
|
||||
- Windows Driver Kit (WDK) for Windows 11 + matching Visual Studio + Windows SDK
|
||||
- A separate WDK/MSBuild project lives here (`RioGamepad.vcxproj`); it is **not**
|
||||
part of `RioJoy.sln` (different toolchain).
|
||||
|
||||
## Signing
|
||||
|
||||
For the cockpit cabinets, enable **test signing** (`bcdedit /set testsigning on`)
|
||||
and install a self-signed test certificate — appropriate for hardware you own.
|
||||
Redistribution would instead use Microsoft **attestation signing** via Partner
|
||||
Center. See the deployment notes in [../docs/PLAN.md](../docs/PLAN.md) (Phase 6).
|
||||
@@ -0,0 +1,4 @@
|
||||
#include <windows.h>
|
||||
#include "c232comm.h"
|
||||
#include "CPlasma.h"
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef __CPLASMA_H__
|
||||
#define __CPLASMA_H__
|
||||
|
||||
#define ESC 27
|
||||
class CPlasma : public C232Comm
|
||||
{
|
||||
public:
|
||||
DWORD m_dwStart;
|
||||
int m_nOldRank;
|
||||
int m_nOldScore;
|
||||
enum {
|
||||
ATTR_NORMAL = 0,
|
||||
ATTR_HALF = 1,
|
||||
ATTR_LINE = 2,
|
||||
ATTR_REVERSE = 4,
|
||||
ATTR_FLASH = 8,
|
||||
ATTR_PROTECTED = 128
|
||||
};
|
||||
enum { PLASMA_OFF, PLASMA_ON, PLASMA_FLASH };
|
||||
|
||||
int m_nGlobalState;
|
||||
// Time m_timeLastPlasma2;
|
||||
public:
|
||||
CPlasma () {
|
||||
Open (2);
|
||||
m_dwStart = GetTickCount ();
|
||||
PlasmaClear ();
|
||||
PlasmaCursor (CPlasma::PLASMA_OFF);
|
||||
m_nOldRank = INT_MIN;
|
||||
m_nOldScore = INT_MIN;
|
||||
|
||||
m_nGlobalState = -1;
|
||||
}
|
||||
virtual ~CPlasma () {
|
||||
PlasmaCursor (CPlasma::PLASMA_OFF);
|
||||
PlasmaClear ();
|
||||
Close ();
|
||||
}
|
||||
public:
|
||||
void SendPacket (const BYTE* pbPacket, char nLen);
|
||||
void PlasmaClear ();
|
||||
|
||||
void PlasmaCursor (char n = PLASMA_OFF);
|
||||
void PlasmaCursorHome ();
|
||||
void PlasmaCursorX (char n);
|
||||
void PlasmaCursorY (char n);
|
||||
|
||||
void PlasmaFontAttr (char n);
|
||||
void PlasmaFont (char n);
|
||||
|
||||
void PlasmaText (const char *szText);
|
||||
POINT GetFontSize (int Font);
|
||||
|
||||
void PlasmaBoxDraw (RECT tag);
|
||||
void PlasmaBoxFill (RECT tag);
|
||||
void PlasmaPosText (const char *szText, char x = 0, char y = 0, char Attr = 0, char Font = 5);
|
||||
void PlasmaScoreDraw (const char *Rank, const char *Score, BOOL bFlag);
|
||||
|
||||
void DoPlasma(char nMode);
|
||||
private:
|
||||
void PlasmaDisplay (int Gamestate, const char *szName, const char *Rank, const char *Score);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Binary file not shown.
+135
@@ -0,0 +1,135 @@
|
||||
#ifndef __RIO_H__
|
||||
#define __RIO_H__
|
||||
|
||||
|
||||
#define MSBON(B) {B |= 0x80;}
|
||||
#define MSBOFF(B) {B &= ~0x80;}
|
||||
#define MAXLENGTH 13
|
||||
|
||||
#define ACK_CHAR 0xFC
|
||||
#define NAK_CHAR 0xFD
|
||||
#define RESTART_CHAR 0xFE
|
||||
#define IDLE_CHAR 0xFF
|
||||
#define RX_ACK_BIT 0x0001
|
||||
#define RX_NAK_BIT 0x0002
|
||||
|
||||
|
||||
class CString
|
||||
{
|
||||
public:
|
||||
char m_sz[256];
|
||||
public:
|
||||
CString()
|
||||
{
|
||||
m_sz[0] = '0';
|
||||
};
|
||||
~CString()
|
||||
{
|
||||
}
|
||||
|
||||
void _cdecl Format(const char* pcszFormat, ...)
|
||||
{
|
||||
va_list va_marker;
|
||||
|
||||
va_start(va_marker, pcszFormat);
|
||||
vsprintf_s(m_sz, pcszFormat, va_marker);
|
||||
va_end(va_marker);
|
||||
}
|
||||
|
||||
operator const char* () const { return &m_sz[0]; }
|
||||
CString& operator = (const char* pcszText)
|
||||
{
|
||||
strcpy_s(m_sz, pcszText);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class CListBox
|
||||
{
|
||||
public:
|
||||
public:
|
||||
CListBox() {}
|
||||
~CListBox() {}
|
||||
int GetCount() const { return 0; }
|
||||
void AddString(const char* pcszText) {}
|
||||
void DeleteString(int nindex) {}
|
||||
};
|
||||
|
||||
class CRIO : public C232Comm
|
||||
{
|
||||
public:
|
||||
CListBox& m_ListBox;
|
||||
BYTE m_ba[2048];
|
||||
BYTE *m_pStart;
|
||||
const BYTE *m_pEnd;
|
||||
int m_nCount;
|
||||
DWORD m_dwFlags;
|
||||
BYTE m_baRead[128];
|
||||
int m_nState;
|
||||
int m_nRead;
|
||||
int m_nLeft;
|
||||
BYTE m_bCheck;
|
||||
BYTE m_baReplies[32];
|
||||
int m_nReplies;
|
||||
int TestModeActive;
|
||||
|
||||
DWORD m_dwAnalogRequest;
|
||||
public:
|
||||
CRIO (CListBox& ListBox) : m_ListBox (ListBox) {
|
||||
Init ();
|
||||
}
|
||||
virtual ~CRIO () {};
|
||||
|
||||
public:
|
||||
void Init ();
|
||||
void RIOBordState (BYTE ID);
|
||||
void DoEventLoop();
|
||||
void EventLoop (const BYTE *buf, int nLen);
|
||||
void AddReply (BYTE bReply);
|
||||
void CheckReplies ();
|
||||
void CheckAnalogRequest();
|
||||
void SendCommand (const BYTE* pbPacket);
|
||||
void SendPacket (const BYTE* pbPacket, int nLen);
|
||||
void SetLamp (int lampNumber, int state);
|
||||
|
||||
void GeneralReset();
|
||||
void ResetThrottle ();
|
||||
void RequestCheck();
|
||||
void RequestVersion();
|
||||
void RequestAnalogUpdate();
|
||||
|
||||
public:
|
||||
enum RIOCommand {
|
||||
rio_CheckRequest = 0x80, // 128
|
||||
rio_VersionRequest, // 129
|
||||
rio_AnalogRequest, // 130
|
||||
rio_ResetRequest, // 131
|
||||
rio_LampRequest, // 132
|
||||
rio_CheckReply, // 133
|
||||
rio_VersionReply, // 134
|
||||
rio_AnalogReply, // 135
|
||||
rio_ButtonPressed, // 136
|
||||
rio_ButtonReleased, // 137
|
||||
rio_KeyPressed, // 138
|
||||
rio_KeyReleased, // 139
|
||||
rio_TestModeChange // 140
|
||||
};
|
||||
|
||||
enum RIOStatusType {
|
||||
BoardOk, BoardMissing, BoardBad, LampBad, RestartCount, AbandonCount, FullBufferCount
|
||||
};
|
||||
|
||||
enum LampState {
|
||||
solid=0, flashSlow=1, flashMed=2, flashFast=3,
|
||||
state1Off=0x00, state1Dim=0x04, state1Bright=0x0C,
|
||||
state2Off=0x00, state2Dim=0x10, state2Bright=0x30,
|
||||
};
|
||||
|
||||
enum {
|
||||
LampSolidOff = solid + state1Off + state2Off,
|
||||
LampSolidDim = solid + state1Dim + state2Dim,
|
||||
LampSolidBright = solid + state1Bright + state2Bright
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include "public.h"
|
||||
#include "vjoyinterface.h"
|
||||
#include "c232comm.h"
|
||||
#include "CRIOMAIN.h"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#ifndef __CRIOMAIN_H__
|
||||
#define __CRIOMAIN_H__
|
||||
|
||||
|
||||
#endif
|
||||
Binary file not shown.
+3622
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
#include <iostream>
|
||||
#include <windows.h>
|
||||
#include "c232comm.h"
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
#if !defined(__C232COMM_H__)
|
||||
#define __C232COMM_H__
|
||||
|
||||
#endif // !defined(__C232COMM_H__)
|
||||
@@ -0,0 +1,206 @@
|
||||
struct hhb_vkey{
|
||||
char* name;
|
||||
uint8_t vkey;
|
||||
char* description;
|
||||
};
|
||||
const hhb_vkey hhb_vkey_list[] = {
|
||||
{ "VK_LBUTTON", 0x01, "Left mouse button" },
|
||||
{ "VK_RBUTTON", 0x02, "Right mouse button" },
|
||||
{ "VK_CANCEL", 0x03, "Control-break processing" },
|
||||
{ "VK_MBUTTON", 0x04, "Middle mouse button (three-button mouse)" },
|
||||
{ "VK_XBUTTON1", 0x05, "X1 mouse button" },
|
||||
{ "VK_XBUTTON2", 0x06, "X2 mouse button" },
|
||||
{ "-", 0x07, "Undefined" },
|
||||
{ "VK_BACK", 0x08, "BACKSPACE key" },
|
||||
{ "VK_TAB", 0x09, "TAB key" },
|
||||
//{ "-", 0x0A - 0B, "Reserved" },
|
||||
{ "VK_CLEAR", 0x0C, "CLEAR key" },
|
||||
{ "VK_RETURN", 0x0D, "ENTER key" },
|
||||
//{ "-", 0x0E - 0F, "Undefined" },
|
||||
{ "VK_SHIFT", 0x10, "SHIFT key" },
|
||||
{ "VK_CONTROL", 0x11, "CTRL key" },
|
||||
{ "VK_MENU", 0x12, "ALT key" },
|
||||
{ "VK_PAUSE", 0x13, "PAUSE key" },
|
||||
{ "VK_CAPITAL", 0x14, "CAPS LOCK key" },
|
||||
{ "VK_KANA", 0x15, "IME Kana mode" },
|
||||
{ "VK_HANGUEL", 0x15, "IME Hanguel mode (maintained for compatibility; use VK_HANGUL)" },
|
||||
{ "VK_HANGUL", 0x15, "IME Hangul mode" },
|
||||
//{ "-", 0x16, "Undefined" },
|
||||
{ "VK_JUNJA", 0x17, "IME Junja mode" },
|
||||
{ "VK_FINAL", 0x18, "IME final mode" },
|
||||
{ "VK_HANJA", 0x19, "IME Hanja mode" },
|
||||
{ "VK_KANJI", 0x19, "IME Kanji mode" },
|
||||
//{ "-", 0x1A, "Undefined" },
|
||||
{ "VK_ESCAPE", 0x1B, "ESC key" },
|
||||
{ "VK_CONVERT", 0x1C, "IME convert" },
|
||||
{ "VK_NONCONVERT", 0x1D, "IME nonconvert" },
|
||||
{ "VK_ACCEPT", 0x1E, "IME accept" },
|
||||
{ "VK_MODECHANGE", 0x1F, "IME mode change request" },
|
||||
{ "VK_SPACE", 0x20, "SPACEBAR" },
|
||||
{ "VK_PRIOR", 0x21, "PAGE UP key" },
|
||||
{ "VK_NEXT", 0x22, "PAGE DOWN key" },
|
||||
{ "VK_END", 0x23, "END key" },
|
||||
{ "VK_HOME", 0x24, "HOME key" },
|
||||
{ "VK_LEFT", 0x25, "LEFT ARROW key" },
|
||||
{ "VK_UP", 0x26, "UP ARROW key" },
|
||||
{ "VK_RIGHT", 0x27, "RIGHT ARROW key" },
|
||||
{ "VK_DOWN", 0x28, "DOWN ARROW key" },
|
||||
{ "VK_SELECT", 0x29, "SELECT key" },
|
||||
{ "VK_PRINT", 0x2A, "PRINT key" },
|
||||
{ "VK_EXECUTE", 0x2B, "EXECUTE key" },
|
||||
{ "VK_SNAPSHOT", 0x2C, "PRINT SCREEN key" },
|
||||
{ "VK_INSERT", 0x2D, "INS key" },
|
||||
{ "VK_DELETE", 0x2E, "DEL key" },
|
||||
{ "VK_HELP", 0x2F, "HELP key" },
|
||||
{ "0 key", 0x30, "0 key" },
|
||||
{ "1 key", 0x31, "1 key" },
|
||||
{ "2 key", 0x32, "2 key" },
|
||||
{ "3 key", 0x33, "3 key" },
|
||||
{ "4 key", 0x34, "4 key" },
|
||||
{ "5 key", 0x35, "5 key" },
|
||||
{ "6 key", 0x36, "6 key" },
|
||||
{ "7 key", 0x37, "7 key" },
|
||||
{ "8 key", 0x38, "8 key" },
|
||||
{ "9 key", 0x39, "9 key" },
|
||||
//{ "undefined", 0x3A - 40, "undefined" },
|
||||
{ "A key", 0x41, "A key" },
|
||||
{ "B key", 0x42, "B key" },
|
||||
{ "C key", 0x43, "C key" },
|
||||
{ "D key", 0x44, "D key" },
|
||||
{ "E key", 0x45, "E key" },
|
||||
{ "F key", 0x46, "F key" },
|
||||
{ "G key", 0x47, "G key" },
|
||||
{ "H key", 0x48, "H key" },
|
||||
{ "I key", 0x49, "I key" },
|
||||
{ "J key", 0x4A, "J key" },
|
||||
{ "K key", 0x4B, "K key" },
|
||||
{ "L key", 0x4C, "L key" },
|
||||
{ "M key", 0x4D, "M key" },
|
||||
{ "N key", 0x4E, "N key" },
|
||||
{ "O key", 0x4F, "O key" },
|
||||
{ "P key", 0x50, "P key" },
|
||||
{ "Q key", 0x51, "Q key" },
|
||||
{ "R key", 0x52, "R key" },
|
||||
{ "S key", 0x53, "S key" },
|
||||
{ "T key", 0x54, "T key" },
|
||||
{ "U key", 0x55, "U key" },
|
||||
{ "V key", 0x56, "V key" },
|
||||
{ "W key", 0x57, "W key" },
|
||||
{ "X key", 0x58, "X key" },
|
||||
{ "Y key", 0x59, "Y key" },
|
||||
{ "Z key", 0x5A, "Z key" },
|
||||
{ "VK_LWIN", 0x5B, "Left Windows key (Natural keyboard)" },
|
||||
{ "VK_RWIN", 0x5C, "Right Windows key (Natural keyboard)" },
|
||||
{ "VK_APPS", 0x5D, "Applications key (Natural keyboard)" },
|
||||
//{ "-", 0x5E, "Reserved" },
|
||||
{ "VK_SLEEP", 0x5F, "Computer Sleep key" },
|
||||
{ "VK_NUMPAD0", 0x60, "Numeric keypad 0 key" },
|
||||
{ "VK_NUMPAD1", 0x61, "Numeric keypad 1 key" },
|
||||
{ "VK_NUMPAD2", 0x62, "Numeric keypad 2 key" },
|
||||
{ "VK_NUMPAD3", 0x63, "Numeric keypad 3 key" },
|
||||
{ "VK_NUMPAD4", 0x64, "Numeric keypad 4 key" },
|
||||
{ "VK_NUMPAD5", 0x65, "Numeric keypad 5 key" },
|
||||
{ "VK_NUMPAD6", 0x66, "Numeric keypad 6 key" },
|
||||
{ "VK_NUMPAD7", 0x67, "Numeric keypad 7 key" },
|
||||
{ "VK_NUMPAD8", 0x68, "Numeric keypad 8 key" },
|
||||
{ "VK_NUMPAD9", 0x69, "Numeric keypad 9 key" },
|
||||
{ "VK_MULTIPLY", 0x6A, "Multiply key" },
|
||||
{ "VK_ADD", 0x6B, "Add key" },
|
||||
{ "VK_SEPARATOR", 0x6C, "Separator key" },
|
||||
{ "VK_SUBTRACT", 0x6D, "Subtract key" },
|
||||
{ "VK_DECIMAL", 0x6E, "Decimal key" },
|
||||
{ "VK_DIVIDE", 0x6F, "Divide key" },
|
||||
{ "VK_F1", 0x70, "F1 key" },
|
||||
{ "VK_F2", 0x71, "F2 key" },
|
||||
{ "VK_F3", 0x72, "F3 key" },
|
||||
{ "VK_F4", 0x73, "F4 key" },
|
||||
{ "VK_F5", 0x74, "F5 key" },
|
||||
{ "VK_F6", 0x75, "F6 key" },
|
||||
{ "VK_F7", 0x76, "F7 key" },
|
||||
{ "VK_F8", 0x77, "F8 key" },
|
||||
{ "VK_F9", 0x78, "F9 key" },
|
||||
{ "VK_F10", 0x79, "F10 key" },
|
||||
{ "VK_F11", 0x7A, "F11 key" },
|
||||
{ "VK_F12", 0x7B, "F12 key" },
|
||||
{ "VK_F13", 0x7C, "F13 key" },
|
||||
{ "VK_F14", 0x7D, "F14 key" },
|
||||
{ "VK_F15", 0x7E, "F15 key" },
|
||||
{ "VK_F16", 0x7F, "F16 key" },
|
||||
{ "VK_F17", 0x80, "F17 key" },
|
||||
{ "VK_F18", 0x81, "F18 key" },
|
||||
{ "VK_F19", 0x82, "F19 key" },
|
||||
{ "VK_F20", 0x83, "F20 key" },
|
||||
{ "VK_F21", 0x84, "F21 key" },
|
||||
{ "VK_F22", 0x85, "F22 key" },
|
||||
{ "VK_F23", 0x86, "F23 key" },
|
||||
{ "VK_F24", 0x87, "F24 key" },
|
||||
//{ "-", 0x88 - 8F, "Unassigned" },
|
||||
{ "VK_NUMLOCK", 0x90, "NUM LOCK key" },
|
||||
{ "VK_SCROLL", 0x91, "SCROLL LOCK key" },
|
||||
//{ "-", 0x88 - 8F, "Unassigned" },
|
||||
{ "VK_NUMLOCK", 0x90, "NUM LOCK key" },
|
||||
{ "VK_SCROLL", 0x91, "SCROLL LOCK key" },
|
||||
//{"-", 0x92-96,"OEM specific"},
|
||||
//{ "-", 0x97 - 9F, "Unassigned" },
|
||||
{ "VK_LSHIFT", 0xA0, "Left SHIFT key" },
|
||||
{ "VK_RSHIFT", 0xA1, "Right SHIFT key" },
|
||||
{ "VK_LCONTROL", 0xA2, "Left CONTROL key" },
|
||||
{ "VK_RCONTROL", 0xA3, "Right CONTROL key" },
|
||||
{ "VK_LMENU", 0xA4, "Left MENU key" },
|
||||
{ "VK_RMENU", 0xA5, "Right MENU key" },
|
||||
{ "VK_BROWSER_BACK", 0xA6, "Browser Back key" },
|
||||
{ "VK_BROWSER_FORWARD", 0xA7, "Browser Forward key" },
|
||||
{ "VK_BROWSER_REFRESH", 0xA8, "Browser Refresh key" },
|
||||
{ "VK_BROWSER_STOP", 0xA9, "Browser Stop key" },
|
||||
{ "VK_BROWSER_SEARCH", 0xAA, "Browser Search key" },
|
||||
{ "VK_BROWSER_FAVORITES", 0xAB, "Browser Favorites key" },
|
||||
{ "VK_BROWSER_HOME", 0xAC, "Browser Start and Home key" },
|
||||
{ "VK_VOLUME_MUTE", 0xAD, "Volume Mute key" },
|
||||
{ "VK_VOLUME_DOWN", 0xAE, "Volume Down key" },
|
||||
{ "VK_VOLUME_UP", 0xAF, "Volume Up key" },
|
||||
{ "VK_MEDIA_NEXT_TRACK", 0xB0, "Next Track key" },
|
||||
{ "VK_MEDIA_PREV_TRACK", 0xB1, "Previous Track key" },
|
||||
{ "VK_MEDIA_STOP", 0xB2, "Stop Media key" },
|
||||
{ "VK_MEDIA_PLAY_PAUSE", 0xB3, "Play/Pause Media key" },
|
||||
{ "VK_LAUNCH_MAIL", 0xB4, "Start Mail key" },
|
||||
{ "VK_LAUNCH_MEDIA_SELECT", 0xB5, "Select Media key" },
|
||||
{ "VK_LAUNCH_APP1", 0xB6, "Start Application 1 key" },
|
||||
{ "VK_LAUNCH_APP2", 0xB7, "Start Application 2 key" },
|
||||
//{ "-", 0xB8 - B9, "Reserved" },
|
||||
{ "VK_OEM_1", 0xBA, "Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \';:\' key VK_OEM_PLUS" },
|
||||
{"VK_OEM_PLUS", 0xBB, "For any country/region, the \'+\' key"},
|
||||
{ "VK_OEM_COMMA", 0xBC, "For any country/region, the \',\' key" },
|
||||
{ "VK_OEM_MINUS", 0xBD, "For any country/region, the \'-\' key" },
|
||||
{ "VK_OEM_PERIOD", 0xBE, "For any country/region, the \'.\' key" },
|
||||
{ "VK_OEM_2", 0xBF, "Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \'/?\' key" },
|
||||
{ "VK_OEM_3", 0xC0, "Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \'`~\' key" },
|
||||
//{ "-", 0xC1 - D7, "Reserved" },
|
||||
//{ "-", 0xD8 - DA, "Unassigned" },
|
||||
{ "VK_OEM_4", 0xDB, "Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \'[{\' key" },
|
||||
{ "VK_OEM_5", 0xDC, "Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \'\\|\' key" },
|
||||
{ "VK_OEM_6", 0xDD, "Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \']}\' key" },
|
||||
{ "VK_OEM_7", 0xDE, "Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \'single-quote/double-quote\' key" },
|
||||
{ "VK_OEM_8", 0xDF, "Used for miscellaneous characters; it can vary by keyboard." },
|
||||
//{ "-", 0xE0, "Reserved" },
|
||||
//{ "-", 0xE1, "OEM specific" },
|
||||
{ "VK_OEM_102", 0xE2, "Either the angle bracket key or the backslash key on the RT 102-key keyboard" },
|
||||
//{ "-", 0xE3 - E4, "OEM specific" },
|
||||
{ "VK_PROCESSKEY", 0xE5, "IME PROCESS key" },
|
||||
//{ "-", 0xE6, "OEM specific" },
|
||||
{ "VK_PACKET", 0xE7, "Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP" },
|
||||
//{ "-", 0xE8, "Unassigned" },
|
||||
// {"-",0xE6,"OEM specific"},
|
||||
{"VK_PACKET",0xE7,"Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP"},
|
||||
// {"-",0xE8,"Unassigned"},
|
||||
//{ "-", 0xE9 - F5, "OEM specific" },
|
||||
{ "VK_ATTN", 0xF6, "Attn key" },
|
||||
{ "VK_CRSEL", 0xF7, "CrSel key" },
|
||||
{ "VK_EXSEL", 0xF8, "ExSel key" },
|
||||
{ "VK_EREOF", 0xF9, "Erase EOF key" },
|
||||
{ "VK_PLAY", 0xFA, "Play key" },
|
||||
{ "VK_ZOOM", 0xFB, "Zoom key" },
|
||||
{ "VK_NONAME", 0xFC, "Reserved" },
|
||||
{ "VK_PA1", 0xFD, "PA1 key" },
|
||||
{ "VK_OEM_CLEAR", 0xFE, "Clear key" }
|
||||
|
||||
};
|
||||
+232
@@ -0,0 +1,232 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) Shaul Eizikovich. All rights reserved.
|
||||
|
||||
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
|
||||
PURPOSE.
|
||||
|
||||
Module Name:
|
||||
|
||||
public.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Public header file for the vJoy project
|
||||
Developpers that need to interface with vJoy need to include this file
|
||||
|
||||
Author:
|
||||
|
||||
|
||||
Environment:
|
||||
|
||||
kernel mode and User mode
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
Revision History:
|
||||
|
||||
|
||||
--*/
|
||||
#ifndef _PUBLIC_H
|
||||
#define _PUBLIC_H
|
||||
|
||||
// Compilation directives
|
||||
#define PPJOY_MODE
|
||||
#undef PPJOY_MODE // Comment-out for compatibility mode
|
||||
|
||||
#ifdef PPJOY_MODE
|
||||
#include "PPJIoctl.h"
|
||||
#endif
|
||||
|
||||
#include <INITGUID.H> // Definitions for controlling GUID initialization
|
||||
|
||||
// Sideband comunication with vJoy Device
|
||||
//{781EF630-72B2-11d2-B852-00C04FAD5101}
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_VJOY, 0x781EF630, 0x72B2, 0x11d2, 0xB8, 0x52, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x01);
|
||||
|
||||
//
|
||||
// Usage example:
|
||||
// CreateFile(TEXT("\\\\.\\vJoy"), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
#ifdef PPJOY_MODE
|
||||
#define DEVICENAME_STRING "PPJoyIOCTL1"
|
||||
#else
|
||||
#define DEVICENAME_STRING "vJoy"
|
||||
#endif
|
||||
#define NTDEVICE_NAME_STRING "\\Device\\"DEVICENAME_STRING
|
||||
#define SYMBOLIC_NAME_STRING "\\DosDevices\\"DEVICENAME_STRING
|
||||
#define DOS_FILE_NAME "\\\\.\\"DEVICENAME_STRING
|
||||
#define VJOY_INTERFACE L"Device_"
|
||||
|
||||
// Version parts
|
||||
#define VER_X_ 0
|
||||
#define VER_H_ 2
|
||||
#define VER_M_ 0
|
||||
#define VER_L_ 5
|
||||
|
||||
#define STRINGIFY_1(x) #x
|
||||
#define STRINGIFY(x) STRINGIFY_1(x)
|
||||
#define PASTE(x, y) x##y
|
||||
#define MAKEWIDE(x) PASTE(L,x)
|
||||
|
||||
// Device Attributes
|
||||
//
|
||||
#define VENDOR_N_ID 0x1234
|
||||
#define PRODUCT_N_ID 0xBEAD
|
||||
#define VERSION_N (VER_L_ + 0x10*VER_M_ + 0x100*VER_H_ + 0x1000*VER_X_)
|
||||
|
||||
// Device Strings
|
||||
//
|
||||
#define VENDOR_STR_ID L"Shaul Eizikovich"
|
||||
#define PRODUCT_STR_ID L"vJoy - Virtual Joystick"
|
||||
#define SERIALNUMBER_STR MAKEWIDE(STRINGIFY(VER_H_)) L"." MAKEWIDE(STRINGIFY(VER_M_)) L"." MAKEWIDE(STRINGIFY(VER_L_))
|
||||
|
||||
// Function codes;
|
||||
//#define LOAD_POSITIONS 0x910
|
||||
//#define GETATTRIB 0x911
|
||||
// #define GET_FFB_DATA 0x00222912 // METHOD_OUT_DIRECT + FILE_DEVICE_UNKNOWN + FILE_ANY_ACCESS
|
||||
//#define SET_FFB_STAT 0x913 // METHOD_NEITHER
|
||||
//#define GET_FFB_STAT 0x916
|
||||
|
||||
#define F_LOAD_POSITIONS 0x910
|
||||
#define F_GETATTRIB 0x911
|
||||
#define F_GET_FFB_DATA 0x912
|
||||
#define F_SET_FFB_STAT 0x913
|
||||
#define F_GET_FFB_STAT 0x916
|
||||
#define F_GET_DEV_INFO 0x917
|
||||
// IO Device Control codes;
|
||||
#define IOCTL_VJOY_GET_ATTRIB CTL_CODE (FILE_DEVICE_UNKNOWN, GETATTRIB, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define LOAD_POSITIONS CTL_CODE (FILE_DEVICE_UNKNOWN, F_LOAD_POSITIONS, METHOD_BUFFERED, FILE_WRITE_ACCESS)
|
||||
#define GET_FFB_DATA CTL_CODE (FILE_DEVICE_UNKNOWN, F_GET_FFB_DATA, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
|
||||
#define SET_FFB_STAT CTL_CODE (FILE_DEVICE_UNKNOWN, F_SET_FFB_STAT, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
#define GET_FFB_STAT CTL_CODE (FILE_DEVICE_UNKNOWN, F_GET_FFB_STAT, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define GET_DEV_INFO CTL_CODE (FILE_DEVICE_UNKNOWN, F_GET_DEV_INFO, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#ifndef __HIDPORT_H__
|
||||
// Copied from hidport.h
|
||||
#define IOCTL_HID_SET_FEATURE 0xB0191
|
||||
#define IOCTL_HID_WRITE_REPORT 0xB000F
|
||||
|
||||
|
||||
typedef struct _HID_DEVICE_ATTRIBUTES {
|
||||
|
||||
ULONG Size;
|
||||
//
|
||||
// sizeof (struct _HID_DEVICE_ATTRIBUTES)
|
||||
//
|
||||
|
||||
//
|
||||
// Vendor ids of this hid device
|
||||
//
|
||||
USHORT VendorID;
|
||||
USHORT ProductID;
|
||||
USHORT VersionNumber;
|
||||
USHORT Reserved[11];
|
||||
|
||||
} HID_DEVICE_ATTRIBUTES, * PHID_DEVICE_ATTRIBUTES;
|
||||
#endif
|
||||
|
||||
// Error levels for status report
|
||||
enum ERRLEVEL {INFO, WARN, ERR, FATAL, APP};
|
||||
// Status report function prototype
|
||||
#ifdef WINAPI
|
||||
typedef BOOL (WINAPI *StatusMessageFunc)(void * output, TCHAR * buffer, enum ERRLEVEL level);
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////// Joystick Position ///////////////////////
|
||||
//
|
||||
// This structure holds data that is passed to the device from
|
||||
// an external application such as SmartPropoPlus.
|
||||
//
|
||||
// Usage example:
|
||||
// JOYSTICK_POSITION iReport;
|
||||
// :
|
||||
// DeviceIoControl (hDevice, 100, &iReport, sizeof(HID_INPUT_REPORT), NULL, 0, &bytes, NULL)
|
||||
|
||||
/*
|
||||
typedef struct _JOYSTICK_POSITION
|
||||
{
|
||||
BYTE bDevice; // Index of device. 1-based.
|
||||
LONG wThrottle;
|
||||
LONG wRudder;
|
||||
LONG wAileron;
|
||||
LONG wAxisX;
|
||||
LONG wAxisY;
|
||||
LONG wAxisZ;
|
||||
LONG wAxisXRot;
|
||||
LONG wAxisYRot;
|
||||
LONG wAxisZRot;
|
||||
LONG wSlider;
|
||||
LONG wDial;
|
||||
LONG wWheel;
|
||||
LONG wAxisVX;
|
||||
LONG wAxisVY;
|
||||
LONG wAxisVZ;
|
||||
LONG wAxisVBRX;
|
||||
LONG wAxisVBRY;
|
||||
LONG wAxisVBRZ;
|
||||
LONG lButtons; // 32 buttons: 0x00000001 means button1 is pressed, 0x80000000 -> button32 is pressed
|
||||
DWORD bHats; // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
|
||||
DWORD bHatsEx1; // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
|
||||
DWORD bHatsEx2; // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
|
||||
DWORD bHatsEx3; // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
|
||||
} JOYSTICK_POSITION, *PJOYSTICK_POSITION;
|
||||
*/
|
||||
|
||||
// Superset of JOYSTICK_POSITION
|
||||
// Extension of JOYSTICK_POSITION with Buttons 33-128 appended to the end of the structure.
|
||||
typedef struct _JOYSTICK_POSITION_V2
|
||||
{
|
||||
/// JOYSTICK_POSITION
|
||||
BYTE bDevice; // Index of device. 1-based.
|
||||
LONG wThrottle;
|
||||
LONG wRudder;
|
||||
LONG wAileron;
|
||||
LONG wAxisX;
|
||||
LONG wAxisY;
|
||||
LONG wAxisZ;
|
||||
LONG wAxisXRot;
|
||||
LONG wAxisYRot;
|
||||
LONG wAxisZRot;
|
||||
LONG wSlider;
|
||||
LONG wDial;
|
||||
LONG wWheel;
|
||||
LONG wAxisVX;
|
||||
LONG wAxisVY;
|
||||
LONG wAxisVZ;
|
||||
LONG wAxisVBRX;
|
||||
LONG wAxisVBRY;
|
||||
LONG wAxisVBRZ;
|
||||
LONG lButtons; // 32 buttons: 0x00000001 means button1 is pressed, 0x80000000 -> button32 is pressed
|
||||
DWORD bHats; // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
|
||||
DWORD bHatsEx1; // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
|
||||
DWORD bHatsEx2; // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
|
||||
DWORD bHatsEx3; // Lower 4 bits: HAT switch or 16-bit of continuous HAT switch
|
||||
|
||||
/// JOYSTICK_POSITION_V2 Extenssion
|
||||
LONG lButtonsEx1; // Buttons 33-64
|
||||
LONG lButtonsEx2; // Buttons 65-96
|
||||
LONG lButtonsEx3; // Buttons 97-128
|
||||
} JOYSTICK_POSITION_V2, *PJOYSTICK_POSITION_V2;
|
||||
|
||||
|
||||
// HID Descriptor definitions
|
||||
#define HID_USAGE_X 0x30
|
||||
#define HID_USAGE_Y 0x31
|
||||
#define HID_USAGE_Z 0x32
|
||||
#define HID_USAGE_RX 0x33
|
||||
#define HID_USAGE_RY 0x34
|
||||
#define HID_USAGE_RZ 0x35
|
||||
#define HID_USAGE_SL0 0x36
|
||||
#define HID_USAGE_SL1 0x37
|
||||
#define HID_USAGE_WHL 0x38
|
||||
#define HID_USAGE_POV 0x39
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+2552
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,37 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.4.33205.214
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "riovjoy2", "riovjoy2.vcxproj", "{960CFE0F-1508-4322-8A91-56E763A14E40}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
WinXP|x64 = WinXP|x64
|
||||
WinXP|x86 = WinXP|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.Debug|x64.Build.0 = Debug|x64
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.Debug|x86.Build.0 = Debug|Win32
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.Release|x64.ActiveCfg = Release|x64
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.Release|x64.Build.0 = Release|x64
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.Release|x86.ActiveCfg = Release|Win32
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.Release|x86.Build.0 = Release|Win32
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.WinXP|x64.ActiveCfg = WinXP|x64
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.WinXP|x64.Build.0 = WinXP|x64
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.WinXP|x86.ActiveCfg = WinXP|Win32
|
||||
{960CFE0F-1508-4322-8A91-56E763A14E40}.WinXP|x86.Build.0 = WinXP|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {BEB6DA97-9C84-49B2-BF49-0318C05AF72E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,245 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="WinXP|Win32">
|
||||
<Configuration>WinXP</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="WinXP|x64">
|
||||
<Configuration>WinXP</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{960cfe0f-1508-4322-8a91-56e763a14e40}</ProjectGuid>
|
||||
<RootNamespace>riovjoy2</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='WinXP|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141_xp</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>Static</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='WinXP|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='WinXP|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='WinXP|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<CopyCppRuntimeToOutputDir>false</CopyCppRuntimeToOutputDir>
|
||||
<CopyLocalProjectReference>false</CopyLocalProjectReference>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='WinXP|Win32'">
|
||||
<CopyCppRuntimeToOutputDir>false</CopyCppRuntimeToOutputDir>
|
||||
<CopyLocalProjectReference>false</CopyLocalProjectReference>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<CopyLocalProjectReference>false</CopyLocalProjectReference>
|
||||
<CopyCppRuntimeToOutputDir>false</CopyCppRuntimeToOutputDir>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>Default</LanguageStandard>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>vJoyInterface.exp;user32.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\Users\cyd\source\repos\riovjoy2\static_debug_vJoy;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>C:\Users\cyd\source\repos\riovjoy2\satic_release_vJoy;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>vJoyInterface.exp;user32.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='WinXP|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>false</ConformanceMode>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>C:\Users\cyd\source\repos\riovjoy2\WinXP\vjoyinterface-x86-XPcompat;C:\WinDDK\7600.16385.1\lib\wxp\i386;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>vJoyInterface.lib;user32.lib;advapi32.lib;hid.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<UseLibraryDependencyInputs>true</UseLibraryDependencyInputs>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='WinXP|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="riovjoy2.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="public.h" />
|
||||
<ClInclude Include="SimpleIni.h" />
|
||||
<ClInclude Include="vjoyinterface.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="satic_release_vJoy\vJoyInterface.dll" />
|
||||
<None Include="satic_release_vJoy\vJoyInterface.exp" />
|
||||
<None Include="satic_release_vJoy\vJoyInterface.map" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="satic_release_vJoy\vJoyInterface.lib" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="riovjoy2.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SimpleIni.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="vjoyinterface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="public.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="static_debug_vJoy\vJoyInterface.exp">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="static_debug_vJoy\vJoyInterface.idb">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="static_debug_vJoy\vJoyInterface.pdb">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Library Include="static_debug_vJoy\vJoyInterface.lib">
|
||||
<Filter>Resource Files</Filter>
|
||||
</Library>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// riovjoy.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#include <windows.h>
|
||||
#include <basetyps.h>
|
||||
#include <cfgmgr32.h>
|
||||
#include <Setupapi.h>
|
||||
#include <strsafe.h>
|
||||
#include <Newdev.h>
|
||||
#include <INITGUID.H>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <string.h>
|
||||
#include "SimpleIni.h"
|
||||
#include "vjoyinterface.h"
|
||||
#include "public.h"
|
||||
#include "c232comm.h"
|
||||
#include "CPlasma.h"
|
||||
#include "CRIO.h"
|
||||
#include "CRIOMAIN.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: reference additional headers your program requires here
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,107 @@
|
||||
// The following ifdef block is the standard way of creating macros which make exporting
|
||||
// from a DLL simpler. All files within this DLL are compiled with the VJOYINTERFACE_EXPORTS
|
||||
// symbol defined on the command line. this symbol should not be defined on any project
|
||||
// that uses this DLL. This way any other project whose source files include this file see
|
||||
// VJOYINTERFACE_API functions as being imported from a DLL, whereas this DLL sees symbols
|
||||
// defined with this macro as being exported.
|
||||
#ifdef VJOYINTERFACE_EXPORTS
|
||||
#define VJOYINTERFACE_API __declspec(dllexport)
|
||||
#else
|
||||
#define VJOYINTERFACE_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
///////////////////////////// vJoy device (collection) status ////////////////////////////////////////////
|
||||
#ifndef VJDSTAT
|
||||
#define VJDSTAT
|
||||
enum VjdStat /* Declares an enumeration data type called BOOLEAN */
|
||||
{
|
||||
VJD_STAT_OWN, // The vJoy Device is owned by this application.
|
||||
VJD_STAT_FREE, // The vJoy Device is NOT owned by any application (including this one).
|
||||
VJD_STAT_BUSY, // The vJoy Device is owned by another application. It cannot be acquired by this application.
|
||||
VJD_STAT_MISS, // The vJoy Device is missing. It either does not exist or the driver is down.
|
||||
VJD_STAT_UNKN // Unknown
|
||||
};
|
||||
|
||||
/* Error codes for some of the functions */
|
||||
#define NO_HANDLE_BY_INDEX -1
|
||||
#define BAD_PREPARSED_DATA -2
|
||||
#define NO_CAPS -3
|
||||
#define BAD_N_BTN_CAPS -4
|
||||
#define BAD_CALLOC -5
|
||||
#define BAD_BTN_CAPS -6
|
||||
#define BAD_BTN_RANGE -7
|
||||
#define BAD_N_VAL_CAPS -8
|
||||
#define BAD_ID_RANGE -9
|
||||
#define NO_SUCH_AXIS -10
|
||||
|
||||
/* Environment Variables */
|
||||
#define INTERFACE_LOG_LEVEL "VJOYINTERFACELOGLEVEL"
|
||||
#define INTERFACE_LOG_FILE "VJOYINTERFACELOGFILE"
|
||||
#define INTERFACE_DEF_LOG_FILE "vJoyInterface.log"
|
||||
|
||||
struct DEV_INFO {
|
||||
BYTE DeviceID; // Device ID: Valid values are 1-16
|
||||
BYTE nImplemented; // Number of implemented device: Valid values are 1-16
|
||||
BYTE isImplemented; // Is this device implemented?
|
||||
BYTE MaxDevices; // Maximum number of devices that may be implemented (16)
|
||||
BYTE DriverFFB; // Does this driver support FFB (False)
|
||||
BYTE DeviceFFB; // Does this device support FFB (False)
|
||||
} ;
|
||||
|
||||
typedef void (CALLBACK *RemovalCB)(BOOL, BOOL, PVOID);
|
||||
|
||||
#endif
|
||||
extern "C" {
|
||||
///////////////////////////// vJoy device (collection) Control interface /////////////////////////////////
|
||||
/*
|
||||
These functions allow writing feeders and other applications that interface with vJoy
|
||||
It is assumed that only one vJoy top-device (= Raw PDO) exists.
|
||||
This top-level device can have up to 16 siblings (=top-level Reports/collections)
|
||||
Each sibling is refered to as a "vJoy Device" and is attributed a unique Report ID (Range: 1-16).
|
||||
|
||||
Naming convetion:
|
||||
VJD = vJoy Device
|
||||
rID = Report ID
|
||||
*/
|
||||
|
||||
///// General driver data
|
||||
VJOYINTERFACE_API SHORT __cdecl GetvJoyVersion(void);
|
||||
VJOYINTERFACE_API BOOL __cdecl vJoyEnabled(void);
|
||||
VJOYINTERFACE_API PVOID __cdecl GetvJoyProductString(void);
|
||||
VJOYINTERFACE_API PVOID __cdecl GetvJoyManufacturerString(void);
|
||||
VJOYINTERFACE_API PVOID __cdecl GetvJoySerialNumberString(void);
|
||||
VJOYINTERFACE_API BOOL __cdecl DriverMatch(WORD * DllVer, WORD * DrvVer);
|
||||
VJOYINTERFACE_API VOID __cdecl RegisterRemovalCB(RemovalCB cb, PVOID data);
|
||||
|
||||
|
||||
///// vJoy Device properties
|
||||
VJOYINTERFACE_API int __cdecl GetVJDButtonNumber(UINT rID); // Get the number of buttons defined in the specified VDJ
|
||||
VJOYINTERFACE_API int __cdecl GetVJDDiscPovNumber(UINT rID); // Get the number of descrete-type POV hats defined in the specified VDJ
|
||||
VJOYINTERFACE_API int __cdecl GetVJDContPovNumber(UINT rID); // Get the number of descrete-type POV hats defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl GetVJDAxisExist(UINT rID, UINT Axis); // Test if given axis defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl GetVJDAxisMax(UINT rID, UINT Axis, LONG * Max); // Get logical Maximum value for a given axis defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl GetVJDAxisMin(UINT rID, UINT Axis, LONG * Min); // Get logical Minimum value for a given axis defined in the specified VDJ
|
||||
|
||||
///// Write access to vJoy Device - Basic
|
||||
VJOYINTERFACE_API BOOL __cdecl AcquireVJD(UINT rID); // Acquire the specified vJoy Device.
|
||||
VJOYINTERFACE_API VOID __cdecl RelinquishVJD(UINT rID); // Relinquish the specified vJoy Device.
|
||||
VJOYINTERFACE_API BOOL __cdecl UpdateVJD(UINT rID, PVOID pData); // Update the position data of the specified vJoy Device.
|
||||
VJOYINTERFACE_API enum VjdStat __cdecl GetVJDStatus(UINT rID); // Get the status of the specified vJoy Device.
|
||||
|
||||
///// Write access to vJoy Device - Modifyiers
|
||||
// This group of functions modify the current value of the position data
|
||||
// They replace the need to create a structure of position data then call UpdateVJD
|
||||
|
||||
//// Reset functions
|
||||
VJOYINTERFACE_API BOOL __cdecl ResetVJD(UINT rID); // Reset all controls to predefined values in the specified VDJ
|
||||
VJOYINTERFACE_API VOID __cdecl ResetAll(void); // Reset all controls to predefined values in all VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl ResetButtons(UINT rID); // Reset all buttons (To 0) in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl ResetPovs(UINT rID); // Reset all POV Switches (To -1) in the specified VDJ
|
||||
|
||||
// Write data
|
||||
VJOYINTERFACE_API BOOL __cdecl SetAxis(LONG Value, UINT rID, UINT Axis); // Write Value to a given axis defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl SetBtn(BOOL Value, UINT rID, UCHAR nBtn); // Write Value to a given button defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl SetDiscPov(int Value, UINT rID, UCHAR nPov); // Write Value to a given descrete POV defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl SetContPov(DWORD Value, UINT rID, UCHAR nPov); // Write Value to a given continuous POV defined in the specified VDJ
|
||||
|
||||
} // extern "C"
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,107 @@
|
||||
// The following ifdef block is the standard way of creating macros which make exporting
|
||||
// from a DLL simpler. All files within this DLL are compiled with the VJOYINTERFACE_EXPORTS
|
||||
// symbol defined on the command line. this symbol should not be defined on any project
|
||||
// that uses this DLL. This way any other project whose source files include this file see
|
||||
// VJOYINTERFACE_API functions as being imported from a DLL, whereas this DLL sees symbols
|
||||
// defined with this macro as being exported.
|
||||
#ifdef VJOYINTERFACE_EXPORTS
|
||||
#define VJOYINTERFACE_API __declspec(dllexport)
|
||||
#else
|
||||
#define VJOYINTERFACE_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
///////////////////////////// vJoy device (collection) status ////////////////////////////////////////////
|
||||
#ifndef VJDSTAT
|
||||
#define VJDSTAT
|
||||
enum VjdStat /* Declares an enumeration data type called BOOLEAN */
|
||||
{
|
||||
VJD_STAT_OWN, // The vJoy Device is owned by this application.
|
||||
VJD_STAT_FREE, // The vJoy Device is NOT owned by any application (including this one).
|
||||
VJD_STAT_BUSY, // The vJoy Device is owned by another application. It cannot be acquired by this application.
|
||||
VJD_STAT_MISS, // The vJoy Device is missing. It either does not exist or the driver is down.
|
||||
VJD_STAT_UNKN // Unknown
|
||||
};
|
||||
|
||||
/* Error codes for some of the functions */
|
||||
#define NO_HANDLE_BY_INDEX -1
|
||||
#define BAD_PREPARSED_DATA -2
|
||||
#define NO_CAPS -3
|
||||
#define BAD_N_BTN_CAPS -4
|
||||
#define BAD_CALLOC -5
|
||||
#define BAD_BTN_CAPS -6
|
||||
#define BAD_BTN_RANGE -7
|
||||
#define BAD_N_VAL_CAPS -8
|
||||
#define BAD_ID_RANGE -9
|
||||
#define NO_SUCH_AXIS -10
|
||||
|
||||
/* Environment Variables */
|
||||
#define INTERFACE_LOG_LEVEL "VJOYINTERFACELOGLEVEL"
|
||||
#define INTERFACE_LOG_FILE "VJOYINTERFACELOGFILE"
|
||||
#define INTERFACE_DEF_LOG_FILE "vJoyInterface.log"
|
||||
|
||||
struct DEV_INFO {
|
||||
BYTE DeviceID; // Device ID: Valid values are 1-16
|
||||
BYTE nImplemented; // Number of implemented device: Valid values are 1-16
|
||||
BYTE isImplemented; // Is this device implemented?
|
||||
BYTE MaxDevices; // Maximum number of devices that may be implemented (16)
|
||||
BYTE DriverFFB; // Does this driver support FFB (False)
|
||||
BYTE DeviceFFB; // Does this device support FFB (False)
|
||||
} ;
|
||||
|
||||
typedef void (CALLBACK *RemovalCB)(BOOL, BOOL, PVOID);
|
||||
|
||||
#endif
|
||||
extern "C" {
|
||||
///////////////////////////// vJoy device (collection) Control interface /////////////////////////////////
|
||||
/*
|
||||
These functions allow writing feeders and other applications that interface with vJoy
|
||||
It is assumed that only one vJoy top-device (= Raw PDO) exists.
|
||||
This top-level device can have up to 16 siblings (=top-level Reports/collections)
|
||||
Each sibling is refered to as a "vJoy Device" and is attributed a unique Report ID (Range: 1-16).
|
||||
|
||||
Naming convetion:
|
||||
VJD = vJoy Device
|
||||
rID = Report ID
|
||||
*/
|
||||
|
||||
///// General driver data
|
||||
VJOYINTERFACE_API SHORT __cdecl GetvJoyVersion(void);
|
||||
VJOYINTERFACE_API BOOL __cdecl vJoyEnabled(void);
|
||||
VJOYINTERFACE_API PVOID __cdecl GetvJoyProductString(void);
|
||||
VJOYINTERFACE_API PVOID __cdecl GetvJoyManufacturerString(void);
|
||||
VJOYINTERFACE_API PVOID __cdecl GetvJoySerialNumberString(void);
|
||||
VJOYINTERFACE_API BOOL __cdecl DriverMatch(WORD * DllVer, WORD * DrvVer);
|
||||
VJOYINTERFACE_API VOID __cdecl RegisterRemovalCB(RemovalCB cb, PVOID data);
|
||||
|
||||
|
||||
///// vJoy Device properties
|
||||
VJOYINTERFACE_API int __cdecl GetVJDButtonNumber(UINT rID); // Get the number of buttons defined in the specified VDJ
|
||||
VJOYINTERFACE_API int __cdecl GetVJDDiscPovNumber(UINT rID); // Get the number of descrete-type POV hats defined in the specified VDJ
|
||||
VJOYINTERFACE_API int __cdecl GetVJDContPovNumber(UINT rID); // Get the number of descrete-type POV hats defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl GetVJDAxisExist(UINT rID, UINT Axis); // Test if given axis defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl GetVJDAxisMax(UINT rID, UINT Axis, LONG * Max); // Get logical Maximum value for a given axis defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl GetVJDAxisMin(UINT rID, UINT Axis, LONG * Min); // Get logical Minimum value for a given axis defined in the specified VDJ
|
||||
|
||||
///// Write access to vJoy Device - Basic
|
||||
VJOYINTERFACE_API BOOL __cdecl AcquireVJD(UINT rID); // Acquire the specified vJoy Device.
|
||||
VJOYINTERFACE_API VOID __cdecl RelinquishVJD(UINT rID); // Relinquish the specified vJoy Device.
|
||||
VJOYINTERFACE_API BOOL __cdecl UpdateVJD(UINT rID, PVOID pData); // Update the position data of the specified vJoy Device.
|
||||
VJOYINTERFACE_API enum VjdStat __cdecl GetVJDStatus(UINT rID); // Get the status of the specified vJoy Device.
|
||||
|
||||
///// Write access to vJoy Device - Modifyiers
|
||||
// This group of functions modify the current value of the position data
|
||||
// They replace the need to create a structure of position data then call UpdateVJD
|
||||
|
||||
//// Reset functions
|
||||
VJOYINTERFACE_API BOOL __cdecl ResetVJD(UINT rID); // Reset all controls to predefined values in the specified VDJ
|
||||
VJOYINTERFACE_API VOID __cdecl ResetAll(void); // Reset all controls to predefined values in all VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl ResetButtons(UINT rID); // Reset all buttons (To 0) in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl ResetPovs(UINT rID); // Reset all POV Switches (To -1) in the specified VDJ
|
||||
|
||||
// Write data
|
||||
VJOYINTERFACE_API BOOL __cdecl SetAxis(LONG Value, UINT rID, UINT Axis); // Write Value to a given axis defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl SetBtn(BOOL Value, UINT rID, UCHAR nBtn); // Write Value to a given button defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl SetDiscPov(int Value, UINT rID, UCHAR nPov); // Write Value to a given descrete POV defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl SetContPov(DWORD Value, UINT rID, UCHAR nPov); // Write Value to a given continuous POV defined in the specified VDJ
|
||||
|
||||
} // extern "C"
|
||||
@@ -0,0 +1,107 @@
|
||||
// The following ifdef block is the standard way of creating macros which make exporting
|
||||
// from a DLL simpler. All files within this DLL are compiled with the VJOYINTERFACE_EXPORTS
|
||||
// symbol defined on the command line. this symbol should not be defined on any project
|
||||
// that uses this DLL. This way any other project whose source files include this file see
|
||||
// VJOYINTERFACE_API functions as being imported from a DLL, whereas this DLL sees symbols
|
||||
// defined with this macro as being exported.
|
||||
#ifdef VJOYINTERFACE_EXPORTS
|
||||
#define VJOYINTERFACE_API __declspec(dllexport)
|
||||
#else
|
||||
#define VJOYINTERFACE_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
///////////////////////////// vJoy device (collection) status ////////////////////////////////////////////
|
||||
#ifndef VJDSTAT
|
||||
#define VJDSTAT
|
||||
enum VjdStat /* Declares an enumeration data type called BOOLEAN */
|
||||
{
|
||||
VJD_STAT_OWN, // The vJoy Device is owned by this application.
|
||||
VJD_STAT_FREE, // The vJoy Device is NOT owned by any application (including this one).
|
||||
VJD_STAT_BUSY, // The vJoy Device is owned by another application. It cannot be acquired by this application.
|
||||
VJD_STAT_MISS, // The vJoy Device is missing. It either does not exist or the driver is down.
|
||||
VJD_STAT_UNKN // Unknown
|
||||
};
|
||||
|
||||
/* Error codes for some of the functions */
|
||||
#define NO_HANDLE_BY_INDEX -1
|
||||
#define BAD_PREPARSED_DATA -2
|
||||
#define NO_CAPS -3
|
||||
#define BAD_N_BTN_CAPS -4
|
||||
#define BAD_CALLOC -5
|
||||
#define BAD_BTN_CAPS -6
|
||||
#define BAD_BTN_RANGE -7
|
||||
#define BAD_N_VAL_CAPS -8
|
||||
#define BAD_ID_RANGE -9
|
||||
#define NO_SUCH_AXIS -10
|
||||
|
||||
/* Environment Variables */
|
||||
#define INTERFACE_LOG_LEVEL "VJOYINTERFACELOGLEVEL"
|
||||
#define INTERFACE_LOG_FILE "VJOYINTERFACELOGFILE"
|
||||
#define INTERFACE_DEF_LOG_FILE "vJoyInterface.log"
|
||||
|
||||
struct DEV_INFO {
|
||||
BYTE DeviceID; // Device ID: Valid values are 1-16
|
||||
BYTE nImplemented; // Number of implemented device: Valid values are 1-16
|
||||
BYTE isImplemented; // Is this device implemented?
|
||||
BYTE MaxDevices; // Maximum number of devices that may be implemented (16)
|
||||
BYTE DriverFFB; // Does this driver support FFB (False)
|
||||
BYTE DeviceFFB; // Does this device support FFB (False)
|
||||
} ;
|
||||
|
||||
typedef void (CALLBACK *RemovalCB)(BOOL, BOOL, PVOID);
|
||||
|
||||
#endif
|
||||
extern "C" {
|
||||
///////////////////////////// vJoy device (collection) Control interface /////////////////////////////////
|
||||
/*
|
||||
These functions allow writing feeders and other applications that interface with vJoy
|
||||
It is assumed that only one vJoy top-device (= Raw PDO) exists.
|
||||
This top-level device can have up to 16 siblings (=top-level Reports/collections)
|
||||
Each sibling is refered to as a "vJoy Device" and is attributed a unique Report ID (Range: 1-16).
|
||||
|
||||
Naming convetion:
|
||||
VJD = vJoy Device
|
||||
rID = Report ID
|
||||
*/
|
||||
|
||||
///// General driver data
|
||||
VJOYINTERFACE_API SHORT __cdecl GetvJoyVersion(void);
|
||||
VJOYINTERFACE_API BOOL __cdecl vJoyEnabled(void);
|
||||
VJOYINTERFACE_API PVOID __cdecl GetvJoyProductString(void);
|
||||
VJOYINTERFACE_API PVOID __cdecl GetvJoyManufacturerString(void);
|
||||
VJOYINTERFACE_API PVOID __cdecl GetvJoySerialNumberString(void);
|
||||
VJOYINTERFACE_API BOOL __cdecl DriverMatch(WORD * DllVer, WORD * DrvVer);
|
||||
VJOYINTERFACE_API VOID __cdecl RegisterRemovalCB(RemovalCB cb, PVOID data);
|
||||
|
||||
|
||||
///// vJoy Device properties
|
||||
VJOYINTERFACE_API int __cdecl GetVJDButtonNumber(UINT rID); // Get the number of buttons defined in the specified VDJ
|
||||
VJOYINTERFACE_API int __cdecl GetVJDDiscPovNumber(UINT rID); // Get the number of descrete-type POV hats defined in the specified VDJ
|
||||
VJOYINTERFACE_API int __cdecl GetVJDContPovNumber(UINT rID); // Get the number of descrete-type POV hats defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl GetVJDAxisExist(UINT rID, UINT Axis); // Test if given axis defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl GetVJDAxisMax(UINT rID, UINT Axis, LONG * Max); // Get logical Maximum value for a given axis defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl GetVJDAxisMin(UINT rID, UINT Axis, LONG * Min); // Get logical Minimum value for a given axis defined in the specified VDJ
|
||||
|
||||
///// Write access to vJoy Device - Basic
|
||||
VJOYINTERFACE_API BOOL __cdecl AcquireVJD(UINT rID); // Acquire the specified vJoy Device.
|
||||
VJOYINTERFACE_API VOID __cdecl RelinquishVJD(UINT rID); // Relinquish the specified vJoy Device.
|
||||
VJOYINTERFACE_API BOOL __cdecl UpdateVJD(UINT rID, PVOID pData); // Update the position data of the specified vJoy Device.
|
||||
VJOYINTERFACE_API enum VjdStat __cdecl GetVJDStatus(UINT rID); // Get the status of the specified vJoy Device.
|
||||
|
||||
///// Write access to vJoy Device - Modifyiers
|
||||
// This group of functions modify the current value of the position data
|
||||
// They replace the need to create a structure of position data then call UpdateVJD
|
||||
|
||||
//// Reset functions
|
||||
VJOYINTERFACE_API BOOL __cdecl ResetVJD(UINT rID); // Reset all controls to predefined values in the specified VDJ
|
||||
VJOYINTERFACE_API VOID __cdecl ResetAll(void); // Reset all controls to predefined values in all VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl ResetButtons(UINT rID); // Reset all buttons (To 0) in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl ResetPovs(UINT rID); // Reset all POV Switches (To -1) in the specified VDJ
|
||||
|
||||
// Write data
|
||||
VJOYINTERFACE_API BOOL __cdecl SetAxis(LONG Value, UINT rID, UINT Axis); // Write Value to a given axis defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl SetBtn(BOOL Value, UINT rID, UCHAR nBtn); // Write Value to a given button defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl SetDiscPov(int Value, UINT rID, UCHAR nPov); // Write Value to a given descrete POV defined in the specified VDJ
|
||||
VJOYINTERFACE_API BOOL __cdecl SetContPov(DWORD Value, UINT rID, UCHAR nPov); // Write Value to a given continuous POV defined in the specified VDJ
|
||||
|
||||
} // extern "C"
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- net8.0 LTS. Windows-flavored TFM: this library uses Win32 P/Invoke
|
||||
(SendInput, SystemParametersInfo) and System.IO.Ports. -->
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Platforms>x64</Platforms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.IO.Ports" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace RioJoy.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Shared metadata for the RIOJoy runtime. The real domain types
|
||||
/// (RIO serial protocol, profile model, input mapper, virtual-HID feeder)
|
||||
/// land here in later phases; see docs/PLAN.md.
|
||||
/// </summary>
|
||||
public static class RioJoyInfo
|
||||
{
|
||||
/// <summary>Product display name.</summary>
|
||||
public const string Name = "RIOJoy";
|
||||
|
||||
/// <summary>
|
||||
/// Successor to the legacy vJoy-based "RIOvJoy v.03" (see legacy/riovjoy2.cpp).
|
||||
/// </summary>
|
||||
public const string Version = "0.1.0-dev";
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace RioJoy.Tray;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// Entry point. RIOJoy runs as a background tray application with no main
|
||||
/// window: an ApplicationContext owns the NotifyIcon and the runtime, so the
|
||||
/// message loop stays alive while the only UI is the tray icon and its menu.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
private static void Main()
|
||||
{
|
||||
ApplicationConfiguration.Initialize();
|
||||
Application.Run(new TrayApplicationContext());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Platforms>x64</Platforms>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RioJoy.Core\RioJoy.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,42 @@
|
||||
namespace RioJoy.Tray;
|
||||
|
||||
/// <summary>
|
||||
/// Owns the tray icon and (eventually) the RIOJoy runtime: the serial link to
|
||||
/// the RIO, the active profile, the virtual-HID feeder, and the profile
|
||||
/// auto-switch watcher.
|
||||
///
|
||||
/// Phase 0 scaffold: just the tray icon + a minimal menu. Wiring the runtime is
|
||||
/// Phase 5 work; the menu items below are placeholders that mirror the legacy
|
||||
/// console menu (reset/recalibrate axes, version/status, quit).
|
||||
/// </summary>
|
||||
internal sealed class TrayApplicationContext : ApplicationContext
|
||||
{
|
||||
private readonly NotifyIcon _trayIcon;
|
||||
|
||||
public TrayApplicationContext()
|
||||
{
|
||||
var menu = new ContextMenuStrip();
|
||||
menu.Items.Add("RIOJoy (scaffold)").Enabled = false;
|
||||
menu.Items.Add(new ToolStripSeparator());
|
||||
menu.Items.Add("Exit", null, (_, _) => ExitThread());
|
||||
|
||||
_trayIcon = new NotifyIcon
|
||||
{
|
||||
Icon = SystemIcons.Application,
|
||||
Text = "RIOJoy",
|
||||
Visible = true,
|
||||
ContextMenuStrip = menu,
|
||||
};
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_trayIcon.Visible = false;
|
||||
_trayIcon.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="RioJoy.Tray.app" type="win32" />
|
||||
|
||||
<!-- Run as the invoking user. RIOJoy needs no admin rights for normal
|
||||
operation: opening a COM port, calling SendInput, and DeviceIoControl
|
||||
to the virtual-HID control device (whose security descriptor will allow
|
||||
interactive users). Installing the driver is a separate, elevated step. -->
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<!-- Declare Windows 10/11 compatibility for correct DPI / API behavior. -->
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> <!-- Windows 10/11 -->
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
Reference in New Issue
Block a user