bool InputManager::addNewDevice(HWND hWindow, GUID instanceGUID, GUID productGUID, std::string name) { bool deviceAdded = false; InputDevice* device; if(nrOfXInputDevices_ >= XUSER_MAX_COUNT || !isXInputDevice(&productGUID)) { LPDIRECTINPUTDEVICE8 dInputDevice; HRESULT result = dInput_->CreateDevice(instanceGUID, &dInputDevice, NULL); if(FAILED(result)) return false; DirectInputDevice* diDevice = new DirectInputDevice(dInputDevice, instanceGUID, name, devices_.size()); if(diDevice->Init(hWindow)) { devices_.push_back(diDevice); device = diDevice; deviceAdded = true; } } else { device = new XInputDevice(nrOfXInputDevices_++, instanceGUID, name, devices_.size()); devices_.push_back(device); deviceAdded = true; } if(deviceAdded) { SEND_EVENT(&Event_CreateInputDevice(device, device->getInputObjectArray())); } return deviceAdded; }
BOOL CALLBACK enumCallback(const DIDEVICEINSTANCE* instance, VOID* context) { HRESULT hr; BOOL xinput = false; if (instance->wUsagePage != 1 || instance->wUsage != 5) { // Not an actual game controller (see issue #3) return DIENUM_CONTINUE; } // First check if the device is known auto it = isXInput.find(instance->guidInstance); if (it == isXInput.end()) { // Not found yet, so check if it is an XInputDevice xinput = isXInputDevice(&instance->guidProduct); isXInput[instance->guidInstance] = xinput; } else { xinput = it->second; } if (xinput) { // If it is an xinput, we can safely ignore return DIENUM_CONTINUE; } // Check if we have a live DI instance of this joystick if (joysticks.find(instance->guidInstance) != joysticks.end()) { return DIENUM_CONTINUE; } // If not we must build it... LPDIRECTINPUTDEVICE8 joystick; // Obtain an interface to the enumerated joystick. hr = di->CreateDevice(instance->guidInstance, &joystick, NULL); // If it failed, then we can't use this joystick. (Maybe the user unplugged // it while we were in the middle of enumerating it.) if (FAILED(hr)) { // As seen on x360ce, if create device fails on guid instance, try the product hr = di->CreateDevice(instance->guidProduct, &joystick, NULL); if (FAILED(hr)) return DIENUM_CONTINUE; } // Set the data format to "simple joystick" - a predefined data format // // A data format specifies which controls on a device we are interested in, // and how they should be reported. This tells DInput that we will be // passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState(). if (FAILED(hr = joystick->SetDataFormat(&c_dfDIJoystick2))) { printf("SetDataFormat is f****d %x\n", hr); joystick->Release(); return DIENUM_CONTINUE; } hr = joystick->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_BACKGROUND); if (FAILED(hr)) { hr = joystick->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); if (FAILED(hr)) { printf("Cooperative is f****d %x\n", hr); } } DIPROPDWORD dipdw; dipdw.diph.dwSize = sizeof(DIPROPDWORD); dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipdw.diph.dwObj = 0; dipdw.diph.dwHow = DIPH_DEVICE; dipdw.dwData = DIPROPAUTOCENTER_ON; joystick->SetProperty(DIPROP_AUTOCENTER, &dipdw.diph); // Acquire the device if (FAILED(hr = joystick->Acquire())) { printf("Acquire is f****d %x\n", hr); joystick->Release(); return DIENUM_CONTINUE; } // Store the joystick instance accessible via guid joysticks[instance->guidInstance] = joystick; // Get other devices return DIENUM_CONTINUE; }