Ejemplo n.º 1
0
        public ViGEmNavMergeX360Sink()
        {
            _deviceCount = 0;
            _Nav0Report  = null;
            _Nav1Report  = null;

            _btnMap0 = new Dictionary <DualShock3Buttons, Xbox360Button>
            {
                { DualShock3Buttons.LeftThumb, Xbox360Button.LeftThumb },
                { DualShock3Buttons.LeftShoulder, Xbox360Button.LeftShoulder },
                { DualShock3Buttons.Circle, Xbox360Button.Start },
                { DualShock3Buttons.Cross, Xbox360Button.Back },
                { DualShock3Buttons.DPadUp, Xbox360Button.Up },
                { DualShock3Buttons.DPadDown, Xbox360Button.Down },
                { DualShock3Buttons.DPadLeft, Xbox360Button.Left },
                { DualShock3Buttons.DPadRight, Xbox360Button.Right },
                { DualShock3Buttons.Ps, Xbox360Button.Guide }
            };

            _btnMap1 = new Dictionary <DualShock3Buttons, Xbox360Button>
            {
                { DualShock3Buttons.LeftThumb, Xbox360Button.RightThumb },
                { DualShock3Buttons.LeftShoulder, Xbox360Button.RightShoulder },
                { DualShock3Buttons.Circle, Xbox360Button.B },
                { DualShock3Buttons.Cross, Xbox360Button.A },
                { DualShock3Buttons.DPadUp, Xbox360Button.Y },
                { DualShock3Buttons.DPadDown, Xbox360Button.A },
                { DualShock3Buttons.DPadLeft, Xbox360Button.X },
                { DualShock3Buttons.DPadRight, Xbox360Button.B },
                { DualShock3Buttons.Ps, Xbox360Button.Guide }
            };

            _client = new ViGEmClient();
        }
Ejemplo n.º 2
0
            protected override void RequestInputReportWorker(object cancellationToken)
            {
                var token           = (CancellationToken)cancellationToken;
                var buffer          = new byte[0x32];
                var unmanagedBuffer = Marshal.AllocHGlobal(buffer.Length);

                try
                {
                    while (!token.IsCancellationRequested)
                    {
                        var ret = DeviceHandle.OverlappedDeviceIoControl(
                            IOCTL_BTHPS3_HID_INTERRUPT_READ,
                            IntPtr.Zero,
                            0,
                            unmanagedBuffer,
                            buffer.Length,
                            out _
                            );

                        if (!ret)
                        {
                            OnDisconnected();
                            return;
                        }

                        Marshal.Copy(unmanagedBuffer, buffer, 0, buffer.Length);

                        /*
                         * When connected via Bluetooth the Sixaxis occasionally sends
                         * a report with the second byte 0xff and the rest zeroed.
                         *
                         * This report does not reflect the actual state of the
                         * controller must be ignored to avoid generating false input
                         * events.
                         */
                        if (buffer[2] == 0xff)
                        {
                            continue;
                        }

                        try
                        {
                            OnInputReport(DualShock3InputReport.FromBuffer(buffer.Skip(1).ToArray()));
                        }
                        catch (InvalidDataException ide)
                        {
                            Log.Warning("Malformed input report received: {Exception}", ide);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error("{Exception}", ex);
                }
                finally
                {
                    Marshal.FreeHGlobal(unmanagedBuffer);
                }
            }
Ejemplo n.º 3
0
        protected override void RequestInputReportWorker(object cancellationToken)
        {
            var token         = (CancellationToken)cancellationToken;
            var requestSize   = Marshal.SizeOf <AirBenderHost.AirbenderGetDs3InputReport>();
            var requestBuffer = Marshal.AllocHGlobal(requestSize);

            Marshal.StructureToPtr(
                new AirBenderHost.AirbenderGetDs3InputReport
            {
                ClientAddress = ClientAddress.ToNativeBdAddr()
            },
                requestBuffer, false);

            try
            {
                while (!token.IsCancellationRequested)
                {
                    //
                    // This call blocks until the driver supplies new data.
                    //
                    var ret = HostDevice.DeviceHandle.OverlappedDeviceIoControl(
                        AirBenderHost.IoctlAirbenderGetDs3InputReport,
                        requestBuffer, requestSize, requestBuffer, requestSize,
                        out _);

                    if (!ret)
                    {
                        throw new AirBenderGetDs3InputReportFailedException("Input Report Request failed.",
                                                                            new Win32Exception(Marshal.GetLastWin32Error()));
                    }

                    var resp = Marshal.PtrToStructure <AirBenderHost.AirbenderGetDs3InputReport>(requestBuffer);

                    try
                    {
                        OnInputReport(DualShock3InputReport.FromBuffer(resp.ReportBuffer));
                    }
                    catch (InvalidDataException ide)
                    {
                        Log.Warning("Malformed input report received: {Exception}", ide);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error("{Exception}", ex);
            }
            finally
            {
                Marshal.FreeHGlobal(requestBuffer);
            }
        }
Ejemplo n.º 4
0
        protected override void RequestInputReportWorker(object cancellationToken)
        {
            var token           = (CancellationToken)cancellationToken;
            var buffer          = new byte[512];
            var unmanagedBuffer = Marshal.AllocHGlobal(buffer.Length);

            try
            {
                while (!token.IsCancellationRequested)
                {
                    var ret = DeviceHandle.OverlappedReadFile(
                        unmanagedBuffer,
                        buffer.Length,
                        out var bytesReturned);

                    if (!ret)
                    {
                        var nex = new Win32Exception(Marshal.GetLastWin32Error());

                        // Valid exception in case the device got surprise-removed, end worker
                        if (nex.NativeErrorCode == Win32ErrorCode.ERROR_OPERATION_ABORTED)
                        {
                            return;
                        }

                        throw new FireShockReadInputReportFailedException(
                                  "Failed to read input report.", nex);
                    }

                    Marshal.Copy(unmanagedBuffer, buffer, 0, bytesReturned);

                    try
                    {
                        OnInputReport(DualShock3InputReport.FromBuffer(buffer));
                    }
                    catch (InvalidDataException ide)
                    {
                        Log.Warning("Malformed input report received: {Exception}", ide);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error("{Exception}", ex);
            }
            finally
            {
                Marshal.FreeHGlobal(unmanagedBuffer);
            }
        }
Ejemplo n.º 5
0
        protected void OnInputReport(IInputReport report)
        {
            if (report == null)
            {
                return;
            }

            // Pull battery state from report
            DualShock3InputReport ds3_report = (DualShock3InputReport)report;

            BatteryState = ds3_report.BatteryState;

            InputReportReceived?.Invoke(this, new InputReportEventArgs(report));
        }
Ejemplo n.º 6
0
            protected override void RequestInputReportWorker(object cancellationToken)
            {
                var token           = (CancellationToken)cancellationToken;
                var buffer          = new byte[0x32];
                var unmanagedBuffer = Marshal.AllocHGlobal(buffer.Length);

                try
                {
                    while (!token.IsCancellationRequested)
                    {
                        var ret = DeviceHandle.OverlappedDeviceIoControl(
                            IOCTL_BTHPS3_HID_INTERRUPT_READ,
                            IntPtr.Zero,
                            0,
                            unmanagedBuffer,
                            buffer.Length,
                            out _
                            );

                        if (!ret)
                        {
                            OnDisconnected();
                            return;
                        }

                        Marshal.Copy(unmanagedBuffer, buffer, 0, buffer.Length);

                        try
                        {
                            OnInputReport(DualShock3InputReport.FromBuffer(buffer.Skip(1).ToArray()));
                        }
                        catch (InvalidDataException ide)
                        {
                            Log.Warning("Malformed input report received: {Exception}", ide);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Error("{Exception}", ex);
                }
                finally
                {
                    Marshal.FreeHGlobal(unmanagedBuffer);
                }
            }
Ejemplo n.º 7
0
        public void InputReportReceived(IDualShockDevice device, IInputReport report)
        {
            _target.ResetReport(); //This may be able to be optimized, look into later...

            // Convert report to DS3 format and store latest report for this device
            var ds3Report = (DualShock3InputReport)report;

            if (device.DeviceIndex == 0)
            {
                _Nav0Report = ds3Report;
            }
            if (device.DeviceIndex == 1)
            {
                _Nav1Report = ds3Report;
            }

            // Only combine reports and submit if we've seen input from each controller at least once
            if (_Nav0Report != null && _Nav1Report != null)
            {
                // Map buttons from Navigation #1 into input report
                _target.SetAxisValue(Xbox360Axis.LeftThumbX, Scale(_Nav0Report[DualShock3Axes.LeftThumbX], false));
                _target.SetAxisValue(Xbox360Axis.LeftThumbY, Scale(_Nav0Report[DualShock3Axes.LeftThumbY], true));
                _target.SetAxisValue(Xbox360Axis.RightThumbX, Scale(_Nav1Report[DualShock3Axes.LeftThumbX], false));
                _target.SetAxisValue(Xbox360Axis.RightThumbY, Scale(_Nav1Report[DualShock3Axes.LeftThumbY], true));

                _target.SetSliderValue(Xbox360Slider.LeftTrigger, _Nav0Report[DualShock3Axes.LeftTrigger]);
                _target.SetSliderValue(Xbox360Slider.RightTrigger, _Nav1Report[DualShock3Axes.LeftTrigger]);

                foreach (var button in _btnMap0.Where(m => _Nav0Report.EngagedButtons.Contains(m.Key))
                         .Select(m => m.Value))
                {
                    _target.SetButtonState(button, true);
                }

                foreach (var button in _btnMap1.Where(m => _Nav1Report.EngagedButtons.Contains(m.Key))
                         .Select(m => m.Value))
                {
                    _target.SetButtonState(button, true);
                }

                _target.SubmitReport();
            }
        }
Ejemplo n.º 8
0
        public void DeviceRemoved(IDualShockDevice device)
        {
            Log.Information("ViGEmNavMergeX360: Device with index {Index} detached", device.DeviceIndex);
            // Only remove the virtual 360 controller if we only had one controller left connected
            if (_deviceCount == 1)
            {
                _target.Disconnect();
                _target = null;
            }

            _deviceCount--;

            if (device.DeviceIndex == 0)
            {
                _Nav0Report = null;
            }
            if (device.DeviceIndex == 1)
            {
                _Nav1Report = null;
            }
        }