From 21a829632a627252f963808b6e79bdc789385f20 Mon Sep 17 00:00:00 2001 From: Timian Heber Date: Sun, 6 Oct 2024 19:46:45 +0200 Subject: [PATCH] Experimentations in input event handling --- src/CTrue.FsConnect.TestConsole/Program.cs | 5 ++ .../Properties/launchSettings.json | 2 +- src/CTrue.FsConnect/FsConnect.cs | 89 +++++++++++++++++-- src/CTrue.FsConnect/IFsConnect.cs | 5 ++ 4 files changed, 95 insertions(+), 6 deletions(-) diff --git a/src/CTrue.FsConnect.TestConsole/Program.cs b/src/CTrue.FsConnect.TestConsole/Program.cs index f2b26bb..076d7e5 100644 --- a/src/CTrue.FsConnect.TestConsole/Program.cs +++ b/src/CTrue.FsConnect.TestConsole/Program.cs @@ -44,6 +44,11 @@ private static void Run(Options commandLineOptions) { _fsConnect = new FsConnect(); + _fsConnect.InputEventDefintion = "joystick:1:button:0"; + //_fsConnect.InputEventDefintion = "w"; + + _fsConnect.InputEventRaised += (sender, args) => { Console.WriteLine("Input event raised"); }; + try { if (string.IsNullOrEmpty(commandLineOptions.Hostname)) diff --git a/src/CTrue.FsConnect.TestConsole/Properties/launchSettings.json b/src/CTrue.FsConnect.TestConsole/Properties/launchSettings.json index 52029a9..6028de8 100644 --- a/src/CTrue.FsConnect.TestConsole/Properties/launchSettings.json +++ b/src/CTrue.FsConnect.TestConsole/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "FsConnectTestConsole": { "commandName": "Project", - "commandLineArgs": "-h localhost -p 500 -l Debug" + "commandLineArgs": "-h 192.168.1.174 -p 500 -l Debug" } } } \ No newline at end of file diff --git a/src/CTrue.FsConnect/FsConnect.cs b/src/CTrue.FsConnect/FsConnect.cs index 9425aa0..ec31f27 100644 --- a/src/CTrue.FsConnect/FsConnect.cs +++ b/src/CTrue.FsConnect/FsConnect.cs @@ -40,7 +40,26 @@ private enum SimEvents enum GROUP_IDS { - GROUP_1 = 98, + GROUP_1 = 98 + } + + public enum GroupIds + { + JOYSTICK_EVENT_KEY_GROUP = 200, + INPUT_KEY_GROUP = 201, + JOYSTICK_EVENT_KEY_GROUP2 = 203, + INPUT_KEY_GROUP2 = 204 + } + + public enum EventIds + { + JOYSTICK_BUTTON1 = 300, + JOYSTICK_BUTTON2 = 301 + } + + public enum SimConnectEnums : uint + { + SIMCONNECT_UNUSED = 4294967295 } #endregion @@ -72,6 +91,9 @@ enum GROUP_IDS /// public event EventHandler Crashed; + /// + public event EventHandler InputEventRaised; + /// public bool Connected { @@ -96,6 +118,14 @@ private set /// public bool Paused => _paused; + /// + /// Experimental: Set this to set up an input event handler, raising the event when triggered. + /// + /// + /// Example: "joystick:1:button:0" + /// + public string InputEventDefintion { get; set; } = string.Empty; + /// public void Connect(string applicationName, uint configIndex = 0) { @@ -137,6 +167,29 @@ public void Connect(string applicationName, uint configIndex = 0) _simConnect.MapClientEventToSimEvent(SimEvents.PauseSet, "PAUSE_SET"); } + void RegisterInputEvent(Enum joystickButtonEventId, Enum joystickButtonEventGroup, Enum inputGroup, string inputDefinition) + { + // Setup client event + _simConnect.MapClientEventToSimEvent(joystickButtonEventId, null); + _simConnect.AddClientEventToNotificationGroup(joystickButtonEventGroup, joystickButtonEventId, false); + _simConnect.SetNotificationGroupPriority(joystickButtonEventGroup, 1); + + // Setup input event mapping + _simConnect.MapInputEventToClientEvent( + inputGroup, + inputDefinition, + joystickButtonEventId, + 1, + SimConnectEnums.SIMCONNECT_UNUSED, + 0, + false + ); + + _simConnect.SetInputGroupPriority(inputGroup, 1); + + Log.Information("Input event g:{inputGroup} e:{inputEventId} registration complete for '{inputDefinition}'", joystickButtonEventGroup, joystickButtonEventId, inputDefinition); + } + /// public void Connect(string applicationName, string hostName, uint port, SimConnectProtocol protocol) { @@ -163,6 +216,10 @@ public void Disconnect() _simConnect.UnsubscribeFromSystemEvent(SimEvents.ObjectAdded); _simConnect.RemoveClientEvent(GROUP_IDS.GROUP_1, SimEvents.PauseSet); + + if(!string.IsNullOrEmpty(InputEventDefintion)) + _simConnect.RemoveClientEvent(GroupIds.INPUT_KEY_GROUP, EventIds.JOYSTICK_BUTTON1); + _simConnectReceiveThread.Abort(); _simConnectReceiveThread.Join(); @@ -379,6 +436,22 @@ private void SimConnect_OnRecvOpen(SimConnect sender, SIMCONNECT_RECV_OPEN data) _connectionInfo.SimConnectBuild = $"{data.dwSimConnectBuildMajor}.{data.dwSimConnectBuildMinor}"; Connected = true; + + if(!string.IsNullOrEmpty(InputEventDefintion)) + { + // Do this after getting the OnRecvOpen event, otherwise connection will fail. + + uint joystickId = 1; // Look at the USB game controller app and determine other of joysticks + uint joystickButtonId = 0; // Use app and see which buttons are mapped to a button id + //string inputDefinition = $"joystick:{joystickId}:button:{joystickButtonId}"; + RegisterInputEvent(EventIds.JOYSTICK_BUTTON1, GroupIds.JOYSTICK_EVENT_KEY_GROUP, GroupIds.INPUT_KEY_GROUP, InputEventDefintion); + + // TODO later: Generalize concept around registering input events + //joystickId = 1; + //joystickButtonId = 1; + //inputDefinition = $"joystick:{joystickId}:button:{joystickButtonId}"; + //RegisterInputEvent(EventIds.JOYSTICK_BUTTON2, GroupIds.JOYSTICK_EVENT_KEY_GROUP2, GroupIds.INPUT_KEY_GROUP2, inputDefinition); + } } private void SimConnect_OnRecvQuit(SimConnect sender, SIMCONNECT_RECV data) @@ -389,7 +462,7 @@ private void SimConnect_OnRecvQuit(SimConnect sender, SIMCONNECT_RECV data) private void SimConnect_OnRecvEvent(SimConnect sender, SIMCONNECT_RECV_EVENT data) { - Log.Debug("OnRecvEvent (S: {Size}, V: {Version}, I: {Id}) {GroupId}, {EventId}, {Data}", data.dwSize, data.dwVersion, data.dwID, data.uGroupID, data.uEventID, data.dwData); + Log.Debug("OnRecvEvent ({Size}b/{Version}/{Id}) g:{GroupId}, e:{EventId}, d:{Data}", data.dwSize, data.dwVersion, data.dwID, data.uGroupID, data.uEventID, data.dwData); if (data.uEventID == (uint)SimEvents.EVENT_AIRCRAFT_LOAD) { @@ -417,14 +490,20 @@ private void SimConnect_OnRecvEvent(SimConnect sender, SIMCONNECT_RECV_EVENT dat Log.Debug("ClientEvent: Paused: {Paused}", _paused); PauseStateChanged?.Invoke(this, new PauseStateChangedEventArgs() { Paused = data.dwData == 1 }); } + else if (data.uGroupID == (uint)GroupIds.JOYSTICK_EVENT_KEY_GROUP) + { + if (data.uEventID == (uint)EventIds.JOYSTICK_BUTTON1) + { + Log.Information("ClientEvent: Input event 1 event: {dwData}", data.dwData); + InputEventRaised?.Invoke(this, EventArgs.Empty); + } + } } private void SimConnect_OnRecvException(SimConnect sender, SIMCONNECT_RECV_EXCEPTION data) { Log.Warning("OnRecvException ({Size}b/{Version}/{Id}) Exception: {Exception}, SendId: {SendId}, Index: {Index}", data.dwSize, data.dwVersion, data.dwID, ((FsException)data.dwException).ToString(), data.dwSendID, data.dwIndex); - - SIMCONNECT_EXCEPTION eException = (SIMCONNECT_EXCEPTION)data.dwException; - + FsError?.Invoke(this, new FsErrorEventArgs() { ExceptionCode = (FsException)data.dwException, diff --git a/src/CTrue.FsConnect/IFsConnect.cs b/src/CTrue.FsConnect/IFsConnect.cs index 854964b..511fb42 100644 --- a/src/CTrue.FsConnect/IFsConnect.cs +++ b/src/CTrue.FsConnect/IFsConnect.cs @@ -57,6 +57,11 @@ public interface IFsConnect : IDisposable /// event EventHandler Crashed; + /// + /// + /// + event EventHandler InputEventRaised; + /// /// Gets a boolean value indication whether a connection to Flight Simulator is established. ///