示例#1
0
void WiimoteScannerHidapi::FindWiimotes(std::vector<Wiimote*>& wiimotes, Wiimote*& board)
{
  hid_device_info* list = hid_enumerate(0x0, 0x0);
  for (hid_device_info* device = list; device; device = device->next)
  {
    const std::string name = device->product_string ? UTF16ToUTF8(device->product_string) : "";
    const bool is_wiimote =
        IsValidDeviceName(name) || (device->vendor_id == 0x057e &&
                                    (device->product_id == 0x0306 || device->product_id == 0x0330));
    if (!is_wiimote || !IsNewWiimote(device->path) || !IsDeviceUsable(device->path))
      continue;

    auto* wiimote = new WiimoteHidapi(device->path);
    const bool is_balance_board = IsBalanceBoardName(name) || wiimote->IsBalanceBoard();
    if (is_balance_board)
      board = wiimote;
    else
      wiimotes.push_back(wiimote);

    NOTICE_LOG(WIIMOTE, "Found %s at %s: %ls %ls (%04hx:%04hx)",
               is_balance_board ? "balance board" : "Wiimote", device->path,
               device->manufacturer_string, device->product_string, device->vendor_id,
               device->product_id);
  }
  hid_free_enumeration(list);
}
示例#2
0
// Connect to a Wiimote with a known device path.
bool WiimoteWindows::ConnectInternal()
{
  if (IsConnected())
    return true;

  if (!IsNewWiimote(UTF16ToUTF8(m_devicepath)))
    return false;

  auto const open_flags = FILE_SHARE_READ | FILE_SHARE_WRITE;

  m_dev_handle = CreateFile(m_devicepath.c_str(), GENERIC_READ | GENERIC_WRITE, open_flags, nullptr,
                            OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);

  if (m_dev_handle == INVALID_HANDLE_VALUE)
  {
    m_dev_handle = nullptr;
    return false;
  }

#if 0
	TCHAR name[128] = {};
	pHidD_GetProductString(dev_handle, name, 128);

	//ERROR_LOG(WIIMOTE, "Product string: %s", TStrToUTF8(name).c_str());

	if (!IsValidBluetoothName(TStrToUTF8(name)))
	{
		CloseHandle(dev_handle);
		dev_handle = 0;
		return false;
	}
#endif

#if 0
	HIDD_ATTRIBUTES attr;
	attr.Size = sizeof(attr);
	if (!pHidD_GetAttributes(dev_handle, &attr))
	{
		CloseHandle(dev_handle);
		dev_handle = 0;
		return false;
	}
#endif

  // TODO: thread isn't started here now, do this elsewhere
  // This isn't as drastic as it sounds, since the process in which the threads
  // reside is normal priority. Needed for keeping audio reports at a decent rate
  /*
    if (!SetThreadPriority(m_wiimote_thread.native_handle(), THREAD_PRIORITY_TIME_CRITICAL))
    {
      ERROR_LOG(WIIMOTE, "Failed to set Wiimote thread priority");
    }
  */

  return true;
}
示例#3
0
文件: IOLinux.cpp 项目: booto/dolphin
void WiimoteScannerLinux::FindWiimotes(std::vector<Wiimote*>& found_wiimotes, Wiimote*& found_board)
{
  // supposedly 1.28 seconds
  int const wait_len = 1;

  int const max_infos = 255;
  inquiry_info scan_infos[max_infos] = {};
  auto* scan_infos_ptr = scan_infos;
  found_board = nullptr;
  // Use Limited Dedicated Inquiry Access Code (LIAC) to query, since third-party Wiimotes
  // cannot be discovered without it.
  const u8 lap[3] = {0x00, 0x8b, 0x9e};

  // Scan for Bluetooth devices
  int const found_devices =
      hci_inquiry(m_device_id, wait_len, max_infos, lap, &scan_infos_ptr, IREQ_CACHE_FLUSH);
  if (found_devices < 0)
  {
    ERROR_LOG(WIIMOTE, "Error searching for Bluetooth devices.");
    return;
  }

  DEBUG_LOG(WIIMOTE, "Found %i Bluetooth device(s).", found_devices);

  // Display discovered devices
  for (int i = 0; i < found_devices; ++i)
  {
    NOTICE_LOG(WIIMOTE, "found a device...");

    // BT names are a maximum of 248 bytes apparently
    char name[255] = {};
    if (hci_read_remote_name(m_device_sock, &scan_infos[i].bdaddr, sizeof(name), name, 1000) < 0)
    {
      ERROR_LOG(WIIMOTE, "name request failed");
      continue;
    }

    NOTICE_LOG(WIIMOTE, "device name %s", name);
    if (!IsValidDeviceName(name))
      continue;

    char bdaddr_str[18] = {};
    ba2str(&scan_infos[i].bdaddr, bdaddr_str);

    if (!IsNewWiimote(bdaddr_str))
      continue;

    // Found a new device
    Wiimote* wm = new WiimoteLinux(scan_infos[i].bdaddr);
    if (IsBalanceBoardName(name))
    {
      found_board = wm;
      NOTICE_LOG(WIIMOTE, "Found balance board (%s).", bdaddr_str);
    }
    else
    {
      found_wiimotes.push_back(wm);
      NOTICE_LOG(WIIMOTE, "Found Wiimote (%s).", bdaddr_str);
    }
  }
}
示例#4
0
// Find and connect Wiimotes.
// Does not replace already found Wiimotes even if they are disconnected.
// wm is an array of max_wiimotes Wiimotes
// Returns the total number of found and connected Wiimotes.
void WiimoteScannerWindows::FindWiimotes(std::vector<Wiimote*>& found_wiimotes,
                                         Wiimote*& found_board)
{
  if (!s_loaded_ok)
    return;

  ProcessWiimotes(true, [](HANDLE hRadio, const BLUETOOTH_RADIO_INFO& rinfo,
                           BLUETOOTH_DEVICE_INFO_STRUCT& btdi) {
    ForgetWiimote(btdi);
    AttachWiimote(hRadio, rinfo, btdi);
  });

  // Get the device id
  GUID device_id;
  pHidD_GetHidGuid(&device_id);

  // Get all hid devices connected
  HDEVINFO const device_info =
      SetupDiGetClassDevs(&device_id, nullptr, nullptr, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT));

  SP_DEVICE_INTERFACE_DATA device_data = {};
  device_data.cbSize = sizeof(device_data);
  PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = nullptr;

  for (int index = 0;
       SetupDiEnumDeviceInterfaces(device_info, nullptr, &device_id, index, &device_data); ++index)
  {
    // Get the size of the data block required
    DWORD len;
    SetupDiGetDeviceInterfaceDetail(device_info, &device_data, nullptr, 0, &len, nullptr);
    detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(len);
    detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

    SP_DEVINFO_DATA device_info_data = {};
    device_info_data.cbSize = sizeof(SP_DEVINFO_DATA);

    // Query the data for this device
    if (SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, nullptr,
                                        &device_info_data))
    {
      std::basic_string<TCHAR> device_path(detail_data->DevicePath);
      bool IsUsingToshibaStack = CheckForToshibaStack(device_info_data.DevInst);

      WinWriteMethod write_method = GetInitialWriteMethod(IsUsingToshibaStack);

      if (!IsNewWiimote(UTF16ToUTF8(device_path)) || !IsWiimote(device_path, write_method))
      {
        free(detail_data);
        continue;
      }

      auto* wiimote = new WiimoteWindows(device_path, write_method);
      if (wiimote->IsBalanceBoard())
        found_board = wiimote;
      else
        found_wiimotes.push_back(wiimote);
    }

    free(detail_data);
  }

  SetupDiDestroyDeviceInfoList(device_info);
}