Example #1
0
        /// <summary>
        ///     Translates an <see cref="ScpHidReport"/> to an Xbox 360 compatible byte array.
        /// </summary>
        /// <param name="inputReport">The <see cref="ScpHidReport"/> to translate.</param>
        /// <returns>The translated data as <see cref="XINPUT_GAMEPAD"/> structure.</returns>
        public XINPUT_GAMEPAD Parse(ScpHidReport inputReport)
        {
            var xButton = X360Button.None;
            var output  = new XINPUT_GAMEPAD();

            switch (inputReport.Model)
            {
            case DsModel.DS3:
            {
                // select & start
                if (inputReport[Ds3Button.Select].IsPressed)
                {
                    xButton |= X360Button.Back;
                }
                if (inputReport[Ds3Button.Start].IsPressed)
                {
                    xButton |= X360Button.Start;
                }

                // d-pad
                if (inputReport[Ds3Button.Up].IsPressed)
                {
                    xButton |= X360Button.Up;
                }
                if (inputReport[Ds3Button.Right].IsPressed)
                {
                    xButton |= X360Button.Right;
                }
                if (inputReport[Ds3Button.Down].IsPressed)
                {
                    xButton |= X360Button.Down;
                }
                if (inputReport[Ds3Button.Left].IsPressed)
                {
                    xButton |= X360Button.Left;
                }

                // shoulders
                if (inputReport[Ds3Button.L1].IsPressed)
                {
                    xButton |= X360Button.LB;
                }
                if (inputReport[Ds3Button.R1].IsPressed)
                {
                    xButton |= X360Button.RB;
                }

                // face buttons
                if (inputReport[Ds3Button.Triangle].IsPressed)
                {
                    xButton |= X360Button.Y;
                }
                if (inputReport[Ds3Button.Circle].IsPressed)
                {
                    xButton |= X360Button.B;
                }
                if (inputReport[Ds3Button.Cross].IsPressed)
                {
                    xButton |= X360Button.A;
                }
                if (inputReport[Ds3Button.Square].IsPressed)
                {
                    xButton |= X360Button.X;
                }

                // PS/Guide
                if (inputReport[Ds3Button.Ps].IsPressed)
                {
                    xButton |= X360Button.Guide;
                }

                // thumbs
                if (inputReport[Ds3Button.L3].IsPressed)
                {
                    xButton |= X360Button.LS;
                }
                if (inputReport[Ds3Button.R3].IsPressed)
                {
                    xButton |= X360Button.RS;
                }

                // face buttons
                output.wButtons = (ushort)xButton;

                // trigger
                output.bLeftTrigger  = inputReport[Ds3Axis.L2].Value;
                output.bRightTrigger = inputReport[Ds3Axis.R2].Value;

                if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL,
                                     inputReport[Ds3Axis.Lx].Value,
                                     inputReport[Ds3Axis.Ly].Value))
                // Left Stick DeadZone
                {
                    output.sThumbLX =
                        (short)
                        +DsMath.Scale(inputReport[Ds3Axis.Lx].Value, GlobalConfiguration.Instance.FlipLX);
                    output.sThumbLY =
                        (short)
                        -DsMath.Scale(inputReport[Ds3Axis.Ly].Value, GlobalConfiguration.Instance.FlipLY);
                }

                if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR,
                                     inputReport[Ds3Axis.Rx].Value,
                                     inputReport[Ds3Axis.Ry].Value))
                // Right Stick DeadZone
                {
                    output.sThumbRX =
                        (short)
                        +DsMath.Scale(inputReport[Ds3Axis.Rx].Value, GlobalConfiguration.Instance.FlipRX);
                    output.sThumbRY =
                        (short)
                        -DsMath.Scale(inputReport[Ds3Axis.Ry].Value, GlobalConfiguration.Instance.FlipRY);
                }
            }
            break;

            case DsModel.DS4:
            {
                if (inputReport[Ds4Button.Share].IsPressed)
                {
                    xButton |= X360Button.Back;
                }
                if (inputReport[Ds4Button.Options].IsPressed)
                {
                    xButton |= X360Button.Start;
                }

                if (inputReport[Ds4Button.Up].IsPressed)
                {
                    xButton |= X360Button.Up;
                }
                if (inputReport[Ds4Button.Right].IsPressed)
                {
                    xButton |= X360Button.Right;
                }
                if (inputReport[Ds4Button.Down].IsPressed)
                {
                    xButton |= X360Button.Down;
                }
                if (inputReport[Ds4Button.Left].IsPressed)
                {
                    xButton |= X360Button.Left;
                }

                if (inputReport[Ds4Button.L1].IsPressed)
                {
                    xButton |= X360Button.LB;
                }
                if (inputReport[Ds4Button.R1].IsPressed)
                {
                    xButton |= X360Button.RB;
                }

                if (inputReport[Ds4Button.Triangle].IsPressed)
                {
                    xButton |= X360Button.Y;
                }
                if (inputReport[Ds4Button.Circle].IsPressed)
                {
                    xButton |= X360Button.B;
                }
                if (inputReport[Ds4Button.Cross].IsPressed)
                {
                    xButton |= X360Button.A;
                }
                if (inputReport[Ds4Button.Square].IsPressed)
                {
                    xButton |= X360Button.X;
                }

                if (inputReport[Ds4Button.Ps].IsPressed)
                {
                    xButton |= X360Button.Guide;
                }

                if (inputReport[Ds4Button.L3].IsPressed)
                {
                    xButton |= X360Button.LS;
                }
                if (inputReport[Ds4Button.R3].IsPressed)
                {
                    xButton |= X360Button.RS;
                }

                // face buttons
                output.wButtons = (ushort)xButton;

                // trigger
                output.bLeftTrigger  = inputReport[Ds4Axis.L2].Value;
                output.bRightTrigger = inputReport[Ds4Axis.R2].Value;

                if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL,
                                     inputReport[Ds4Axis.Lx].Value,
                                     inputReport[Ds4Axis.Ly].Value))
                // Left Stick DeadZone
                {
                    output.sThumbLX =
                        (short)
                        +DsMath.Scale(inputReport[Ds4Axis.Lx].Value, GlobalConfiguration.Instance.FlipLX);
                    output.sThumbLY =
                        (short)
                        -DsMath.Scale(inputReport[Ds4Axis.Ly].Value, GlobalConfiguration.Instance.FlipLY);
                }

                if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR,
                                     inputReport[Ds4Axis.Rx].Value,
                                     inputReport[Ds4Axis.Ry].Value))
                // Right Stick DeadZone
                {
                    output.sThumbRX =
                        (short)
                        +DsMath.Scale(inputReport[Ds4Axis.Rx].Value, GlobalConfiguration.Instance.FlipRX);
                    output.sThumbRY =
                        (short)
                        -DsMath.Scale(inputReport[Ds4Axis.Ry].Value, GlobalConfiguration.Instance.FlipRY);
                }
            }
            break;
            }

            return(output);
        }
Example #2
0
        /// <summary>
        ///     Translates an <see cref="ScpHidReport"/> to an Xbox 360 compatible byte array.
        /// </summary>
        /// <param name="inputReport">The <see cref="ScpHidReport"/> to translate.</param>
        /// <param name="output">The target Xbox data array.</param>
        public void Parse(ScpHidReport inputReport, byte[] output)
        {
            var input = inputReport.RawBytes;

            var serial = IndexToSerial(input[0]);

            for (var index = 0; index < ReportSize; index++)
            {
                output[index] = 0x00;
            }

            output[0] = 0x1C;
            output[4] = (byte)((serial >> 0) & 0xFF);
            output[5] = (byte)((serial >> 8) & 0xFF);
            output[6] = (byte)((serial >> 16) & 0xFF);
            output[7] = (byte)((serial >> 24) & 0xFF);
            output[9] = 0x14;

            var xButton = X360Button.None;

            if (inputReport.PadState == DsState.Connected) // Pad is active
            {
                switch (inputReport.Model)
                {
                case DsModel.DS3:
                {
                    // select & start
                    if (inputReport[Ds3Button.Select].IsPressed)
                    {
                        xButton |= X360Button.Back;
                    }
                    if (inputReport[Ds3Button.Start].IsPressed)
                    {
                        xButton |= X360Button.Start;
                    }

                    // d-pad
                    if (inputReport[Ds3Button.Up].IsPressed)
                    {
                        xButton |= X360Button.Up;
                    }
                    if (inputReport[Ds3Button.Right].IsPressed)
                    {
                        xButton |= X360Button.Right;
                    }
                    if (inputReport[Ds3Button.Down].IsPressed)
                    {
                        xButton |= X360Button.Down;
                    }
                    if (inputReport[Ds3Button.Left].IsPressed)
                    {
                        xButton |= X360Button.Left;
                    }

                    // shoulders
                    if (inputReport[Ds3Button.L1].IsPressed)
                    {
                        xButton |= X360Button.LB;
                    }
                    if (inputReport[Ds3Button.R1].IsPressed)
                    {
                        xButton |= X360Button.RB;
                    }

                    // face buttons
                    if (inputReport[Ds3Button.Triangle].IsPressed)
                    {
                        xButton |= X360Button.Y;
                    }
                    if (inputReport[Ds3Button.Circle].IsPressed)
                    {
                        xButton |= X360Button.B;
                    }
                    if (inputReport[Ds3Button.Cross].IsPressed)
                    {
                        xButton |= X360Button.A;
                    }
                    if (inputReport[Ds3Button.Square].IsPressed)
                    {
                        xButton |= X360Button.X;
                    }

                    // PS/Guide
                    if (inputReport[Ds3Button.Ps].IsPressed)
                    {
                        xButton |= X360Button.Guide;
                    }

                    // thumbs
                    if (inputReport[Ds3Button.L3].IsPressed)
                    {
                        xButton |= X360Button.LS;
                    }
                    if (inputReport[Ds3Button.R3].IsPressed)
                    {
                        xButton |= X360Button.RS;
                    }

                    output[(uint)X360Axis.BT_Lo] = (byte)((uint)xButton >> 0 & 0xFF);
                    output[(uint)X360Axis.BT_Hi] = (byte)((uint)xButton >> 8 & 0xFF);

                    // trigger
                    output[(uint)X360Axis.LT] = inputReport[Ds3Axis.L2].Value;
                    output[(uint)X360Axis.RT] = inputReport[Ds3Axis.R2].Value;

                    if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL,
                                         inputReport[Ds3Axis.Lx].Value,
                                         inputReport[Ds3Axis.Ly].Value))
                    // Left Stick DeadZone
                    {
                        var thumbLx = +DsMath.Scale(inputReport[Ds3Axis.Lx].Value, GlobalConfiguration.Instance.FlipLX);
                        var thumbLy = -DsMath.Scale(inputReport[Ds3Axis.Ly].Value, GlobalConfiguration.Instance.FlipLY);

                        output[(uint)X360Axis.LX_Lo] = (byte)((thumbLx >> 0) & 0xFF);       // LX
                        output[(uint)X360Axis.LX_Hi] = (byte)((thumbLx >> 8) & 0xFF);

                        output[(uint)X360Axis.LY_Lo] = (byte)((thumbLy >> 0) & 0xFF);       // LY
                        output[(uint)X360Axis.LY_Hi] = (byte)((thumbLy >> 8) & 0xFF);
                    }

                    if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR,
                                         inputReport[Ds3Axis.Rx].Value,
                                         inputReport[Ds3Axis.Ry].Value))
                    // Right Stick DeadZone
                    {
                        var thumbRx = +DsMath.Scale(inputReport[Ds3Axis.Rx].Value, GlobalConfiguration.Instance.FlipRX);
                        var thumbRy = -DsMath.Scale(inputReport[Ds3Axis.Ry].Value, GlobalConfiguration.Instance.FlipRY);

                        output[(uint)X360Axis.RX_Lo] = (byte)((thumbRx >> 0) & 0xFF);       // RX
                        output[(uint)X360Axis.RX_Hi] = (byte)((thumbRx >> 8) & 0xFF);

                        output[(uint)X360Axis.RY_Lo] = (byte)((thumbRy >> 0) & 0xFF);       // RY
                        output[(uint)X360Axis.RY_Hi] = (byte)((thumbRy >> 8) & 0xFF);
                    }
                }
                break;

                case DsModel.DS4:
                {
                    if (inputReport[Ds4Button.Share].IsPressed)
                    {
                        xButton |= X360Button.Back;
                    }
                    if (inputReport[Ds4Button.Options].IsPressed)
                    {
                        xButton |= X360Button.Start;
                    }

                    if (inputReport[Ds4Button.Up].IsPressed)
                    {
                        xButton |= X360Button.Up;
                    }
                    if (inputReport[Ds4Button.Right].IsPressed)
                    {
                        xButton |= X360Button.Right;
                    }
                    if (inputReport[Ds4Button.Down].IsPressed)
                    {
                        xButton |= X360Button.Down;
                    }
                    if (inputReport[Ds4Button.Left].IsPressed)
                    {
                        xButton |= X360Button.Left;
                    }

                    if (inputReport[Ds4Button.L1].IsPressed)
                    {
                        xButton |= X360Button.LB;
                    }
                    if (inputReport[Ds4Button.R1].IsPressed)
                    {
                        xButton |= X360Button.RB;
                    }

                    if (inputReport[Ds4Button.Triangle].IsPressed)
                    {
                        xButton |= X360Button.Y;
                    }
                    if (inputReport[Ds4Button.Circle].IsPressed)
                    {
                        xButton |= X360Button.B;
                    }
                    if (inputReport[Ds4Button.Cross].IsPressed)
                    {
                        xButton |= X360Button.A;
                    }
                    if (inputReport[Ds4Button.Square].IsPressed)
                    {
                        xButton |= X360Button.X;
                    }

                    if (inputReport[Ds4Button.Ps].IsPressed)
                    {
                        xButton |= X360Button.Guide;
                    }

                    if (inputReport[Ds4Button.L3].IsPressed)
                    {
                        xButton |= X360Button.LS;
                    }
                    if (inputReport[Ds4Button.R3].IsPressed)
                    {
                        xButton |= X360Button.RS;
                    }

                    output[(uint)X360Axis.BT_Lo] = (byte)((uint)xButton >> 0 & 0xFF);
                    output[(uint)X360Axis.BT_Hi] = (byte)((uint)xButton >> 8 & 0xFF);

                    output[(uint)X360Axis.LT] = inputReport[Ds4Axis.L2].Value;
                    output[(uint)X360Axis.RT] = inputReport[Ds4Axis.R2].Value;

                    if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL,
                                         inputReport[Ds4Axis.Lx].Value,
                                         inputReport[Ds4Axis.Ly].Value))
                    // Left Stick DeadZone
                    {
                        var thumbLx = +DsMath.Scale(inputReport[Ds4Axis.Lx].Value, GlobalConfiguration.Instance.FlipLX);
                        var thumbLy = -DsMath.Scale(inputReport[Ds4Axis.Ly].Value, GlobalConfiguration.Instance.FlipLY);

                        output[(uint)X360Axis.LX_Lo] = (byte)((thumbLx >> 0) & 0xFF);       // LX
                        output[(uint)X360Axis.LX_Hi] = (byte)((thumbLx >> 8) & 0xFF);

                        output[(uint)X360Axis.LY_Lo] = (byte)((thumbLy >> 0) & 0xFF);       // LY
                        output[(uint)X360Axis.LY_Hi] = (byte)((thumbLy >> 8) & 0xFF);
                    }

                    if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR,
                                         inputReport[Ds4Axis.Rx].Value,
                                         inputReport[Ds4Axis.Ry].Value))
                    // Right Stick DeadZone
                    {
                        var thumbRx = +DsMath.Scale(inputReport[Ds4Axis.Rx].Value, GlobalConfiguration.Instance.FlipRX);
                        var thumbRy = -DsMath.Scale(inputReport[Ds4Axis.Ry].Value, GlobalConfiguration.Instance.FlipRY);

                        output[(uint)X360Axis.RX_Lo] = (byte)((thumbRx >> 0) & 0xFF);       // RX
                        output[(uint)X360Axis.RX_Hi] = (byte)((thumbRx >> 8) & 0xFF);

                        output[(uint)X360Axis.RY_Lo] = (byte)((thumbRy >> 0) & 0xFF);       // RY
                        output[(uint)X360Axis.RY_Hi] = (byte)((thumbRy >> 8) & 0xFF);
                    }
                }
                break;
                }
            }
        }
        public static uint XInputGetState(uint dwUserIndex, ref XINPUT_STATE pState)
        {
#if !EXPERIMENTAL
            return(OriginalXInputGetStateFunction.Value(dwUserIndex, ref pState));
#else
            if (OriginalXInputGetStateFunction.Value(dwUserIndex, ref pState) == ResultWin32.ERROR_SUCCESS)
            {
                return(ResultWin32.ERROR_SUCCESS);
            }

            try
            {
                ScpHidReport report = null;

                while (dwUserIndex == 0 && (report = Proxy.GetReport(dwUserIndex)) == null)
                {
                    Thread.Sleep(100);
                }

                if (report == null || report.PadState != DsState.Connected)
                {
                    return(ResultWin32.ERROR_DEVICE_NOT_CONNECTED);
                }

                var xPad = new XINPUT_GAMEPAD();

                pState.dwPacketNumber = report.PacketCounter;

                switch (report.Model)
                {
                case DsModel.DS3:
                {
                    // select & start
                    xPad.wButtons |= (ushort)report[Ds3Button.Select].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds3Button.Start].Xbox360Button;

                    // d-pad
                    xPad.wButtons |= (ushort)report[Ds3Button.Up].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds3Button.Right].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds3Button.Down].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds3Button.Left].Xbox360Button;

                    // shoulders
                    xPad.wButtons |= (ushort)report[Ds3Button.L1].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds3Button.R1].Xbox360Button;

                    // face buttons
                    xPad.wButtons |= (ushort)report[Ds3Button.Triangle].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds3Button.Circle].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds3Button.Cross].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds3Button.Square].Xbox360Button;

                    // PS/Guide
                    xPad.wButtons |= (ushort)report[Ds3Button.Ps].Xbox360Button;

                    // thumbs
                    xPad.wButtons |= (ushort)report[Ds3Button.L3].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds3Button.R3].Xbox360Button;

                    // triggers
                    xPad.bLeftTrigger  = report[Ds3Axis.L2].Value;
                    xPad.bRightTrigger = report[Ds3Axis.R2].Value;

                    // thumb axes
                    xPad.sThumbLX = (short)+DsMath.Scale(report[Ds3Axis.Lx].Value, false);
                    xPad.sThumbLY = (short)-DsMath.Scale(report[Ds3Axis.Ly].Value, false);
                    xPad.sThumbRX = (short)+DsMath.Scale(report[Ds3Axis.Rx].Value, false);
                    xPad.sThumbRY = (short)-DsMath.Scale(report[Ds3Axis.Ry].Value, false);
                }
                break;

                case DsModel.DS4:
                {
                    // select & start
                    xPad.wButtons |= (ushort)report[Ds4Button.Share].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds4Button.Options].Xbox360Button;

                    // d-pad
                    xPad.wButtons |= (ushort)report[Ds4Button.Up].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds4Button.Right].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds4Button.Down].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds4Button.Left].Xbox360Button;

                    // shoulders
                    xPad.wButtons |= (ushort)report[Ds4Button.L1].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds4Button.R1].Xbox360Button;

                    // face buttons
                    xPad.wButtons |= (ushort)report[Ds4Button.Triangle].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds4Button.Circle].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds4Button.Cross].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds4Button.Square].Xbox360Button;

                    // PS/Guide
                    xPad.wButtons |= (ushort)report[Ds4Button.Ps].Xbox360Button;

                    // thumbs
                    xPad.wButtons |= (ushort)report[Ds4Button.L3].Xbox360Button;
                    xPad.wButtons |= (ushort)report[Ds4Button.R3].Xbox360Button;

                    // triggers
                    xPad.bLeftTrigger  = report[Ds4Axis.L2].Value;
                    xPad.bRightTrigger = report[Ds4Axis.R2].Value;

                    // thumb axes
                    xPad.sThumbLX = (short)+DsMath.Scale(report[Ds4Axis.Lx].Value, false);
                    xPad.sThumbLY = (short)-DsMath.Scale(report[Ds4Axis.Ly].Value, false);
                    xPad.sThumbRX = (short)+DsMath.Scale(report[Ds4Axis.Rx].Value, false);
                    xPad.sThumbRY = (short)-DsMath.Scale(report[Ds4Axis.Ry].Value, false);
                }
                break;
                }

                pState.Gamepad = xPad;
            }
            catch (Exception ex)
            {
                Log.ErrorFormat("Unexpected error: {0}", ex);
                return(ResultWin32.ERROR_DEVICE_NOT_CONNECTED);
            }

            return(ResultWin32.ERROR_SUCCESS);
#endif
        }
Example #4
0
        private bool ReportToBuffer(ScpHidReport hidReport, byte[] outputData, ref int outIdx)
        {
            switch (hidReport.Model)
            {
            case DsModel.DS3:
            {
                outputData[outIdx] = 0;

                if (hidReport[Ds3Button.Left].IsPressed)
                {
                    outputData[outIdx] |= 0x80;
                }
                if (hidReport[Ds3Button.Down].IsPressed)
                {
                    outputData[outIdx] |= 0x40;
                }
                if (hidReport[Ds3Button.Right].IsPressed)
                {
                    outputData[outIdx] |= 0x20;
                }
                if (hidReport[Ds3Button.Up].IsPressed)
                {
                    outputData[outIdx] |= 0x10;
                }

                if (hidReport[Ds3Button.Start].IsPressed)
                {
                    outputData[outIdx] |= 0x08;
                }
                if (hidReport[Ds3Button.R3].IsPressed)
                {
                    outputData[outIdx] |= 0x04;
                }
                if (hidReport[Ds3Button.L3].IsPressed)
                {
                    outputData[outIdx] |= 0x02;
                }
                if (hidReport[Ds3Button.Select].IsPressed)
                {
                    outputData[outIdx] |= 0x01;
                }

                outputData[++outIdx] = 0;

                if (hidReport[Ds3Button.Square].IsPressed)
                {
                    outputData[outIdx] |= 0x80;
                }
                if (hidReport[Ds3Button.Cross].IsPressed)
                {
                    outputData[outIdx] |= 0x40;
                }
                if (hidReport[Ds3Button.Circle].IsPressed)
                {
                    outputData[outIdx] |= 0x20;
                }
                if (hidReport[Ds3Button.Triangle].IsPressed)
                {
                    outputData[outIdx] |= 0x10;
                }

                if (hidReport[Ds3Button.R1].IsPressed)
                {
                    outputData[outIdx] |= 0x08;
                }
                if (hidReport[Ds3Button.L1].IsPressed)
                {
                    outputData[outIdx] |= 0x04;
                }
                if (!GlobalConfiguration.Instance.SwapTriggers)
                {
                    if (hidReport[Ds3Button.R2].IsPressed)
                    {
                        outputData[outIdx] |= 0x02;
                    }
                    if (hidReport[Ds3Button.L2].IsPressed)
                    {
                        outputData[outIdx] |= 0x01;
                    }
                }
                else
                {
                    if (hidReport[Ds3Button.L2].IsPressed)
                    {
                        outputData[outIdx] |= 0x01;
                    }
                    if (hidReport[Ds3Button.R2].IsPressed)
                    {
                        outputData[outIdx] |= 0x02;
                    }
                }

                outputData[++outIdx] = (hidReport[Ds3Button.Ps].IsPressed) ? (byte)1 : (byte)0;
                outputData[++outIdx] = 0;                                 //no Touchpad click on ds3

                if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL, hidReport[Ds3Axis.Lx].Value, hidReport[Ds3Axis.Ly].Value))
                {
                    outputData[++outIdx] = hidReport[Ds3Axis.Lx].Value;
                    if (GlobalConfiguration.Instance.FlipLX)
                    {
                        outputData[outIdx] = (byte)(255 - outputData[outIdx]);
                    }

                    outputData[++outIdx] = hidReport[Ds3Axis.Ly].Value;
                    if (!GlobalConfiguration.Instance.FlipLY)
                    {
                        outputData[outIdx] = (byte)(255 - outputData[outIdx]);
                    }
                }
                else
                {
                    outputData[++outIdx] = 0x7F;
                    outputData[++outIdx] = 0x7F;
                }

                if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR, hidReport[Ds3Axis.Rx].Value, hidReport[Ds3Axis.Ry].Value))
                {
                    outputData[++outIdx] = hidReport[Ds3Axis.Rx].Value;
                    if (GlobalConfiguration.Instance.FlipRX)
                    {
                        outputData[outIdx] = (byte)(255 - outputData[outIdx]);
                    }

                    outputData[++outIdx] = hidReport[Ds3Axis.Ry].Value;
                    if (!GlobalConfiguration.Instance.FlipRY)
                    {
                        outputData[outIdx] = (byte)(255 - outputData[outIdx]);
                    }
                }
                else
                {
                    outputData[++outIdx] = 0x7F;
                    outputData[++outIdx] = 0x7F;
                }

                //Analog buttons
                outputData[++outIdx] = hidReport[Ds3Axis.Left].Value;
                outputData[++outIdx] = hidReport[Ds3Axis.Down].Value;
                outputData[++outIdx] = hidReport[Ds3Axis.Right].Value;
                outputData[++outIdx] = hidReport[Ds3Axis.Up].Value;

                outputData[++outIdx] = hidReport[Ds3Axis.Square].Value;
                outputData[++outIdx] = hidReport[Ds3Axis.Cross].Value;
                outputData[++outIdx] = hidReport[Ds3Axis.Circle].Value;
                outputData[++outIdx] = hidReport[Ds3Axis.Triangle].Value;

                outputData[++outIdx] = hidReport[Ds3Axis.R1].Value;
                outputData[++outIdx] = hidReport[Ds3Axis.L1].Value;

                if (!GlobalConfiguration.Instance.SwapTriggers)
                {
                    outputData[++outIdx] = hidReport[Ds3Axis.R2].Value;
                    outputData[++outIdx] = hidReport[Ds3Axis.L2].Value;
                }
                else
                {
                    outputData[++outIdx] = hidReport[Ds3Axis.L2].Value;
                    outputData[++outIdx] = hidReport[Ds3Axis.R2].Value;
                }

                outIdx++;
            }
            break;

            case DsModel.DS4:
            {
                outputData[outIdx] = 0;

                if (hidReport[Ds4Button.Left].IsPressed)
                {
                    outputData[outIdx] |= 0x80;
                }
                if (hidReport[Ds4Button.Down].IsPressed)
                {
                    outputData[outIdx] |= 0x40;
                }
                if (hidReport[Ds4Button.Right].IsPressed)
                {
                    outputData[outIdx] |= 0x20;
                }
                if (hidReport[Ds4Button.Up].IsPressed)
                {
                    outputData[outIdx] |= 0x10;
                }

                if (hidReport[Ds4Button.Options].IsPressed)
                {
                    outputData[outIdx] |= 0x08;
                }
                if (hidReport[Ds4Button.R3].IsPressed)
                {
                    outputData[outIdx] |= 0x04;
                }
                if (hidReport[Ds4Button.L3].IsPressed)
                {
                    outputData[outIdx] |= 0x02;
                }
                if (hidReport[Ds4Button.Share].IsPressed)
                {
                    outputData[outIdx] |= 0x01;
                }

                outputData[++outIdx] = 0;

                if (hidReport[Ds4Button.Square].IsPressed)
                {
                    outputData[outIdx] |= 0x80;
                }
                if (hidReport[Ds4Button.Cross].IsPressed)
                {
                    outputData[outIdx] |= 0x40;
                }
                if (hidReport[Ds4Button.Circle].IsPressed)
                {
                    outputData[outIdx] |= 0x20;
                }
                if (hidReport[Ds4Button.Triangle].IsPressed)
                {
                    outputData[outIdx] |= 0x10;
                }

                if (hidReport[Ds4Button.R1].IsPressed)
                {
                    outputData[outIdx] |= 0x08;
                }
                if (hidReport[Ds4Button.L1].IsPressed)
                {
                    outputData[outIdx] |= 0x04;
                }
                if (!GlobalConfiguration.Instance.SwapTriggers)
                {
                    if (hidReport[Ds4Button.R2].IsPressed)
                    {
                        outputData[outIdx] |= 0x02;
                    }
                    if (hidReport[Ds4Button.L2].IsPressed)
                    {
                        outputData[outIdx] |= 0x01;
                    }
                }
                else
                {
                    if (hidReport[Ds4Button.L2].IsPressed)
                    {
                        outputData[outIdx] |= 0x01;
                    }
                    if (hidReport[Ds4Button.R2].IsPressed)
                    {
                        outputData[outIdx] |= 0x02;
                    }
                }

                outputData[++outIdx] = (hidReport[Ds4Button.Ps].IsPressed) ? (byte)1 : (byte)0;
                outputData[++outIdx] = (hidReport[Ds4Button.TouchPad].IsPressed) ? (byte)1 : (byte)0;

                if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneL, hidReport[Ds4Axis.Lx].Value, hidReport[Ds4Axis.Ly].Value))
                {
                    outputData[++outIdx] = hidReport[Ds4Axis.Lx].Value;
                    if (GlobalConfiguration.Instance.FlipLX)
                    {
                        outputData[outIdx] = (byte)(255 - outputData[outIdx]);
                    }

                    outputData[++outIdx] = hidReport[Ds4Axis.Ly].Value;
                    if (!GlobalConfiguration.Instance.FlipLY)
                    {
                        outputData[outIdx] = (byte)(255 - outputData[outIdx]);
                    }
                }
                else
                {
                    outputData[++outIdx] = 0x7F;
                    outputData[++outIdx] = 0x7F;
                }

                if (!DsMath.DeadZone(GlobalConfiguration.Instance.DeadZoneR, hidReport[Ds4Axis.Rx].Value, hidReport[Ds4Axis.Ry].Value))
                {
                    outputData[++outIdx] = hidReport[Ds4Axis.Rx].Value;
                    if (GlobalConfiguration.Instance.FlipRX)
                    {
                        outputData[outIdx] = (byte)(255 - outputData[outIdx]);
                    }

                    outputData[++outIdx] = hidReport[Ds4Axis.Ry].Value;
                    if (!GlobalConfiguration.Instance.FlipRY)
                    {
                        outputData[outIdx] = (byte)(255 - outputData[outIdx]);
                    }
                }
                else
                {
                    outputData[++outIdx] = 0x7F;
                    outputData[++outIdx] = 0x7F;
                }

                //we don't have analog buttons so just use the Button enums (which give either 0 or 0xFF)
                outputData[++outIdx] = hidReport[Ds4Button.Left].Value;
                outputData[++outIdx] = hidReport[Ds4Button.Down].Value;
                outputData[++outIdx] = hidReport[Ds4Button.Right].Value;
                outputData[++outIdx] = hidReport[Ds4Button.Up].Value;

                outputData[++outIdx] = hidReport[Ds4Button.Square].Value;
                outputData[++outIdx] = hidReport[Ds4Button.Cross].Value;
                outputData[++outIdx] = hidReport[Ds4Button.Circle].Value;
                outputData[++outIdx] = hidReport[Ds4Button.Triangle].Value;

                outputData[++outIdx] = hidReport[Ds4Button.R1].Value;
                outputData[++outIdx] = hidReport[Ds4Button.L1].Value;

                if (!GlobalConfiguration.Instance.SwapTriggers)
                {
                    outputData[++outIdx] = hidReport[Ds4Axis.R2].Value;
                    outputData[++outIdx] = hidReport[Ds4Axis.L2].Value;
                }
                else
                {
                    outputData[++outIdx] = hidReport[Ds4Axis.L2].Value;
                    outputData[++outIdx] = hidReport[Ds4Axis.R2].Value;
                }

                outIdx++;
            }
            break;

            default:
                return(false);                        //we only support DS3 and DS4
            }

            //DS4 only: touchpad points
            for (int i = 0; i < 2; i++)
            {
                var tpad = hidReport.TrackPadTouch0;
                if (tpad != null && i > 0)
                {
                    tpad = hidReport.TrackPadTouch1;
                }

                if (tpad != null)
                {
                    outputData[outIdx++] = tpad.IsActive ? (byte)1 : (byte)0;
                    outputData[outIdx++] = (byte)tpad.Id;
                    Array.Copy(BitConverter.GetBytes((ushort)tpad.X), 0, outputData, outIdx, 2);
                    outIdx += 2;
                    Array.Copy(BitConverter.GetBytes((ushort)tpad.Y), 0, outputData, outIdx, 2);
                    outIdx += 2;
                }
                else
                {
                    outIdx += 6;
                }
            }

            //motion timestamp
            Array.Copy(BitConverter.GetBytes((ulong)hidReport.Timestamp), 0, outputData, outIdx, 8);
            outIdx += 8;

            //accelerometer
            {
                var accel = hidReport.Accelerometer;
                if (accel != null)
                {
                    Array.Copy(BitConverter.GetBytes((float)accel.X), 0, outputData, outIdx, 4);
                    outIdx += 4;
                    Array.Copy(BitConverter.GetBytes((float)accel.Y), 0, outputData, outIdx, 4);
                    outIdx += 4;
                    Array.Copy(BitConverter.GetBytes((float)accel.Z), 0, outputData, outIdx, 4);
                    outIdx += 4;
                }
                else
                {
                    outIdx += 12;
                }
            }

            //gyroscope
            {
                var gyro = hidReport.Gyroscope;
                if (gyro != null)
                {
                    Array.Copy(BitConverter.GetBytes((float)gyro.Pitch), 0, outputData, outIdx, 4);
                    outIdx += 4;
                    Array.Copy(BitConverter.GetBytes((float)gyro.Yaw), 0, outputData, outIdx, 4);
                    outIdx += 4;
                    Array.Copy(BitConverter.GetBytes((float)gyro.Roll), 0, outputData, outIdx, 4);
                    outIdx += 4;
                }
                else
                {
                    outIdx += 12;
                }
            }

            return(true);
        }