Fix input delay 2 (#357)
* extract xboxc360ontroller * extracts DualShock4Controller * Revert "ensures we get the latest available HID data (#345)" This reverts commitcd659366b5
. * Revert "fixes cpu busy spinning when there is no hid data available (#356)" This reverts commitc4f5bbdc56
.
This commit is contained in:
parent
c4f5bbdc56
commit
a8396554e7
6 changed files with 675 additions and 278 deletions
|
@ -131,6 +131,8 @@
|
|||
<DependentUpon>3rdPartyControllers.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Config.cs" />
|
||||
<Compile Include="Controller\OutputControllerDualShock4.cs" />
|
||||
<Compile Include="Controller\OutputControllerXbox360.cs" />
|
||||
<Compile Include="HIDapi.cs" />
|
||||
<Compile Include="Joycon.cs" />
|
||||
<Compile Include="MainForm.cs">
|
||||
|
|
192
BetterJoyForCemu/Controller/OutputControllerDualShock4.cs
Normal file
192
BetterJoyForCemu/Controller/OutputControllerDualShock4.cs
Normal file
|
@ -0,0 +1,192 @@
|
|||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
163
BetterJoyForCemu/Controller/OutputControllerXbox360.cs
Normal file
163
BetterJoyForCemu/Controller/OutputControllerXbox360.cs
Normal file
|
@ -0,0 +1,163 @@
|
|||
using Nefarius.ViGEm.Client.Targets;
|
||||
using Nefarius.ViGEm.Client.Targets.Xbox360;
|
||||
using System.Web.UI;
|
||||
|
||||
namespace BetterJoyForCemu.Controller
|
||||
{
|
||||
public struct OutputControllerXbox360InputState
|
||||
{
|
||||
// buttons
|
||||
public bool thumb_stick_left;
|
||||
public bool thumb_stick_right;
|
||||
|
||||
public bool y;
|
||||
public bool x;
|
||||
public bool b;
|
||||
public bool a;
|
||||
|
||||
public bool start;
|
||||
public bool back;
|
||||
|
||||
public bool guide;
|
||||
|
||||
public bool shoulder_left;
|
||||
public bool shoulder_right;
|
||||
|
||||
// dpad
|
||||
public bool dpad_up;
|
||||
public bool dpad_right;
|
||||
public bool dpad_down;
|
||||
public bool dpad_left;
|
||||
|
||||
// axis
|
||||
public short axis_left_x;
|
||||
public short axis_left_y;
|
||||
|
||||
public short axis_right_x;
|
||||
public short axis_right_y;
|
||||
|
||||
// triggers
|
||||
public byte trigger_left;
|
||||
public byte trigger_right;
|
||||
|
||||
public bool IsEqual(OutputControllerXbox360InputState other)
|
||||
{
|
||||
bool buttons = thumb_stick_left == other.thumb_stick_left
|
||||
&& thumb_stick_right == other.thumb_stick_right
|
||||
&& y == other.y
|
||||
&& x == other.x
|
||||
&& b == other.b
|
||||
&& a == other.a
|
||||
&& start == other.start
|
||||
&& back == other.back
|
||||
&& guide == other.guide
|
||||
&& shoulder_left == other.shoulder_left
|
||||
&& shoulder_right == other.shoulder_right;
|
||||
|
||||
bool dpad = dpad_up == other.dpad_up
|
||||
&& dpad_right == other.dpad_right
|
||||
&& dpad_down == other.dpad_down
|
||||
&& dpad_left == other.dpad_left;
|
||||
|
||||
bool axis = axis_left_x == other.axis_left_x
|
||||
&& axis_left_y == other.axis_left_y
|
||||
&& axis_right_x == other.axis_right_x
|
||||
&& axis_right_y == other.axis_right_y;
|
||||
|
||||
bool triggers = trigger_left == other.trigger_left
|
||||
&& trigger_right == other.trigger_right;
|
||||
|
||||
return buttons && dpad && axis && triggers;
|
||||
}
|
||||
}
|
||||
|
||||
public class OutputControllerXbox360
|
||||
{
|
||||
private IXbox360Controller xbox_controller;
|
||||
private OutputControllerXbox360InputState current_state;
|
||||
|
||||
public delegate void Xbox360FeedbackReceivedEventHandler(Xbox360FeedbackReceivedEventArgs e);
|
||||
|
||||
public event Xbox360FeedbackReceivedEventHandler FeedbackReceived;
|
||||
|
||||
public OutputControllerXbox360()
|
||||
{
|
||||
xbox_controller = Program.emClient.CreateXbox360Controller();
|
||||
Init();
|
||||
}
|
||||
|
||||
public OutputControllerXbox360(ushort vendor_id, ushort product_id)
|
||||
{
|
||||
xbox_controller = Program.emClient.CreateXbox360Controller(vendor_id, product_id);
|
||||
Init();
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
xbox_controller.FeedbackReceived += FeedbackReceivedRcv;
|
||||
xbox_controller.AutoSubmitReport = false;
|
||||
}
|
||||
|
||||
private void FeedbackReceivedRcv(object _sender, Xbox360FeedbackReceivedEventArgs e)
|
||||
{
|
||||
FeedbackReceived(e);
|
||||
}
|
||||
|
||||
public bool UpdateInput(OutputControllerXbox360InputState new_state) {
|
||||
if (current_state.IsEqual(new_state))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DoUpdateInput(new_state);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Connect()
|
||||
{
|
||||
xbox_controller.Connect();
|
||||
DoUpdateInput(new OutputControllerXbox360InputState());
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
xbox_controller.Disconnect();
|
||||
}
|
||||
|
||||
private void DoUpdateInput(OutputControllerXbox360InputState new_state)
|
||||
{
|
||||
xbox_controller.SetButtonState(Xbox360Button.LeftThumb, new_state.thumb_stick_left);
|
||||
xbox_controller.SetButtonState(Xbox360Button.RightThumb, new_state.thumb_stick_right);
|
||||
|
||||
xbox_controller.SetButtonState(Xbox360Button.Y, new_state.y);
|
||||
xbox_controller.SetButtonState(Xbox360Button.X, new_state.x);
|
||||
xbox_controller.SetButtonState(Xbox360Button.B, new_state.b);
|
||||
xbox_controller.SetButtonState(Xbox360Button.A, new_state.a);
|
||||
|
||||
xbox_controller.SetButtonState(Xbox360Button.Start, new_state.start);
|
||||
xbox_controller.SetButtonState(Xbox360Button.Back, new_state.back);
|
||||
xbox_controller.SetButtonState(Xbox360Button.Guide, new_state.guide);
|
||||
|
||||
xbox_controller.SetButtonState(Xbox360Button.Up, new_state.dpad_up);
|
||||
xbox_controller.SetButtonState(Xbox360Button.Right, new_state.dpad_right);
|
||||
xbox_controller.SetButtonState(Xbox360Button.Down, new_state.dpad_down);
|
||||
xbox_controller.SetButtonState(Xbox360Button.Left, new_state.dpad_left);
|
||||
|
||||
xbox_controller.SetButtonState(Xbox360Button.LeftShoulder, new_state.shoulder_left);
|
||||
xbox_controller.SetButtonState(Xbox360Button.RightShoulder, new_state.shoulder_right);
|
||||
|
||||
xbox_controller.SetAxisValue(Xbox360Axis.LeftThumbX, new_state.axis_left_x);
|
||||
xbox_controller.SetAxisValue(Xbox360Axis.LeftThumbY, new_state.axis_left_y);
|
||||
xbox_controller.SetAxisValue(Xbox360Axis.RightThumbX, new_state.axis_right_x);
|
||||
xbox_controller.SetAxisValue(Xbox360Axis.RightThumbY, new_state.axis_right_y);
|
||||
|
||||
xbox_controller.SetSliderValue(Xbox360Slider.LeftTrigger, new_state.trigger_left);
|
||||
xbox_controller.SetSliderValue(Xbox360Slider.RightTrigger, new_state.trigger_right);
|
||||
|
||||
xbox_controller.SubmitReport();
|
||||
|
||||
current_state = new_state;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ using System.Runtime.InteropServices;
|
|||
using System.Windows.Forms;
|
||||
using WindowsInput;
|
||||
using Nefarius.ViGEm.Client.Targets.DualShock4;
|
||||
using BetterJoyForCemu.Controller;
|
||||
|
||||
namespace BetterJoyForCemu {
|
||||
public class Joycon {
|
||||
|
@ -222,8 +223,8 @@ namespace BetterJoyForCemu {
|
|||
public ulong Timestamp = 0;
|
||||
public int packetCounter = 0;
|
||||
|
||||
public IXbox360Controller xin;
|
||||
public IDualShock4Controller ds4;
|
||||
public OutputControllerXbox360 out_xbox;
|
||||
public OutputControllerDualShock4 out_ds4;
|
||||
ushort ds4_ts = 0;
|
||||
ulong lag;
|
||||
|
||||
|
@ -267,34 +268,31 @@ namespace BetterJoyForCemu {
|
|||
connection = isUSB ? 0x01 : 0x02;
|
||||
|
||||
if (showAsXInput) {
|
||||
xin = Program.emClient.CreateXbox360Controller();
|
||||
xin.AutoSubmitReport = false;
|
||||
|
||||
if (toRumble)
|
||||
xin.FeedbackReceived += ReceiveRumble;
|
||||
out_xbox = new OutputControllerXbox360();
|
||||
out_xbox.FeedbackReceived += ReceiveRumble;
|
||||
}
|
||||
|
||||
if (showAsDS4) {
|
||||
ds4 = Program.emClient.CreateDualShock4Controller();
|
||||
ds4.AutoSubmitReport = false;
|
||||
out_ds4 = new OutputControllerDualShock4();
|
||||
|
||||
if (toRumble)
|
||||
ds4.FeedbackReceived += Ds4_FeedbackReceived;
|
||||
out_ds4.FeedbackReceived += Ds4_FeedbackReceived;
|
||||
}
|
||||
}
|
||||
|
||||
public void getActiveData() {
|
||||
public void getActiveData()
|
||||
{
|
||||
this.activeData = form.activeCaliData(serial_number);
|
||||
}
|
||||
|
||||
public void ReceiveRumble(object sender, Nefarius.ViGEm.Client.Targets.Xbox360.Xbox360FeedbackReceivedEventArgs e) {
|
||||
public void ReceiveRumble(Xbox360FeedbackReceivedEventArgs e) {
|
||||
SetRumble(lowFreq, highFreq, (float)(e.LargeMotor + e.SmallMotor) / (float)255, rumblePeriod);
|
||||
|
||||
if (other != null && other != this)
|
||||
other.SetRumble(lowFreq, highFreq, (float)(e.LargeMotor + e.SmallMotor) / (float)255, rumblePeriod);
|
||||
}
|
||||
|
||||
public void Ds4_FeedbackReceived(object sender, DualShock4FeedbackReceivedEventArgs e) {
|
||||
public void Ds4_FeedbackReceived(DualShock4FeedbackReceivedEventArgs e) {
|
||||
SetRumble(lowFreq, highFreq, (float)(e.LargeMotor + e.SmallMotor) / (float)255, rumblePeriod);
|
||||
|
||||
if (other != null && other != this)
|
||||
|
@ -472,12 +470,12 @@ namespace BetterJoyForCemu {
|
|||
public void Detach(bool close = false) {
|
||||
stop_polling = true;
|
||||
|
||||
if (xin != null) {
|
||||
xin.Disconnect();
|
||||
if (out_xbox != null) {
|
||||
out_xbox.Disconnect();
|
||||
}
|
||||
|
||||
if (ds4 != null) {
|
||||
ds4.Disconnect();
|
||||
if (out_ds4 != null) {
|
||||
out_ds4.Disconnect();
|
||||
}
|
||||
|
||||
if (state > state_.NO_JOYCONS) {
|
||||
|
@ -505,32 +503,8 @@ namespace BetterJoyForCemu {
|
|||
private int ReceiveRaw() {
|
||||
if (handle == IntPtr.Zero) return -2;
|
||||
HIDapi.hid_set_nonblocking(handle, 1);
|
||||
byte[] raw_buf;
|
||||
|
||||
byte[][] buffers = new byte[][] { new byte[report_len], new byte[report_len] };
|
||||
|
||||
int ret = HIDapi.hid_read(handle, buffers[0], new UIntPtr(report_len));
|
||||
if (ret == 0) return ret;
|
||||
int ret2;
|
||||
|
||||
// read data until there is no more to read and discard all but the latest data
|
||||
while(true)
|
||||
{
|
||||
ret2 = HIDapi.hid_read(handle, buffers[1], new UIntPtr(report_len));
|
||||
if(ret2 == 0)
|
||||
{
|
||||
raw_buf = buffers[0];
|
||||
break;
|
||||
}
|
||||
ret = HIDapi.hid_read(handle, buffers[1], new UIntPtr(report_len));
|
||||
if(ret == 0)
|
||||
{
|
||||
ret = ret2;
|
||||
raw_buf = buffers[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] raw_buf = new byte[report_len];
|
||||
int ret = HIDapi.hid_read_timeout(handle, raw_buf, new UIntPtr(report_len), 5000);
|
||||
if (ret > 0) {
|
||||
// Process packets as soon as they come
|
||||
for (int n = 0; n < 3; n++) {
|
||||
|
@ -555,22 +529,19 @@ namespace BetterJoyForCemu {
|
|||
if (Program.server != null)
|
||||
Program.server.NewReportIncoming(this);
|
||||
|
||||
SetDS4ReportState(n);
|
||||
if (ds4 != null) {
|
||||
if (out_ds4 != null) {
|
||||
try {
|
||||
ds4.SubmitReport();
|
||||
out_ds4.UpdateInput(MapToDualShock4Input(this));
|
||||
} catch (Exception e) {
|
||||
// ignore /shrug
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetXInputReportState();
|
||||
|
||||
|
||||
// no reason to send XInput reports so often
|
||||
if (xin != null) {
|
||||
if (out_xbox != null) {
|
||||
try {
|
||||
xin.SubmitReport();
|
||||
out_xbox.UpdateInput(MapToXbox360Input(this));
|
||||
} catch (Exception e) {
|
||||
// ignore /shrug
|
||||
}
|
||||
|
@ -775,7 +746,6 @@ namespace BetterJoyForCemu {
|
|||
} else if (a == 0) {
|
||||
// The non-blocking read timed out. No need to sleep.
|
||||
// No need to increase attempts because it's not an error.
|
||||
Thread.Sleep((Int32)5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -907,201 +877,6 @@ namespace BetterJoyForCemu {
|
|||
return 0;
|
||||
}
|
||||
|
||||
private void SetXInputReportState() {
|
||||
if (xin == null)
|
||||
return;
|
||||
|
||||
if (isPro) {
|
||||
xin.SetButtonState(Xbox360Button.A, buttons[(int)(!swapAB ? Button.B : Button.A)]);
|
||||
xin.SetButtonState(Xbox360Button.B, buttons[(int)(!swapAB ? Button.A : Button.B)]);
|
||||
xin.SetButtonState(Xbox360Button.Y, buttons[(int)(!swapXY ? Button.X : Button.Y)]);
|
||||
xin.SetButtonState(Xbox360Button.X, buttons[(int)(!swapXY ? Button.Y : Button.X)]);
|
||||
xin.SetButtonState(Xbox360Button.Up, buttons[(int)Button.DPAD_UP]);
|
||||
xin.SetButtonState(Xbox360Button.Down, buttons[(int)Button.DPAD_DOWN]);
|
||||
xin.SetButtonState(Xbox360Button.Left, buttons[(int)Button.DPAD_LEFT]);
|
||||
xin.SetButtonState(Xbox360Button.Right, buttons[(int)Button.DPAD_RIGHT]);
|
||||
xin.SetButtonState(Xbox360Button.Back, buttons[(int)Button.MINUS]);
|
||||
xin.SetButtonState(Xbox360Button.Start, buttons[(int)Button.PLUS]);
|
||||
xin.SetButtonState(Xbox360Button.Guide, buttons[(int)Button.HOME]);
|
||||
xin.SetButtonState(Xbox360Button.LeftShoulder, buttons[(int)Button.SHOULDER_1]);
|
||||
xin.SetButtonState(Xbox360Button.RightShoulder, buttons[(int)Button.SHOULDER2_1]);
|
||||
xin.SetButtonState(Xbox360Button.LeftThumb, buttons[(int)Button.STICK]);
|
||||
xin.SetButtonState(Xbox360Button.RightThumb, buttons[(int)Button.STICK2]);
|
||||
} else {
|
||||
if (other != null) { // no need for && other != this
|
||||
xin.SetButtonState(!swapAB ? Xbox360Button.A : Xbox360Button.B, buttons[(int)(isLeft ? Button.B : Button.DPAD_DOWN)]);
|
||||
xin.SetButtonState(!swapAB ? Xbox360Button.B : Xbox360Button.A, buttons[(int)(isLeft ? Button.A : Button.DPAD_RIGHT)]);
|
||||
xin.SetButtonState(!swapXY ? Xbox360Button.Y : Xbox360Button.X, buttons[(int)(isLeft ? Button.X : Button.DPAD_UP)]);
|
||||
xin.SetButtonState(!swapXY ? Xbox360Button.X : Xbox360Button.Y, buttons[(int)(isLeft ? Button.Y : Button.DPAD_LEFT)]);
|
||||
xin.SetButtonState(Xbox360Button.Up, buttons[(int)(isLeft ? Button.DPAD_UP : Button.X)]);
|
||||
xin.SetButtonState(Xbox360Button.Down, buttons[(int)(isLeft ? Button.DPAD_DOWN : Button.B)]);
|
||||
xin.SetButtonState(Xbox360Button.Left, buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.Y)]);
|
||||
xin.SetButtonState(Xbox360Button.Right, buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.A)]);
|
||||
xin.SetButtonState(Xbox360Button.Back, buttons[(int)Button.MINUS]);
|
||||
xin.SetButtonState(Xbox360Button.Start, buttons[(int)Button.PLUS]);
|
||||
xin.SetButtonState(Xbox360Button.Guide, buttons[(int)Button.HOME]);
|
||||
xin.SetButtonState(Xbox360Button.LeftShoulder, buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER2_1)]);
|
||||
xin.SetButtonState(Xbox360Button.RightShoulder, buttons[(int)(isLeft ? Button.SHOULDER2_1 : Button.SHOULDER_1)]);
|
||||
xin.SetButtonState(Xbox360Button.LeftThumb, buttons[(int)(isLeft ? Button.STICK : Button.STICK2)]);
|
||||
xin.SetButtonState(Xbox360Button.RightThumb, buttons[(int)(isLeft ? Button.STICK2 : Button.STICK)]);
|
||||
} else { // single joycon mode
|
||||
xin.SetButtonState(!swapAB ? Xbox360Button.A : Xbox360Button.B, buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.DPAD_RIGHT)]);
|
||||
xin.SetButtonState(!swapAB ? Xbox360Button.B : Xbox360Button.A, buttons[(int)(isLeft ? Button.DPAD_DOWN : Button.DPAD_UP)]);
|
||||
xin.SetButtonState(!swapXY ? Xbox360Button.Y : Xbox360Button.X, buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.DPAD_LEFT)]);
|
||||
xin.SetButtonState(!swapXY ? Xbox360Button.X : Xbox360Button.Y, buttons[(int)(isLeft ? Button.DPAD_UP : Button.DPAD_DOWN)]);
|
||||
xin.SetButtonState(Xbox360Button.Back, buttons[(int)Button.MINUS] | buttons[(int)Button.HOME]);
|
||||
xin.SetButtonState(Xbox360Button.Start, buttons[(int)Button.PLUS] | buttons[(int)Button.CAPTURE]);
|
||||
|
||||
xin.SetButtonState(Xbox360Button.LeftShoulder, buttons[(int)Button.SL]);
|
||||
xin.SetButtonState(Xbox360Button.RightShoulder, buttons[(int)Button.SR]);
|
||||
|
||||
xin.SetButtonState(Xbox360Button.LeftThumb, buttons[(int)Button.STICK]);
|
||||
}
|
||||
}
|
||||
|
||||
// overwrite guide button if it's custom-mapped
|
||||
if (Config.Value("home") != "0")
|
||||
xin.SetButtonState(Xbox360Button.Guide, false);
|
||||
|
||||
if (!isSnes) {
|
||||
if (other != null || isPro) { // no need for && other != this
|
||||
xin.SetAxisValue(Xbox360Axis.LeftThumbX, CastStickValue((other == this && !isLeft) ? stick2[0] : stick[0]));
|
||||
xin.SetAxisValue(Xbox360Axis.LeftThumbY, CastStickValue((other == this && !isLeft) ? stick2[1] : stick[1]));
|
||||
xin.SetAxisValue(Xbox360Axis.RightThumbX, CastStickValue((other == this && !isLeft) ? stick[0] : stick2[0]));
|
||||
xin.SetAxisValue(Xbox360Axis.RightThumbY, CastStickValue((other == this && !isLeft) ? stick[1] : stick2[1]));
|
||||
} else { // single joycon mode
|
||||
xin.SetAxisValue(Xbox360Axis.LeftThumbY, CastStickValue((isLeft ? 1 : -1) * stick[0]));
|
||||
xin.SetAxisValue(Xbox360Axis.LeftThumbX, CastStickValue((isLeft ? -1 : 1) * stick[1]));
|
||||
}
|
||||
}
|
||||
|
||||
if (other != null || isPro) {
|
||||
byte lval = GyroAnalogSliders ? sliderVal[0] : Byte.MaxValue;
|
||||
byte rval = GyroAnalogSliders ? sliderVal[1] : Byte.MaxValue;
|
||||
xin.SetSliderValue(Xbox360Slider.LeftTrigger, (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER2_2)] ? lval : 0));
|
||||
xin.SetSliderValue(Xbox360Slider.RightTrigger, (byte)(buttons[(int)(isLeft ? Button.SHOULDER2_2 : Button.SHOULDER_2)] ? rval : 0));
|
||||
} else {
|
||||
xin.SetSliderValue(Xbox360Slider.LeftTrigger, (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER_1)] ? Byte.MaxValue : 0));
|
||||
xin.SetSliderValue(Xbox360Slider.RightTrigger, (byte)(buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER_2)] ? Byte.MaxValue : 0));
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDS4ReportState(int n) {
|
||||
if (ds4 == null)
|
||||
return;
|
||||
|
||||
if (isPro) {
|
||||
ds4.SetButtonState(DualShock4Button.Cross, buttons[(int)(!swapAB ? Button.B : Button.A)]);
|
||||
ds4.SetButtonState(DualShock4Button.Circle, buttons[(int)(!swapAB ? Button.A : Button.B)]);
|
||||
ds4.SetButtonState(DualShock4Button.Triangle, buttons[(int)(!swapXY ? Button.X : Button.Y)]);
|
||||
ds4.SetButtonState(DualShock4Button.Square, buttons[(int)(!swapXY ? Button.Y : Button.X)]);
|
||||
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.None);
|
||||
if (buttons[(int)Button.DPAD_LEFT])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.West);
|
||||
if (buttons[(int)Button.DPAD_RIGHT])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.East);
|
||||
if (buttons[(int)Button.DPAD_UP]) {
|
||||
if (buttons[(int)Button.DPAD_LEFT])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.Northwest);
|
||||
else if (buttons[(int)Button.DPAD_RIGHT])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.Northeast);
|
||||
else
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.North);
|
||||
}
|
||||
if (buttons[(int)Button.DPAD_DOWN]) {
|
||||
if (buttons[(int)Button.DPAD_LEFT])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.Southwest);
|
||||
else if (buttons[(int)Button.DPAD_RIGHT])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.Southeast);
|
||||
else
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.South);
|
||||
}
|
||||
|
||||
ds4.SetButtonState(DualShock4Button.Share, buttons[(int)Button.MINUS]);
|
||||
ds4.SetButtonState(DualShock4Button.Options, buttons[(int)Button.PLUS]);
|
||||
ds4.SetButtonState(DualShock4SpecialButton.Ps, buttons[(int)Button.HOME]);
|
||||
ds4.SetButtonState(DualShock4SpecialButton.Touchpad, buttons[(int)Button.CAPTURE]);
|
||||
ds4.SetButtonState(DualShock4Button.ShoulderLeft, buttons[(int)Button.SHOULDER_1]);
|
||||
ds4.SetButtonState(DualShock4Button.ShoulderRight, buttons[(int)Button.SHOULDER2_1]);
|
||||
ds4.SetButtonState(DualShock4Button.ThumbLeft, buttons[(int)Button.STICK]);
|
||||
ds4.SetButtonState(DualShock4Button.ThumbRight, buttons[(int)Button.STICK2]);
|
||||
} else {
|
||||
if (other != null) { // no need for && other != this
|
||||
ds4.SetButtonState(!swapAB ? DualShock4Button.Cross : DualShock4Button.Circle, buttons[(int)(isLeft ? Button.B : Button.DPAD_DOWN)]);
|
||||
ds4.SetButtonState(!swapAB ? DualShock4Button.Circle : DualShock4Button.Cross, buttons[(int)(isLeft ? Button.A : Button.DPAD_RIGHT)]);
|
||||
ds4.SetButtonState(!swapXY ? DualShock4Button.Triangle : DualShock4Button.Square, buttons[(int)(isLeft ? Button.X : Button.DPAD_UP)]);
|
||||
ds4.SetButtonState(!swapXY ? DualShock4Button.Square : DualShock4Button.Triangle, buttons[(int)(isLeft ? Button.Y : Button.DPAD_LEFT)]);
|
||||
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.None);
|
||||
if (buttons[(int)(isLeft ? Button.DPAD_UP : Button.X)])
|
||||
if (buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.Y)])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.Northwest);
|
||||
else if (buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.A)])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.Northeast);
|
||||
else
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.North);
|
||||
if (buttons[(int)(isLeft ? Button.DPAD_DOWN : Button.B)])
|
||||
if (buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.Y)])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.Southwest);
|
||||
else if (buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.A)])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.Southeast);
|
||||
else
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.South);
|
||||
if (buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.Y)])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.West);
|
||||
if (buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.A)])
|
||||
ds4.SetDPadDirection(DualShock4DPadDirection.East);
|
||||
|
||||
ds4.SetButtonState(DualShock4Button.Share, buttons[(int)Button.MINUS]);
|
||||
ds4.SetButtonState(DualShock4Button.Options, buttons[(int)Button.PLUS]);
|
||||
ds4.SetButtonState(DualShock4SpecialButton.Ps, buttons[(int)Button.HOME]);
|
||||
ds4.SetButtonState(DualShock4SpecialButton.Touchpad, buttons[(int)Button.CAPTURE]);
|
||||
ds4.SetButtonState(DualShock4Button.ShoulderLeft, buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER2_1)]);
|
||||
ds4.SetButtonState(DualShock4Button.ShoulderRight, buttons[(int)(isLeft ? Button.SHOULDER2_1 : Button.SHOULDER_1)]);
|
||||
ds4.SetButtonState(DualShock4Button.ThumbLeft, buttons[(int)(isLeft ? Button.STICK : Button.STICK2)]);
|
||||
ds4.SetButtonState(DualShock4Button.ThumbRight, buttons[(int)(isLeft ? Button.STICK2 : Button.STICK)]);
|
||||
} else { // single joycon mode
|
||||
ds4.SetButtonState(!swapAB ? DualShock4Button.Cross : DualShock4Button.Circle, buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.DPAD_RIGHT)]);
|
||||
ds4.SetButtonState(!swapAB ? DualShock4Button.Circle : DualShock4Button.Cross, buttons[(int)(isLeft ? Button.DPAD_DOWN : Button.DPAD_UP)]);
|
||||
ds4.SetButtonState(!swapXY ? DualShock4Button.Triangle : DualShock4Button.Square, buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.DPAD_LEFT)]);
|
||||
ds4.SetButtonState(!swapXY ? DualShock4Button.Square : DualShock4Button.Triangle, buttons[(int)(isLeft ? Button.DPAD_UP : Button.DPAD_DOWN)]);
|
||||
ds4.SetButtonState(DualShock4Button.Share, buttons[(int)Button.MINUS] | buttons[(int)Button.HOME]);
|
||||
ds4.SetButtonState(DualShock4Button.Options, buttons[(int)Button.PLUS] | buttons[(int)Button.CAPTURE]);
|
||||
|
||||
ds4.SetButtonState(DualShock4Button.ShoulderLeft, buttons[(int)Button.SL]);
|
||||
ds4.SetButtonState(DualShock4Button.ShoulderRight, buttons[(int)Button.SR]);
|
||||
|
||||
ds4.SetButtonState(DualShock4Button.ThumbLeft, buttons[(int)Button.STICK]);
|
||||
}
|
||||
}
|
||||
|
||||
// overwrite guide button if it's custom-mapped
|
||||
if (Config.Value("home") != "0")
|
||||
ds4.SetButtonState(DualShock4SpecialButton.Ps, false);
|
||||
|
||||
if (!isSnes) {
|
||||
if (other != null || isPro) { // no need for && other != this
|
||||
ds4.SetAxisValue(DualShock4Axis.LeftThumbX, CastStickValueByte((other == this && !isLeft) ? -stick2[0] : -stick[0]));
|
||||
ds4.SetAxisValue(DualShock4Axis.LeftThumbY, CastStickValueByte((other == this && !isLeft) ? stick2[1] : stick[1]));
|
||||
ds4.SetAxisValue(DualShock4Axis.RightThumbX, CastStickValueByte((other == this && !isLeft) ? -stick[0] : -stick2[0]));
|
||||
ds4.SetAxisValue(DualShock4Axis.RightThumbY, CastStickValueByte((other == this && !isLeft) ? stick[1] : stick2[1]));
|
||||
} else { // single joycon mode
|
||||
ds4.SetAxisValue(DualShock4Axis.LeftThumbY, CastStickValueByte((isLeft ? 1 : -1) * stick[0]));
|
||||
ds4.SetAxisValue(DualShock4Axis.LeftThumbX, CastStickValueByte((isLeft ? 1 : -1) * stick[1]));
|
||||
}
|
||||
}
|
||||
|
||||
if (other != null || isPro) {
|
||||
byte lval = GyroAnalogSliders ? sliderVal[0] : Byte.MaxValue;
|
||||
byte rval = GyroAnalogSliders ? sliderVal[1] : Byte.MaxValue;
|
||||
ds4.SetSliderValue(DualShock4Slider.LeftTrigger, (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER2_2)] ? lval : 0));
|
||||
ds4.SetSliderValue(DualShock4Slider.RightTrigger, (byte)(buttons[(int)(isLeft ? Button.SHOULDER2_2 : Button.SHOULDER_2)] ? rval : 0));
|
||||
} else {
|
||||
ds4.SetSliderValue(DualShock4Slider.LeftTrigger, (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER_1)] ? Byte.MaxValue : 0));
|
||||
ds4.SetSliderValue(DualShock4Slider.RightTrigger, (byte)(buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER_2)] ? Byte.MaxValue : 0));
|
||||
}
|
||||
}
|
||||
|
||||
// Get Gyro/Accel data
|
||||
private void ExtractIMUValues(byte[] report_buf, int n = 0) {
|
||||
|
@ -1215,11 +990,11 @@ namespace BetterJoyForCemu {
|
|||
return s;
|
||||
}
|
||||
|
||||
private short CastStickValue(float stick_value) {
|
||||
private static short CastStickValue(float stick_value) {
|
||||
return (short)Math.Max(Int16.MinValue, Math.Min(Int16.MaxValue, stick_value * (stick_value > 0 ? Int16.MaxValue : -Int16.MinValue)));
|
||||
}
|
||||
|
||||
private byte CastStickValueByte(float stick_value) {
|
||||
private static byte CastStickValueByte(float stick_value) {
|
||||
return (byte)Math.Max(Byte.MinValue, Math.Min(Byte.MaxValue, 127 - stick_value * Byte.MaxValue));
|
||||
}
|
||||
|
||||
|
@ -1385,5 +1160,271 @@ namespace BetterJoyForCemu {
|
|||
}
|
||||
DebugPrint(string.Format(format, tostr), d);
|
||||
}
|
||||
|
||||
private static OutputControllerXbox360InputState MapToXbox360Input(Joycon input)
|
||||
{
|
||||
var output = new OutputControllerXbox360InputState();
|
||||
|
||||
var swapAB = input.swapAB;
|
||||
var swapXY = input.swapXY;
|
||||
|
||||
var isPro = input.isPro;
|
||||
var isLeft = input.isLeft;
|
||||
var isSnes = input.isSnes;
|
||||
var other = input.other;
|
||||
var GyroAnalogSliders = input.GyroAnalogSliders;
|
||||
|
||||
var buttons = input.buttons;
|
||||
var stick = input.stick;
|
||||
var stick2 = input.stick2;
|
||||
var sliderVal = input.sliderVal;
|
||||
|
||||
if (isPro)
|
||||
{
|
||||
output.a = buttons[(int)(!swapAB ? Button.B : Button.A)];
|
||||
output.b = buttons[(int)(!swapAB ? Button.A : Button.B)];
|
||||
output.y = buttons[(int)(!swapXY ? Button.X : Button.Y)];
|
||||
output.x = buttons[(int)(!swapXY ? Button.Y : Button.X)];
|
||||
|
||||
output.dpad_up = buttons[(int)Button.DPAD_UP];
|
||||
output.dpad_down = buttons[(int)Button.DPAD_DOWN];
|
||||
output.dpad_left = buttons[(int)Button.DPAD_LEFT];
|
||||
output.dpad_right = buttons[(int)Button.DPAD_RIGHT];
|
||||
|
||||
output.back = buttons[(int)Button.MINUS];
|
||||
output.start = buttons[(int)Button.PLUS];
|
||||
output.guide = buttons[(int)Button.HOME];
|
||||
|
||||
output.shoulder_left = buttons[(int)Button.SHOULDER_1];
|
||||
output.shoulder_right = buttons[(int)Button.SHOULDER2_1];
|
||||
|
||||
output.thumb_stick_left = buttons[(int)Button.STICK];
|
||||
output.thumb_stick_right = buttons[(int)Button.STICK2];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (other != null)
|
||||
{ // no need for && other != this
|
||||
output.a = buttons[(int)(!swapAB ? isLeft ? Button.B : Button.DPAD_DOWN : isLeft ? Button.A : Button.DPAD_RIGHT)];
|
||||
output.b = buttons[(int)(swapAB ? isLeft ? Button.B : Button.DPAD_DOWN : isLeft ? Button.A : Button.DPAD_RIGHT)];
|
||||
output.y = buttons[(int)(!swapXY ? isLeft ? Button.X : Button.DPAD_UP : isLeft ? Button.Y : Button.DPAD_LEFT)];
|
||||
output.x = buttons[(int)(swapXY ? isLeft ? Button.X : Button.DPAD_UP : isLeft ? Button.Y : Button.DPAD_LEFT)];
|
||||
|
||||
output.dpad_up = buttons[(int)(isLeft ? Button.DPAD_UP : Button.X)];
|
||||
output.dpad_down = buttons[(int)(isLeft ? Button.DPAD_DOWN : Button.B)];
|
||||
output.dpad_left = buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.Y)];
|
||||
output.dpad_right = buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.A)];
|
||||
|
||||
output.back = buttons[(int)Button.MINUS];
|
||||
output.start = buttons[(int)Button.PLUS];
|
||||
output.guide = buttons[(int)Button.HOME];
|
||||
|
||||
output.shoulder_left = buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER2_1)];
|
||||
output.shoulder_right = buttons[(int)(isLeft ? Button.SHOULDER2_1 : Button.SHOULDER_1)];
|
||||
|
||||
output.thumb_stick_left = buttons[(int)(isLeft ? Button.STICK : Button.STICK2)];
|
||||
output.thumb_stick_right = buttons[(int)(isLeft ? Button.STICK2 : Button.STICK)];
|
||||
}
|
||||
else
|
||||
{ // single joycon mode
|
||||
output.a = buttons[(int)(!swapAB ? isLeft ? Button.DPAD_LEFT : Button.DPAD_RIGHT : isLeft ? Button.DPAD_DOWN : Button.DPAD_UP)];
|
||||
output.b = buttons[(int)(swapAB ? isLeft ? Button.DPAD_LEFT : Button.DPAD_RIGHT : isLeft ? Button.DPAD_DOWN : Button.DPAD_UP)];
|
||||
output.y = buttons[(int)(!swapXY ? isLeft ? Button.DPAD_RIGHT : Button.DPAD_LEFT : isLeft ? Button.DPAD_UP : Button.DPAD_DOWN)];
|
||||
output.x = buttons[(int)(swapXY ? isLeft ? Button.DPAD_RIGHT : Button.DPAD_LEFT : isLeft ? Button.DPAD_UP : Button.DPAD_DOWN)];
|
||||
|
||||
output.back = buttons[(int)Button.MINUS] | buttons[(int)Button.HOME];
|
||||
output.start = buttons[(int)Button.PLUS] | buttons[(int)Button.CAPTURE];
|
||||
|
||||
output.shoulder_left = buttons[(int)Button.SL];
|
||||
output.shoulder_right = buttons[(int)Button.SR];
|
||||
|
||||
output.thumb_stick_left = buttons[(int)Button.STICK];
|
||||
}
|
||||
}
|
||||
|
||||
// overwrite guide button if it's custom-mapped
|
||||
if (Config.Value("home") != "0")
|
||||
output.guide = false;
|
||||
|
||||
if (!isSnes)
|
||||
{
|
||||
if (other != null || isPro)
|
||||
{ // no need for && other != this
|
||||
output.axis_left_x = CastStickValue((other == input && !isLeft) ? stick2[0] : stick[0]);
|
||||
output.axis_left_y = CastStickValue((other == input && !isLeft) ? stick2[1] : stick[1]);
|
||||
|
||||
output.axis_right_x = CastStickValue((other == input && !isLeft) ? stick[0] : stick2[0]);
|
||||
output.axis_right_y = CastStickValue((other == input && !isLeft) ? stick[1] : stick2[1]);
|
||||
}
|
||||
else
|
||||
{ // single joycon mode
|
||||
output.axis_left_x = CastStickValue((isLeft ? 1 : -1) * stick[0]);
|
||||
output.axis_left_y = CastStickValue((isLeft ? -1 : 1) * stick[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (other != null || isPro)
|
||||
{
|
||||
byte lval = GyroAnalogSliders ? sliderVal[0] : Byte.MaxValue;
|
||||
byte rval = GyroAnalogSliders ? sliderVal[1] : Byte.MaxValue;
|
||||
output.trigger_left = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER2_2)] ? lval : 0);
|
||||
output.trigger_right = (byte)(buttons[(int)(isLeft ? Button.SHOULDER2_2 : Button.SHOULDER_2)] ? rval : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
output.trigger_left = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER_1)] ? Byte.MaxValue : 0);
|
||||
output.trigger_right = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER_2)] ? Byte.MaxValue : 0);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
private static OutputControllerDualShock4InputState MapToDualShock4Input(Joycon input)
|
||||
{
|
||||
var output = new OutputControllerDualShock4InputState();
|
||||
|
||||
var swapAB = input.swapAB;
|
||||
var swapXY = input.swapXY;
|
||||
|
||||
var isPro = input.isPro;
|
||||
var isLeft = input.isLeft;
|
||||
var isSnes = input.isSnes;
|
||||
var other = input.other;
|
||||
var GyroAnalogSliders = input.GyroAnalogSliders;
|
||||
|
||||
var buttons = input.buttons;
|
||||
var stick = input.stick;
|
||||
var stick2 = input.stick2;
|
||||
var sliderVal = input.sliderVal;
|
||||
|
||||
if (isPro)
|
||||
{
|
||||
output.cross = buttons[(int)(!swapAB ? Button.B : Button.A)];
|
||||
output.circle = buttons[(int)(!swapAB ? Button.A : Button.B)];
|
||||
output.triangle = buttons[(int)(!swapXY ? Button.X : Button.Y)];
|
||||
output.square = buttons[(int)(!swapXY ? Button.Y : Button.X)];
|
||||
|
||||
|
||||
if (buttons[(int)Button.DPAD_UP])
|
||||
{
|
||||
if (buttons[(int)Button.DPAD_LEFT])
|
||||
output.dPad = DpadDirection.Northwest;
|
||||
else if (buttons[(int)Button.DPAD_RIGHT])
|
||||
output.dPad = DpadDirection.Northeast;
|
||||
else
|
||||
output.dPad = DpadDirection.North;
|
||||
}
|
||||
else if (buttons[(int)Button.DPAD_DOWN])
|
||||
{
|
||||
if (buttons[(int)Button.DPAD_LEFT])
|
||||
output.dPad = DpadDirection.Southwest;
|
||||
else if (buttons[(int)Button.DPAD_RIGHT])
|
||||
output.dPad = DpadDirection.Southeast;
|
||||
else
|
||||
output.dPad = DpadDirection.South;
|
||||
}
|
||||
else if (buttons[(int)Button.DPAD_LEFT])
|
||||
output.dPad = DpadDirection.West;
|
||||
else if (buttons[(int)Button.DPAD_RIGHT])
|
||||
output.dPad = DpadDirection.East;
|
||||
|
||||
output.share = buttons[(int)Button.MINUS];
|
||||
output.options = buttons[(int)Button.PLUS];
|
||||
output.ps = buttons[(int)Button.HOME];
|
||||
output.touchpad = buttons[(int)Button.CAPTURE];
|
||||
output.shoulder_left = buttons[(int)Button.SHOULDER_1];
|
||||
output.shoulder_right = buttons[(int)Button.SHOULDER2_1];
|
||||
output.thumb_left = buttons[(int)Button.STICK];
|
||||
output.thumb_right = buttons[(int)Button.STICK2];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (other != null)
|
||||
{ // no need for && other != this
|
||||
output.circle = !swapAB ? buttons[(int)(isLeft ? Button.B : Button.DPAD_DOWN)] : buttons[(int)(isLeft ? Button.A : Button.DPAD_RIGHT)];
|
||||
output.cross = swapAB ? buttons[(int)(isLeft ? Button.B : Button.DPAD_DOWN)] : buttons[(int)(isLeft ? Button.A : Button.DPAD_RIGHT)];
|
||||
output.triangle = !swapXY ? buttons[(int)(isLeft ? Button.X : Button.DPAD_UP)] : buttons[(int)(isLeft ? Button.Y : Button.DPAD_LEFT)];
|
||||
output.triangle = swapXY ? buttons[(int)(isLeft ? Button.X : Button.DPAD_UP)] : buttons[(int)(isLeft ? Button.Y : Button.DPAD_LEFT)];
|
||||
|
||||
if (buttons[(int)(isLeft ? Button.DPAD_UP : Button.X)])
|
||||
if (buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.Y)])
|
||||
output.dPad = DpadDirection.Northwest;
|
||||
else if (buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.A)])
|
||||
output.dPad = DpadDirection.Northeast;
|
||||
else
|
||||
output.dPad = DpadDirection.North;
|
||||
else if (buttons[(int)(isLeft ? Button.DPAD_DOWN : Button.B)])
|
||||
if (buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.Y)])
|
||||
output.dPad = DpadDirection.Southwest;
|
||||
else if (buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.A)])
|
||||
output.dPad = DpadDirection.Southeast;
|
||||
else
|
||||
output.dPad = DpadDirection.South;
|
||||
else if (buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.Y)])
|
||||
output.dPad = DpadDirection.West;
|
||||
else if (buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.A)])
|
||||
output.dPad = DpadDirection.East;
|
||||
|
||||
output.share = buttons[(int)Button.MINUS];
|
||||
output.options = buttons[(int)Button.PLUS];
|
||||
output.ps = buttons[(int)Button.HOME];
|
||||
output.touchpad = buttons[(int)Button.CAPTURE];
|
||||
output.shoulder_left = buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER2_1)];
|
||||
output.shoulder_right = buttons[(int)(isLeft ? Button.SHOULDER2_1 : Button.SHOULDER_1)];
|
||||
output.thumb_left = buttons[(int)(isLeft ? Button.STICK : Button.STICK2)];
|
||||
output.thumb_right = buttons[(int)(isLeft ? Button.STICK2 : Button.STICK)];
|
||||
}
|
||||
else
|
||||
{ // single joycon mode
|
||||
output.cross = !swapAB ? buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.DPAD_RIGHT)] : buttons[(int)(isLeft ? Button.DPAD_DOWN : Button.DPAD_UP)];
|
||||
output.circle = swapAB ? buttons[(int)(isLeft ? Button.DPAD_LEFT : Button.DPAD_RIGHT)] : buttons[(int)(isLeft ? Button.DPAD_DOWN : Button.DPAD_UP)];
|
||||
output.triangle = !swapXY ? buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.DPAD_LEFT)] : buttons[(int)(isLeft ? Button.DPAD_UP : Button.DPAD_DOWN)];
|
||||
output.square = swapXY ? buttons[(int)(isLeft ? Button.DPAD_RIGHT : Button.DPAD_LEFT)] : buttons[(int)(isLeft ? Button.DPAD_UP : Button.DPAD_DOWN)];
|
||||
|
||||
output.square = buttons[(int)Button.MINUS] | buttons[(int)Button.HOME];
|
||||
output.options = buttons[(int)Button.PLUS] | buttons[(int)Button.CAPTURE];
|
||||
|
||||
output.shoulder_left = buttons[(int)Button.SL];
|
||||
output.shoulder_right = buttons[(int)Button.SR];
|
||||
|
||||
output.thumb_left = buttons[(int)Button.STICK];
|
||||
}
|
||||
}
|
||||
|
||||
// overwrite guide button if it's custom-mapped
|
||||
if (Config.Value("home") != "0")
|
||||
output.ps = false;
|
||||
|
||||
if (!isSnes)
|
||||
{
|
||||
if (other != null || isPro)
|
||||
{ // no need for && other != this
|
||||
output.thumb_left_x = CastStickValueByte((other == input && !isLeft) ? -stick2[0] : -stick[0]);
|
||||
output.thumb_left_y = CastStickValueByte((other == input && !isLeft) ? stick2[1] : stick[1]);
|
||||
output.thumb_right_x = CastStickValueByte((other == input && !isLeft) ? -stick[0] : -stick2[0]);
|
||||
output.thumb_right_y = CastStickValueByte((other == input && !isLeft) ? stick[1] : stick2[1]);
|
||||
}
|
||||
else
|
||||
{ // single joycon mode
|
||||
output.thumb_left_x = CastStickValueByte((isLeft ? 1 : -1) * stick[0]);
|
||||
output.thumb_left_y = CastStickValueByte((isLeft ? 1 : -1) * stick[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (other != null || isPro)
|
||||
{
|
||||
byte lval = GyroAnalogSliders ? sliderVal[0] : Byte.MaxValue;
|
||||
byte rval = GyroAnalogSliders ? sliderVal[1] : Byte.MaxValue;
|
||||
output.trigger_left_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER2_2)] ? lval : 0);
|
||||
output.trigger_right_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER2_2 : Button.SHOULDER_2)] ? rval : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
output.trigger_left_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER_1)] ? Byte.MaxValue : 0);
|
||||
output.trigger_right_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER_2)] ? Byte.MaxValue : 0);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -178,14 +178,14 @@ namespace BetterJoyForCemu {
|
|||
jc.SetPlayerLED(led);
|
||||
v.SetPlayerLED(led);
|
||||
|
||||
if (v.xin != null) {
|
||||
v.xin.Disconnect();
|
||||
v.xin = null;
|
||||
if (v.out_xbox != null) {
|
||||
v.out_xbox.Disconnect();
|
||||
v.out_xbox = null;
|
||||
}
|
||||
|
||||
if (v.ds4 != null) {
|
||||
v.ds4.Disconnect();
|
||||
v.ds4 = null;
|
||||
if (v.out_ds4 != null) {
|
||||
v.out_ds4.Disconnect();
|
||||
v.out_ds4 = null;
|
||||
}
|
||||
|
||||
// setting the other joycon's button image
|
||||
|
@ -262,21 +262,20 @@ namespace BetterJoyForCemu {
|
|||
}
|
||||
|
||||
void ReenableViGEm(Joycon v) {
|
||||
if (showAsXInput && v.xin == null) {
|
||||
v.xin = Program.emClient.CreateXbox360Controller();
|
||||
if (showAsXInput && v.out_xbox == null) {
|
||||
v.out_xbox = new Controller.OutputControllerXbox360();
|
||||
|
||||
if (toRumble)
|
||||
v.xin.FeedbackReceived += v.ReceiveRumble;
|
||||
v.xin.Connect();
|
||||
v.out_xbox.FeedbackReceived += v.ReceiveRumble;
|
||||
v.out_xbox.Connect();
|
||||
}
|
||||
|
||||
if (showAsDS4 && v.ds4 == null) {
|
||||
v.ds4 = Program.emClient.CreateDualShock4Controller();
|
||||
v.ds4.AutoSubmitReport = false;
|
||||
if (showAsDS4 && v.out_ds4 == null) {
|
||||
v.out_ds4 = new Controller.OutputControllerDualShock4();
|
||||
|
||||
if (toRumble)
|
||||
v.ds4.FeedbackReceived += v.Ds4_FeedbackReceived;
|
||||
v.ds4.Connect();
|
||||
v.out_ds4.FeedbackReceived += v.Ds4_FeedbackReceived;
|
||||
v.out_ds4.Connect();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -239,22 +239,22 @@ namespace BetterJoyForCemu {
|
|||
temp.SetPlayerLED(led);
|
||||
v.SetPlayerLED(led);
|
||||
|
||||
if (temp.xin != null) {
|
||||
if (temp.out_xbox != null) {
|
||||
try {
|
||||
temp.xin.Disconnect();
|
||||
temp.out_xbox.Disconnect();
|
||||
} catch (Exception e) {
|
||||
// it wasn't connected in the first place, go figure
|
||||
}
|
||||
}
|
||||
if (temp.ds4 != null) {
|
||||
if (temp.out_ds4 != null) {
|
||||
try {
|
||||
temp.ds4.Disconnect();
|
||||
temp.out_ds4.Disconnect();
|
||||
} catch (Exception e) {
|
||||
// it wasn't connected in the first place, go figure
|
||||
}
|
||||
}
|
||||
temp.xin = null;
|
||||
temp.ds4 = null;
|
||||
temp.out_xbox = null;
|
||||
temp.out_ds4 = null;
|
||||
|
||||
foreach (Button b in form.con)
|
||||
if (b.Tag == v || b.Tag == temp) {
|
||||
|
@ -272,10 +272,10 @@ namespace BetterJoyForCemu {
|
|||
|
||||
foreach (Joycon jc in j) { // Connect device straight away
|
||||
if (jc.state == Joycon.state_.NOT_ATTACHED) {
|
||||
if (jc.xin != null)
|
||||
jc.xin.Connect();
|
||||
if (jc.ds4 != null)
|
||||
jc.ds4.Connect();
|
||||
if (jc.out_xbox != null)
|
||||
jc.out_xbox.Connect();
|
||||
if (jc.out_ds4 != null)
|
||||
jc.out_ds4.Connect();
|
||||
|
||||
jc.Attach(leds_: jc.LED);
|
||||
|
||||
|
@ -305,12 +305,12 @@ namespace BetterJoyForCemu {
|
|||
else
|
||||
v.Detach();
|
||||
|
||||
if (v.xin != null) {
|
||||
v.xin.Disconnect();
|
||||
if (v.out_xbox != null) {
|
||||
v.out_xbox.Disconnect();
|
||||
}
|
||||
|
||||
if (v.ds4 != null) {
|
||||
v.ds4.Disconnect();
|
||||
if (v.out_ds4 != null) {
|
||||
v.out_ds4.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue