v1.2
This commit is contained in:
215
FSI.BT.Tools/SystemTrayMenu/Helpers/JoystickHelper.cs
Normal file
215
FSI.BT.Tools/SystemTrayMenu/Helpers/JoystickHelper.cs
Normal file
@@ -0,0 +1,215 @@
|
||||
// <copyright file="JoystickHelper.cs" company="PlaceholderCompany">
|
||||
// Copyright (c) PlaceholderCompany. All rights reserved.
|
||||
// </copyright>
|
||||
|
||||
namespace FSI.BT.Tools.SystemTrayMenu.Helpers
|
||||
{
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Metrics;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using SharpDX.DirectInput;
|
||||
|
||||
public class JoystickHelper : IDisposable
|
||||
{
|
||||
private readonly System.Timers.Timer timerReadJoystick = new();
|
||||
private readonly object lockRead = new();
|
||||
private Joystick joystick;
|
||||
private Keys pressingKey;
|
||||
private int pressingKeyCounter;
|
||||
private bool joystickHelperEnabled;
|
||||
|
||||
public JoystickHelper()
|
||||
{
|
||||
timerReadJoystick.Interval = 80;
|
||||
timerReadJoystick.Elapsed += ReadJoystickLoop;
|
||||
timerReadJoystick.Enabled = false;
|
||||
if (Global.Vars.SystemTrayMenuSettings.SupportGamepad)
|
||||
{
|
||||
timerReadJoystick.Start();
|
||||
}
|
||||
}
|
||||
|
||||
~JoystickHelper() // the finalizer
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public event Action<Keys> KeyPressed;
|
||||
|
||||
public void Enable()
|
||||
{
|
||||
joystickHelperEnabled = true;
|
||||
}
|
||||
|
||||
public void Disable()
|
||||
{
|
||||
joystickHelperEnabled = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
timerReadJoystick.Elapsed -= ReadJoystickLoop;
|
||||
timerReadJoystick?.Dispose();
|
||||
joystick?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static Keys ReadKeyFromState(JoystickUpdate state)
|
||||
{
|
||||
Keys keys = Keys.None;
|
||||
switch (state.Offset)
|
||||
{
|
||||
case JoystickOffset.PointOfViewControllers0:
|
||||
switch (state.Value)
|
||||
{
|
||||
case 0:
|
||||
keys = Keys.Up;
|
||||
break;
|
||||
case 9000:
|
||||
keys = Keys.Right;
|
||||
break;
|
||||
case 18000:
|
||||
keys = Keys.Down;
|
||||
break;
|
||||
case 27000:
|
||||
keys = Keys.Left;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case JoystickOffset.Buttons0:
|
||||
if (state.Value == 128)
|
||||
{
|
||||
keys = Keys.Enter;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
private void ReadJoystickLoop(object sender, System.Timers.ElapsedEventArgs e)
|
||||
{
|
||||
if (joystickHelperEnabled)
|
||||
{
|
||||
lock (lockRead)
|
||||
{
|
||||
timerReadJoystick.Stop();
|
||||
if (joystick == null)
|
||||
{
|
||||
Thread.Sleep(3000);
|
||||
InitializeJoystick();
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadJoystick();
|
||||
}
|
||||
|
||||
timerReadJoystick.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadJoystick()
|
||||
{
|
||||
try
|
||||
{
|
||||
joystick.Poll();
|
||||
JoystickUpdate[] datas = joystick.GetBufferedData();
|
||||
foreach (JoystickUpdate state in datas)
|
||||
{
|
||||
if (state.Value < 0)
|
||||
{
|
||||
pressingKey = Keys.None;
|
||||
pressingKeyCounter = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
Keys key = ReadKeyFromState(state);
|
||||
if (key != Keys.None)
|
||||
{
|
||||
KeyPressed?.Invoke(key);
|
||||
if (state.Offset == JoystickOffset.PointOfViewControllers0)
|
||||
{
|
||||
pressingKeyCounter = 0;
|
||||
pressingKey = key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pressingKey != Keys.None)
|
||||
{
|
||||
pressingKeyCounter += 1;
|
||||
if (pressingKeyCounter > 1)
|
||||
{
|
||||
KeyPressed?.Invoke(pressingKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
joystick?.Dispose();
|
||||
joystick = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeJoystick()
|
||||
{
|
||||
// Initialize DirectInput
|
||||
DirectInput directInput = new();
|
||||
|
||||
// Find a Joystick Guid
|
||||
Guid joystickGuid = Guid.Empty;
|
||||
|
||||
foreach (DeviceInstance deviceInstance in directInput.GetDevices(
|
||||
DeviceType.Gamepad,
|
||||
DeviceEnumerationFlags.AllDevices))
|
||||
{
|
||||
joystickGuid = deviceInstance.InstanceGuid;
|
||||
}
|
||||
|
||||
// If Gamepad not found, look for a Joystick
|
||||
if (joystickGuid == Guid.Empty)
|
||||
{
|
||||
foreach (DeviceInstance deviceInstance in directInput.GetDevices(
|
||||
DeviceType.Joystick,
|
||||
DeviceEnumerationFlags.AllDevices))
|
||||
{
|
||||
joystickGuid = deviceInstance.InstanceGuid;
|
||||
}
|
||||
}
|
||||
|
||||
// If Joystick found
|
||||
if (joystickGuid != Guid.Empty)
|
||||
{
|
||||
// Instantiate the joystick
|
||||
joystick = new Joystick(directInput, joystickGuid);
|
||||
|
||||
// Set BufferSize in order to use buffered data.
|
||||
joystick.Properties.BufferSize = 128;
|
||||
|
||||
var handle = Process.GetCurrentProcess().MainWindowHandle;
|
||||
joystick.SetCooperativeLevel(handle, CooperativeLevel.NonExclusive | CooperativeLevel.Background);
|
||||
|
||||
// Acquire the joystick
|
||||
joystick.Acquire();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user