Пример #1
0
        private unsafe void UpdateButtons(RawInput *rin, Device stick)
        {
            stick.ClearButtons();

            for (int i = 0; i < stick.ButtonCaps.Count; i++)
            {
                short * usage_list   = stackalloc short[64];
                int     usage_length = 64;
                HIDPage page         = stick.ButtonCaps[i].UsagePage;
                short   collection   = stick.ButtonCaps[i].LinkCollection;

                HidProtocolStatus status = HidProtocol.GetUsages(
                    HidProtocolReportType.Input,
                    page, 0, usage_list, ref usage_length,
                    PreparsedData,
                    new IntPtr((void *)&rin->Data.HID.RawData),
                    rin->Data.HID.Size);

                if (status != HidProtocolStatus.Success)
                {
                    Debug.Print("[WinRawJoystick] HidProtocol.GetUsages() failed with {0}",
                                Marshal.GetLastWin32Error());
                    continue;
                }

                for (int j = 0; j < usage_length; j++)
                {
                    short usage = *(usage_list + j);
                    stick.SetButton(collection, page, usage, true);
                }
            }
        }
Пример #2
0
        private unsafe void UpdateAxes(RawInput *rin, Device stick)
        {
            for (int i = 0; i < stick.AxisCaps.Count; i++)
            {
                if (stick.AxisCaps[i].IsRange)
                {
                    Debug.Print("[{0}] Axis range collections not implemented. Please report your controller type at https://github.com/opentk/opentk/issues",
                                GetType().Name);
                    continue;
                }

                HIDPage page       = stick.AxisCaps[i].UsagePage;
                short   usage      = stick.AxisCaps[i].NotRange.Usage;
                uint    value      = 0;
                short   collection = stick.AxisCaps[i].LinkCollection;

                HidProtocolStatus status = HidProtocol.GetUsageValue(
                    HidProtocolReportType.Input,
                    page, 0, usage, ref value,
                    PreparsedData,
                    new IntPtr((void *)&rin->Data.HID.RawData),
                    rin->Data.HID.Size);

                if (status != HidProtocolStatus.Success)
                {
                    Debug.Print("[{0}] HidProtocol.GetScaledUsageValue() failed. Error: {1}",
                                GetType().Name, status);
                    continue;
                }

                if (page == HIDPage.GenericDesktop && (HIDUsageGD)usage == HIDUsageGD.Hatswitch)
                {
                    stick.SetHat(collection, page, usage, GetHatPosition(value, stick.AxisCaps[i]));
                }
                else
                {
                    if (stick.AxisCaps[i].LogicalMin > 0)
                    {
                        short scaled_value = (short)HidHelper.ScaleValue(
                            (int)((long)value + stick.AxisCaps[i].LogicalMin),
                            stick.AxisCaps[i].LogicalMin, stick.AxisCaps[i].LogicalMax,
                            Int16.MinValue, Int16.MaxValue);
                        stick.SetAxis(collection, page, usage, scaled_value);
                    }
                    else
                    {
                        //If our stick returns a minimum value below zero, we should not add this to our value
                        //before attempting to scale it, as this then inverts the value
                        short scaled_value = (short)HidHelper.ScaleValue(
                            (int)(long)value,
                            stick.AxisCaps[i].LogicalMin, stick.AxisCaps[i].LogicalMax,
                            Int16.MinValue, Int16.MaxValue);
                        stick.SetAxis(collection, page, usage, scaled_value);
                    }
                }
            }
        }
Пример #3
0
        private static bool GetDeviceCaps(Device stick, byte[] preparsed_data, out HidProtocolCaps caps)
        {
            // Query joystick capabilities
            caps = new HidProtocolCaps();
            if (HidProtocol.GetCaps(preparsed_data, ref caps) != HidProtocolStatus.Success)
            {
                Debug.Print("[WinRawJoystick] HidProtocol.GetCaps() failed with {0}",
                            Marshal.GetLastWin32Error());
                return(false);
            }

            // Make sure our caps arrays are big enough
            HidProtocolValueCaps[]  axis_caps   = new HidProtocolValueCaps[caps.NumberInputValueCaps];
            HidProtocolButtonCaps[] button_caps = new HidProtocolButtonCaps[caps.NumberInputButtonCaps];

            // Axis capabilities
            ushort axis_count = (ushort)axis_caps.Length;

            if (HidProtocol.GetValueCaps(HidProtocolReportType.Input,
                                         axis_caps, ref axis_count, preparsed_data) !=
                HidProtocolStatus.Success)
            {
                Debug.Print("[WinRawJoystick] HidProtocol.GetValueCaps() failed with {0}",
                            Marshal.GetLastWin32Error());
                return(false);
            }

            // Button capabilities
            ushort button_count = (ushort)button_caps.Length;

            if (HidProtocol.GetButtonCaps(HidProtocolReportType.Input,
                                          button_caps, ref button_count, preparsed_data) !=
                HidProtocolStatus.Success)
            {
                Debug.Print("[WinRawJoystick] HidProtocol.GetButtonCaps() failed with {0}",
                            Marshal.GetLastWin32Error());
                return(false);
            }

            stick.AxisCaps.Clear();
            stick.AxisCaps.AddRange(axis_caps);

            stick.ButtonCaps.Clear();
            stick.ButtonCaps.AddRange(button_caps);

            return(true);
        }
Пример #4
0
        public unsafe bool ProcessEvent(IntPtr raw)
        {
            // Query the size of the raw HID data buffer
            int size = 0;

            Functions.GetRawInputData(raw, GetRawInputDataEnum.INPUT, IntPtr.Zero, ref size, RawInputHeader.SizeInBytes);
            if (size > HIDData.Length)
            {
                Array.Resize(ref HIDData, size);
            }

            // Retrieve the raw HID data buffer
            if (Functions.GetRawInputData(raw, HIDData) > 0)
            {
                fixed(byte *pdata = HIDData)
                {
                    RawInput *rin = (RawInput *)pdata;

                    IntPtr handle = rin->Header.Device;
                    Device stick  = GetDevice(handle);

                    if (stick == null)
                    {
                        Debug.Print("[WinRawJoystick] Unknown device {0}", handle);
                        return(false);
                    }

                    if (stick.IsXInput)
                    {
                        return(true);
                    }

                    if (!GetPreparsedData(handle, ref PreparsedData))
                    {
                        return(false);
                    }

                    // Query current state
                    // Allocate enough storage to hold the data of the current report
                    int report_count = HidProtocol.MaxDataListLength(HidProtocolReportType.Input, PreparsedData);

                    if (report_count == 0)
                    {
                        Debug.Print("[WinRawJoystick] HidProtocol.MaxDataListLength() failed with {0}",
                                    Marshal.GetLastWin32Error());
                        return(false);
                    }

                    // Fill the data buffer
                    if (DataBuffer.Length < report_count)
                    {
                        Array.Resize(ref DataBuffer, report_count);
                    }

                    UpdateAxes(rin, stick);
                    UpdateButtons(rin, stick);
                    return(true);
                }
            }

            return(false);
        }