Skip to content

Commit

Permalink
MotionServer DS4 mapping (#743)
Browse files Browse the repository at this point in the history
* Fix DS4 button mapping for PS and square buttons

* Use DS4 mapping for UdpServer

Leverage the complex single vs. double joycon vs. pro logic in the
Show as DS4 mapping code so that the MotionServer can properly support
a single joycon with SL and SR buttons available.
  • Loading branch information
kcghost committed Mar 31, 2021
1 parent 2ca18ff commit 8d5fd67
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 43 deletions.
4 changes: 2 additions & 2 deletions BetterJoyForCemu/Joycon.cs
Expand Up @@ -1353,7 +1353,7 @@ private struct Rumble {
return output;
}

private static OutputControllerDualShock4InputState MapToDualShock4Input(Joycon input) {
public static OutputControllerDualShock4InputState MapToDualShock4Input(Joycon input) {
var output = new OutputControllerDualShock4InputState();

var swapAB = input.swapAB;
Expand Down Expand Up @@ -1444,7 +1444,7 @@ private struct Rumble {
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.ps = 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];
Expand Down
77 changes: 36 additions & 41 deletions BetterJoyForCemu/UpdServer.cs
Expand Up @@ -317,62 +317,57 @@ class ClientRequestTimes {
}
}

bool swapAB = Boolean.Parse(ConfigurationManager.AppSettings["SwapAB"]);
bool swapXY = Boolean.Parse(ConfigurationManager.AppSettings["SwapXY"]);
private bool ReportToBuffer(Joycon hidReport, byte[] outputData, ref int outIdx) {
outputData[outIdx] = 0;
var ds4 = Joycon.MapToDualShock4Input(hidReport);

bool isLeft = hidReport.isLeft;
outputData[outIdx] = 0;

if (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_LEFT : Joycon.Button.Y)) outputData[outIdx] |= 0x80;
if (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_DOWN : Joycon.Button.B)) outputData[outIdx] |= 0x40;
if (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_RIGHT : Joycon.Button.A)) outputData[outIdx] |= 0x20;
if (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_UP : Joycon.Button.X)) outputData[outIdx] |= 0x10;
if (ds4.dPad == Controller.DpadDirection.West || ds4.dPad == Controller.DpadDirection.Northwest || ds4.dPad == Controller.DpadDirection.Southwest) outputData[outIdx] |= 0x80;
if (ds4.dPad == Controller.DpadDirection.South || ds4.dPad == Controller.DpadDirection.Southwest || ds4.dPad == Controller.DpadDirection.Southeast) outputData[outIdx] |= 0x40;
if (ds4.dPad == Controller.DpadDirection.East || ds4.dPad == Controller.DpadDirection.Northeast || ds4.dPad == Controller.DpadDirection.Southeast) outputData[outIdx] |= 0x20;
if (ds4.dPad == Controller.DpadDirection.North || ds4.dPad == Controller.DpadDirection.Northwest || ds4.dPad == Controller.DpadDirection.Northeast) outputData[outIdx] |= 0x10;

if (hidReport.GetButton(Joycon.Button.PLUS)) outputData[outIdx] |= 0x08;
if (hidReport.GetButton(isLeft ? Joycon.Button.STICK2 : Joycon.Button.STICK)) outputData[outIdx] |= 0x04;
if (hidReport.GetButton(isLeft ? Joycon.Button.STICK : Joycon.Button.STICK2)) outputData[outIdx] |= 0x02;
if (hidReport.GetButton(Joycon.Button.MINUS)) outputData[outIdx] |= 0x01;
if (ds4.options) outputData[outIdx] |= 0x08;
if (ds4.thumb_right) outputData[outIdx] |= 0x04;
if (ds4.thumb_left) outputData[outIdx] |= 0x02;
if (ds4.share) outputData[outIdx] |= 0x01;

outputData[++outIdx] = 0;

if (hidReport.GetButton(!swapXY ? (isLeft ? Joycon.Button.Y : Joycon.Button.DPAD_LEFT) : (isLeft ? Joycon.Button.X : Joycon.Button.DPAD_UP))) outputData[outIdx] |= 0x80;
if (hidReport.GetButton(!swapAB ? (isLeft ? Joycon.Button.B : Joycon.Button.DPAD_DOWN) : (isLeft ? Joycon.Button.A : Joycon.Button.DPAD_RIGHT))) outputData[outIdx] |= 0x40;
if (hidReport.GetButton(!swapAB ? (isLeft ? Joycon.Button.A : Joycon.Button.DPAD_RIGHT) : (isLeft ? Joycon.Button.B : Joycon.Button.DPAD_DOWN))) outputData[outIdx] |= 0x20;
if (hidReport.GetButton(!swapXY ? (isLeft ? Joycon.Button.X : Joycon.Button.DPAD_UP) : (isLeft ? Joycon.Button.Y : Joycon.Button.DPAD_LEFT))) outputData[outIdx] |= 0x10;

if (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER2_1 : Joycon.Button.SHOULDER_1)) outputData[outIdx] |= 0x08;
if (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER_1 : Joycon.Button.SHOULDER2_1)) outputData[outIdx] |= 0x04;
if (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER2_2 : Joycon.Button.SHOULDER_2)) outputData[outIdx] |= 0x02;
if (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER_2 : Joycon.Button.SHOULDER2_2)) outputData[outIdx] |= 0x01;
if (ds4.square) outputData[outIdx] |= 0x80;
if (ds4.cross) outputData[outIdx] |= 0x40;
if (ds4.circle) outputData[outIdx] |= 0x20;
if (ds4.triangle) outputData[outIdx] |= 0x10;

outputData[++outIdx] = (hidReport.GetButton(Joycon.Button.HOME)) ? (byte)1 : (byte)0;
outputData[++outIdx] = 0; // no touch pad
if (ds4.shoulder_right) outputData[outIdx] |= 0x08;
if (ds4.shoulder_left) outputData[outIdx] |= 0x04;
if (ds4.trigger_right_value == Byte.MaxValue) outputData[outIdx] |= 0x02;
if (ds4.trigger_left_value == Byte.MaxValue) outputData[outIdx] |= 0x01;

float[] leftStick = hidReport.GetStick(); // 127 is 0
outputData[++outIdx] = (byte)(Math.Max(0, Math.Min(255, 127 + leftStick[0] * 127)));
outputData[++outIdx] = (byte)(Math.Max(0, Math.Min(255, 127 + leftStick[1] * 127)));
outputData[++outIdx] = ds4.ps ? (byte)1 : (byte)0;
outputData[++outIdx] = ds4.touchpad ? (byte)1 : (byte)0;

float[] rightStick = hidReport.GetStick2(); // 127 is 0
outputData[++outIdx] = (byte)(Math.Max(0, Math.Min(255, 127 + rightStick[0] * 127)));
outputData[++outIdx] = (byte)(Math.Max(0, Math.Min(255, 127 + rightStick[1] * 127)));
outputData[++outIdx] = ds4.thumb_left_x;
outputData[++outIdx] = ds4.thumb_left_y;
outputData[++outIdx] = ds4.thumb_right_x;
outputData[++outIdx] = ds4.thumb_right_y;

//we don't have analog buttons so just use the Button enums (which give either 0 or 0xFF)
outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_LEFT : Joycon.Button.Y)) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_DOWN : Joycon.Button.B)) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_RIGHT : Joycon.Button.A)) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.DPAD_UP : Joycon.Button.X)) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (ds4.dPad == Controller.DpadDirection.West || ds4.dPad == Controller.DpadDirection.Northwest || ds4.dPad == Controller.DpadDirection.Southwest) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (ds4.dPad == Controller.DpadDirection.South || ds4.dPad == Controller.DpadDirection.Southwest || ds4.dPad == Controller.DpadDirection.Southeast) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (ds4.dPad == Controller.DpadDirection.East || ds4.dPad == Controller.DpadDirection.Northeast || ds4.dPad == Controller.DpadDirection.Southeast) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (ds4.dPad == Controller.DpadDirection.North || ds4.dPad == Controller.DpadDirection.Northwest || ds4.dPad == Controller.DpadDirection.Northeast) ? (byte)0xFF : (byte)0; ;

outputData[++outIdx] = (hidReport.GetButton(!swapXY ? (isLeft ? Joycon.Button.Y : Joycon.Button.DPAD_LEFT) : (isLeft ? Joycon.Button.X : Joycon.Button.DPAD_UP))) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (hidReport.GetButton(!swapAB ? (isLeft ? Joycon.Button.B : Joycon.Button.DPAD_DOWN) : (isLeft ? Joycon.Button.A : Joycon.Button.DPAD_RIGHT))) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (hidReport.GetButton(!swapAB ? (isLeft ? Joycon.Button.A : Joycon.Button.DPAD_RIGHT) : (isLeft ? Joycon.Button.B : Joycon.Button.DPAD_DOWN))) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (hidReport.GetButton(!swapXY ? (isLeft ? Joycon.Button.X : Joycon.Button.DPAD_UP) : (isLeft ? Joycon.Button.Y : Joycon.Button.DPAD_LEFT))) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = ds4.square ? (byte)0xFF : (byte)0;
outputData[++outIdx] = ds4.cross ? (byte)0xFF : (byte)0;
outputData[++outIdx] = ds4.circle ? (byte)0xFF : (byte)0;
outputData[++outIdx] = ds4.triangle ? (byte)0xFF : (byte)0;

outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER2_1 : Joycon.Button.SHOULDER_1)) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER_1 : Joycon.Button.SHOULDER2_1)) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = ds4.shoulder_right ? (byte)0xFF : (byte)0;
outputData[++outIdx] = ds4.shoulder_left ? (byte)0xFF : (byte)0;

outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER2_2 : Joycon.Button.SHOULDER_2)) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = (hidReport.GetButton(isLeft ? Joycon.Button.SHOULDER_2 : Joycon.Button.SHOULDER2_2)) ? (byte)0xFF : (byte)0;
outputData[++outIdx] = ds4.trigger_right_value;
outputData[++outIdx] = ds4.trigger_left_value;

outIdx++;

Expand Down

0 comments on commit 8d5fd67

Please sign in to comment.