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;
}
Ejemplo n.º 2
0
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;
}