/// <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); }
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); }
internal static extern NTStatus HidP_GetCaps( [In] IntPtr preparsedData, [In, Out] ref HidPCaps caps );