示例#1
0
        /// <summary>
        /// Initializes a new PS4 controller.
        /// </summary>
        /// <param name="read">The "file" that the controller sends info to.</param>
        /// <param name="info">The capabilities of the controller.</param>
        internal Ps4Controller(SafeFileHandle read, HidPCaps info)
        {
            _handleRead = read;
            _caps       = info;

            _fsRead = new FileStream(read, FileAccess.ReadWrite, _caps.InputReportByteLength, false);

            // Typically you don't want to explicitly new an enum as it can cause undefined results.
            // However Monogame doesn't have a default value for Buttons, so we're forced to.
            // This will make it so the variable is equal to 0, therefore having no flags set.
            // We could also just set the variable to zero, but this way is clearer to me.

            CurrentFrameState  = new Buttons();
            PreviousFrameState = new Buttons();
            AsyncState         = new Buttons();

            //Start reading the file.
            ReadAsync();

            //Determine the controller index.
            if (_openSlots.Count == 0)
            {
                Index = _count++;
            }
            else
            {
                Index = _openSlots.Min();
                _openSlots.Remove(Index);
            }

            Ps4Input.OnControllerConnected(this);
        }
示例#2
0
        internal unsafe static bool TryRegisterPS4Controller(IntPtr handle, out Ps4Controller controller)
        {
            controller = null;
            var devName = GetRawInputDeviceName(handle);

            char[] arr       = new char[126];
            string product   = "";
            var    devHandle = CreateFileW(devName, FileAccess.Read, FileShare.ReadWrite, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero);

            fixed(char *p = arr)
            {
                if (HidD_GetProductString(devHandle, p, 126))
                {
                    product = new string(p);
                    var index = product.IndexOf('\0');
                    if (index != -1)
                    {
                        product.Remove(index);
                    }
                }
            }

            if (product == "Wireless Controller")
            {
                var preparsedData = IntPtr.Zero;
                if (!HidD_GetPreparsedData(devHandle, ref preparsedData))
                {
                    devHandle.Close();
                    return(false);
                }

                HidPCaps caps = new HidPCaps();
                if (HidP_GetCaps(preparsedData, ref caps) != NTStatus.Success)
                {
                    HidD_FreePreparsedData(ref preparsedData);
                    devHandle.Close();
                    return(false);
                }

                if (caps.InputReportByteLength == 64)
                {
                    HidD_FreePreparsedData(ref preparsedData);
                    controller = new Ps4Controller(devHandle, caps);
                    return(true);
                }
                else
                {
                    devHandle.Close();
                    return(false);
                }
            }
            devHandle.Close();
            return(false);
        }
示例#3
0
 internal static extern NTStatus HidP_GetCaps(
     [In] IntPtr preparsedData,
     [In, Out] ref HidPCaps caps
     );