1
\$\begingroup\$

I have working wrappers for Xinput and DirectInput in my game, but I had problems with xbox controllers, because they are also recognized as generic controllers by directinput.

I have found out that Microsoft recommends to solve this problem like described on this MSDN page (See the IsXInputDevice function in the code sample).

I implemented the suggested function, but sadly it is very slow and I found out that the following call takes about half a minute to finish on my computer:

pIWbemServices->CreateInstanceEnum(bstrClassName, 0, NULL, &pEnumDevices);

Could anyone solve this problem and if yes, how? I imagine many games use this method to select the correct input method for gamepads, but the problem is not common at all.

For the time being, I began writing a wrapper for raw input but I'd be happy if this also got solved.

\$\endgroup\$
  • \$\begingroup\$ Most games these days just use XInput and don't bother with legacy DirectInput--unless you really need legacy joystick support or driving a custom haptic device, there's not much point. You should also avoid using DirectInput for mouse and keyboard input in all cases. The delay does seem unusually long, but perhaps it's something to do with your Internet connection? CreateInstanceEnum takes a number of flags you might consider using if you really need to go this route. \$\endgroup\$ – Chuck Walbourn Sep 8 '16 at 17:21
1
\$\begingroup\$

There's an alternative, but it is in C#:

http://www.gamedev.net/blog/161/entry-1868663-controller-input-updates-to-cogwheel/

using System.Globalization;
using System.Management;
using System.Text.RegularExpressions;

namespace CogwheelSlimDX.JoystickInput {
    public class Joystick {

    public ushort VendorId { get; private set; }

    public ushort ProductId { get; private set; }

    public bool IsXInputDevice {
        get {
            var ParseIds = new Regex(@"([VP])ID_([\da-fA-F]{4})"); // Used to grab the VID/PID components from the device ID string.

            // Iterate over all PNP devices.
            using (var QueryPnp = new ManagementObjectSearcher(@"\\.\root\cimv2", string.Format("Select * FROM Win32_PNPEntity"), new EnumerationOptions() { BlockSize = 20 })) {
                foreach (var PnpDevice in QueryPnp.Get()) {

                    // Check if the DeviceId contains the tell-tale "IG_".
                    var DeviceId = (string)PnpDevice.Properties["DeviceID"].Value;
                    if (DeviceId.Contains("IG_")) {

                        // Check the VID/PID components against the joystick's.
                        var Ids = ParseIds.Matches(DeviceId);
                        if (Ids.Count == 2) {
                            ushort? VId = null, PId = null;
                            foreach (Match M in Ids) {
                                ushort Value = ushort.Parse(M.Groups[2].Value, NumberStyles.HexNumber);
                                switch (M.Groups[1].Value) {
                                    case "V": VId = Value; break;
                                    case "P": PId = Value; break;
                                }
                            }
                            if (VId.HasValue && this.VendorId == VId && PId.HasValue && this.ProductId == PId) return true;
                        }
                    }
                }
            }
            return false;
        }
    }
  }
}
\$\endgroup\$
  • \$\begingroup\$ Thanks, but I specifically need C++. :) \$\endgroup\$ – János Turánszki Aug 20 '15 at 18:13
  • \$\begingroup\$ While this answer is old, it looks like all that's happening here is a walk over the devices, checking for particular strings/patterns. So there shouldn't be anything here that a user trying to solve this problem couldn't translate into the language of their choice. \$\endgroup\$ – DMGregory Sep 20 '18 at 9:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.