feat: simplified and modularized gamepad reader

This commit is contained in:
Gerard Gascón 2024-06-06 23:47:06 +02:00
parent 8717f9d716
commit 0ebb7f6459
4 changed files with 72 additions and 66 deletions

8
GamepadReader.cs Normal file
View file

@ -0,0 +1,8 @@
namespace SwitchSlidePresenter;
public abstract class GamepadReader {
public abstract event Action NextSlide;
public abstract event Action PrevSlide;
public abstract Task Read();
}

View file

@ -10,12 +10,58 @@ using wtf.cluster.JoyCon.Rumble;
namespace SwitchSlidePresenter; namespace SwitchSlidePresenter;
public class JoyConRead { public class JoyConRead : GamepadReader {
public static async Task Read() { public override event Action NextSlide;
public override event Action PrevSlide;
public override async Task Read() {
Console.OutputEncoding = Encoding.UTF8; Console.OutputEncoding = Encoding.UTF8;
HidDevice? device = null; HidDevice? device = GetHidDevice();
if (device == null) {
Console.WriteLine("No controller. Please connect Joy-Con or Pro controller via Bluetooth.");
return;
}
JoyCon joycon = new(device);
joycon.Start();
await joycon.SetInputReportModeAsync(JoyCon.InputReportType.Simple);
await LogDeviceInfo(joycon);
joycon.ReportReceived += OnJoyConOnReportReceived;
Console.WriteLine($"JoyCon ready for presenting.");
joycon.StoppedOnError += (_, ex) => {
Console.WriteLine();
Console.WriteLine($"Critical error: {ex.Message}");
Console.WriteLine("Controller polling stopped.");
Environment.Exit(1);
return Task.CompletedTask;
};
Console.ReadKey();
joycon.Stop();
Console.WriteLine();
Console.WriteLine("Stopped.");
}
private static async Task LogDeviceInfo(JoyCon joycon) {
DeviceInfo deviceInfo = await joycon.GetDeviceInfoAsync();
Console.WriteLine(
$"Type: {deviceInfo.ControllerType}, Firmware: {deviceInfo.FirmwareVersionMajor}.{deviceInfo.FirmwareVersionMinor}");
string? serial = await joycon.GetSerialNumberAsync();
Console.WriteLine($"Serial number: {serial ?? "<none>"}");
ControllerColors? colors = await joycon.GetColorsAsync();
Console.WriteLine(colors != null
? $"Body color: {colors.BodyColor}, buttons color: {colors.ButtonsColor}"
: "Colors not specified, seems like the controller is grey.");
}
private static HidDevice? GetHidDevice() {
DeviceList list = DeviceList.Local; DeviceList list = DeviceList.Local;
HidDevice? device = null;
if (OperatingSystem.IsWindows()) { if (OperatingSystem.IsWindows()) {
var nintendos = list.GetHidDevices(0x057e); var nintendos = list.GetHidDevices(0x057e);
device = nintendos.FirstOrDefault(); device = nintendos.FirstOrDefault();
@ -44,54 +90,21 @@ public class JoyConRead {
} }
} }
} }
if (device == null) { return device;
Console.WriteLine("No controller. Please connect Joy-Con or Pro controller via Bluetooth.");
return;
}
JoyCon joycon = new(device);
joycon.Start();
await joycon.SetInputReportModeAsync(JoyCon.InputReportType.Simple);
DeviceInfo deviceInfo = await joycon.GetDeviceInfoAsync();
Console.WriteLine(
$"Type: {deviceInfo.ControllerType}, Firmware: {deviceInfo.FirmwareVersionMajor}.{deviceInfo.FirmwareVersionMinor}");
var serial = await joycon.GetSerialNumberAsync();
Console.WriteLine($"Serial number: {serial ?? "<none>"}");
ControllerColors? colors = await joycon.GetColorsAsync();
if (colors != null) {
Console.WriteLine($"Body color: {colors.BodyColor}, buttons color: {colors.ButtonsColor}");
} else {
Console.WriteLine("Colors not specified, seems like the controller is grey.");
} }
joycon.ReportReceived += OnJoyconOnReportReceived; private Task OnJoyConOnReportReceived(JoyCon _, IJoyConReport input) {
if (input is not InputSimple j) {
joycon.StoppedOnError += (_, ex) => { Console.WriteLine($"Invalid input report type: {input.GetType()}");
Console.WriteLine();
Console.WriteLine($"Critical error: {ex.Message}");
Console.WriteLine("Controller polling stopped.");
Environment.Exit(1);
return Task.CompletedTask; return Task.CompletedTask;
};
Console.ReadKey();
joycon.Stop();
Console.WriteLine();
Console.WriteLine("Stopped.");
} }
private static Task OnJoyconOnReportReceived(JoyCon _, IJoyConReport input) {
if (input is InputSimple j) {
bool prev = PreviousPressed(j.Buttons); bool prev = PreviousPressed(j.Buttons);
bool next = NextPressed(j.Buttons); bool next = NextPressed(j.Buttons);
if(prev) if (prev)
Console.WriteLine("Previous Slide"); PrevSlide?.Invoke();
if(next) if (next)
Console.WriteLine("Next Slide"); NextSlide?.Invoke();
} else {
Console.WriteLine($"Invalid input report type: {input.GetType()}");
}
return Task.CompletedTask; return Task.CompletedTask;
} }

View file

@ -1,16 +1,8 @@
using HidSharp; namespace SwitchSlidePresenter {
using System.Text;
using wtf.cluster.JoyCon;
using wtf.cluster.JoyCon.Calibration;
using wtf.cluster.JoyCon.ExtraData;
using wtf.cluster.JoyCon.HomeLed;
using wtf.cluster.JoyCon.InputReports;
using wtf.cluster.JoyCon.Rumble;
namespace SwitchSlidePresenter {
class Program { class Program {
static async Task Main(string[] args) { private static async Task Main() {
await JoyConRead.Read(); GamepadReader reader = new JoyConRead();
await reader.Read();
} }
} }
} }

View file

@ -1,7 +0,0 @@
namespace SwitchSlidePresenter;
public enum SlideSwitchPress {
None,
Previous,
Next
}