using Nefarius.ViGEm.Client.Targets; using Nefarius.ViGEm.Client.Targets.DualShock4; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms.VisualStyles; using System.Xml.Serialization; namespace BetterJoyForCemu.Controller { public enum DpadDirection { None, Northwest, West, Southwest, South, Southeast, East, Northeast, North, } public struct OutputControllerDualShock4InputState { public bool triangle; public bool circle; public bool cross; public bool square; public bool trigger_left; public bool trigger_right; public bool shoulder_left; public bool shoulder_right; public bool options; public bool share; public bool ps; public bool touchpad; public bool thumb_left; public bool thumb_right; public DpadDirection dPad; public byte thumb_left_x; public byte thumb_left_y; public byte thumb_right_x; public byte thumb_right_y; public byte trigger_left_value; public byte trigger_right_value; public bool IsEqual(OutputControllerDualShock4InputState other) { bool buttons = triangle == other.triangle && circle == other.circle && cross == other.cross && square == other.square && trigger_left == other.trigger_left && trigger_right == other.trigger_right && shoulder_left == other.shoulder_left && shoulder_right == other.shoulder_right && options == other.options && share == other.share && ps == other.ps && touchpad == other.touchpad && thumb_left == other.thumb_left && thumb_right == other.thumb_right && dPad == other.dPad; bool axis = thumb_left_x == other.thumb_left_x && thumb_left_y == other.thumb_left_y && thumb_right_x == other.thumb_right_x && thumb_right_y == other.thumb_right_y; bool triggers = trigger_left_value == other.trigger_left_value && trigger_right_value == other.trigger_right_value; return buttons && axis && triggers; } } public class OutputControllerDualShock4 { private IDualShock4Controller controller; private OutputControllerDualShock4InputState current_state; public delegate void DualShock4FeedbackReceivedEventHandler(DualShock4FeedbackReceivedEventArgs e); public event DualShock4FeedbackReceivedEventHandler FeedbackReceived; public OutputControllerDualShock4() { controller = Program.emClient.CreateDualShock4Controller(); Init(); } public OutputControllerDualShock4(ushort vendor_id, ushort product_id) { controller = Program.emClient.CreateDualShock4Controller(vendor_id, product_id); Init(); } private void Init() { controller.AutoSubmitReport = false; controller.FeedbackReceived += FeedbackReceivedRcv; } private void FeedbackReceivedRcv(object _sender, DualShock4FeedbackReceivedEventArgs e) { FeedbackReceived(e); } public void Connect() { controller.Connect(); } public void Disconnect() { controller.Disconnect(); } public bool UpdateInput(OutputControllerDualShock4InputState new_state) { if(current_state.IsEqual(new_state)) { return false; } DoUpdateInput(new_state); return true; } private void DoUpdateInput(OutputControllerDualShock4InputState new_state) { controller.SetButtonState(DualShock4Button.Triangle, new_state.triangle); controller.SetButtonState(DualShock4Button.Circle, new_state.circle); controller.SetButtonState(DualShock4Button.Cross, new_state.cross); controller.SetButtonState(DualShock4Button.Square, new_state.square); controller.SetButtonState(DualShock4Button.ShoulderLeft, new_state.shoulder_left); controller.SetButtonState(DualShock4Button.ShoulderRight, new_state.shoulder_right); controller.SetButtonState(DualShock4Button.TriggerLeft, new_state.trigger_left); controller.SetButtonState(DualShock4Button.TriggerRight, new_state.trigger_right); controller.SetButtonState(DualShock4Button.ThumbLeft, new_state.thumb_left); controller.SetButtonState(DualShock4Button.ThumbRight, new_state.thumb_left); controller.SetButtonState(DualShock4Button.Share, new_state.share); controller.SetButtonState(DualShock4Button.Options, new_state.options); controller.SetButtonState(DualShock4SpecialButton.Ps, new_state.ps); controller.SetButtonState(DualShock4SpecialButton.Touchpad, new_state.touchpad); controller.SetDPadDirection(MapDPadDirection(new_state.dPad)); controller.SetAxisValue(DualShock4Axis.LeftThumbX, new_state.thumb_left_x); controller.SetAxisValue(DualShock4Axis.LeftThumbY, new_state.thumb_left_y); controller.SetAxisValue(DualShock4Axis.RightThumbX, new_state.thumb_right_x); controller.SetAxisValue(DualShock4Axis.RightThumbY, new_state.thumb_right_y); controller.SetSliderValue(DualShock4Slider.LeftTrigger, new_state.trigger_left_value); controller.SetSliderValue(DualShock4Slider.RightTrigger, new_state.trigger_right_value); controller.SubmitReport(); current_state = new_state; } private DualShock4DPadDirection MapDPadDirection(DpadDirection dPad) { switch(dPad) { case DpadDirection.None: return DualShock4DPadDirection.None; case DpadDirection.North: return DualShock4DPadDirection.North; case DpadDirection.Northeast: return DualShock4DPadDirection.Northeast; case DpadDirection.East: return DualShock4DPadDirection.East; case DpadDirection.Southeast: return DualShock4DPadDirection.Southeast; case DpadDirection.South: return DualShock4DPadDirection.South; case DpadDirection.Southwest: return DualShock4DPadDirection.Southwest; case DpadDirection.West: return DualShock4DPadDirection.West; case DpadDirection.Northwest: return DualShock4DPadDirection.Northwest; default: throw new NotImplementedException(); } } } }