0

I'm working on a multi-joystick setup where I need to build custom button mappings. And even map across devices. For example, if there is a separate joystick and throttle quadrant I need to map 'Z' or whatever, over to the throttle input. I also need to be able to check and see if there is a slider(s) available on each stick as I build the mapping profiles, etc. I cannot figure out how to just say something like: if (joystick.HasSliders)

So far I've tried different variations of

PropertyInfo rxprop = typeof(SharpDX.DirectInput.JoystickState).GetProperty("Sliders");

However, if the joystick does not have sliders, this of course will throw an exception. If it only has a single slider, I will always get back an Int array of Sliders[] with two values, no matter if the stick only has a single slider or not. So it is not a guaranteed way to know if sliders exist, or even how many exist. If there is no second actual slider, the value Sliders[1] is always 0, but if there is a second slider it could still be in the 0 position.

Currently this is what I've been messing with:

usbjoysticks[k].Poll();
JoystickState currentState = null;

try
{
    currentState = usbjoysticks[k].GetCurrentState();

    //joystickmap.axisRangeMax = usbjoysticks[k].GetObjectInfoById(1);
    PropertyInfo rxprop = typeof(SharpDX.DirectInput.JoystickState).GetProperty("Sliders");
    var rzvalue = (int[])rxprop.GetValue(currentState, null);
    var mySlider1 = rzvalue[0];

    var datas = usbjoysticks[k].GetBufferedData();
    foreach (var state in datas)
    {
        Console.WriteLine(state);
        if (state.Offset == JoystickOffset.X)
        {
            Console.WriteLine(state.Value);
        }
    }
    //DeviceObjectInstance my = usbjoysticks[k].GetObjectInfoByName("Sliders1");
    var stuff = usbjoysticks[k].GetObjectPropertiesByName("Sliders0");
    //=================
    joystickmap.jX = "X";
    joystickmap.axisRangeMax = usbjoysticks[k].GetObjectPropertiesByName("Y").Range.Maximum; //65535
    joystickmap.jY = "Y";

    if (currentState.Z != 0)
    {
        joystickmap.jZ = "Z";
        var maxZrange = usbjoysticks[k].GetObjectPropertiesByName("Z").Range.Maximum;
        joystickmap.axisRangeMax = usbjoysticks[k].GetObjectPropertiesByName("Z").Range.Maximum;
    }

    if (currentState.Sliders[0] != 0 || currentState.Sliders[1] != 0) //TODO possible change to Joystick State value in class object instead of text. 
    {
        joystickmap.SLD1 = "Slider1";
        //joystickmap.jZ = "Sliders";
        joystickmap.jsSliders = currentState.Sliders;
        var maxSld1range = usbjoysticks[k].GetObjectPropertiesByName("Sliders0").Range.Maximum; 
        joystickmap.sld1 = joystickmap.jsSliders[0];
        joystickmap.sld2 = joystickmap.jsSliders[1];
    }

    if (currentState.Sliders[1] != 0)
    {
        joystickmap.SLD2 = "Slider2";
    }

    if (currentState.RotationX != 0)
    {
        joystickmap.rX = "RotationX";
    }

    if (currentState.RotationY != 0)
    {
        joystickmap.rY = "RotationY";
    }

    if (currentState.RotationZ != 0)
    {
        joystickmap.rZ = "RotationZ";
        //joystickmap.jZ = "RotationZ";
    }

    joystickmap.axisdivider = 2;

    for (var b = 0; b < 20; b++)
    {
        //joystickmap.joybuttons.Add(currentState.Buttons[b]);
        joystickmap.joybuttons[b] = (b + 1);
    }


    joystickmappings.Add(joystickmap);

    if (!File.Exists(filename))
    {
        File.WriteAllText(filename, JsonConvert.SerializeObject(joystickmap));
        // serialize JSON directly to a file
        using (StreamWriter file = File.CreateText(filename))
        {
            JsonSerializer serializer = new JsonSerializer();
            serializer.Serialize(file, joystickmap);
        }
    }
}
catch (Exception e)
{
    MessageBox.Show("USB joystick map creation failure!\n" + e.Message);
    break;
}
  • Looks like sliders are a special case as per the page here -> https://learn.microsoft.com/en-us/windows-hardware/drivers/hid/special-case-mappings. You look like you're getting close to a solution, but testing for 0, is that the rest state value of the controllers? – ErnieDingo May 16 '18 at 21:25
  • @ErnieDingo 0 is either the current physical position value or the value that comes back when the slider doesn't exist. Not sure what you mean by 'rest state'. – taterfudge May 18 '18 at 01:08
  • That is. Rest state means if the mechanism is in its default location. Eg. For a joystick it's centred. – ErnieDingo May 18 '18 at 01:15
  • @ErnieDingo Ah right, that's part of the problem. In this case, sliders, there isn't a spring driven or otherwise auto rest state. They could be left in any position, so no guarantees. I mean sure I could just make standard operating procedure that states the program cannot be initialized until someone manually returns all sliders to middle position to ensure a value other than 0 returns, but that's pretty terrible. – taterfudge May 19 '18 at 22:10
  • There has to be a way to detect even in their rest state. Will check through my code to see if anything pops up. Sounds like a challenge for you – ErnieDingo May 19 '18 at 22:48
  • I had a look at your issue, yes, the getproperty function looks your best bet to detect the slider. But, you might get more info from the Device/Capabilities of the device. Just using Properties.Device.Capabilities, check the Axe count, as I think if it's greater than 2 and you have a slider that might tell you more. – ErnieDingo May 19 '18 at 23:03
  • @ErnieDingo Yup Device.Capabilities was the first place I went looking to see if I could verify sliders or other things. It didn't pan out well. joystickmap.axiscount = usbjoysticks[k].Capabilities.AxeCount; joystickmap.axismode = usbjoysticks[k].Properties.AxisMode; joystickmap.deadzone = usbjoysticks[k].Properties.DeadZone; PropertyInfo rxprop = typeof(SharpDX.DirectInput.JoystickState).GetProperty("Sliders"); var rzvalue = (int[])rxprop.GetValue(currentState, null); var mySlider1 = rzvalue[0]; – taterfudge May 21 '18 at 00:39

0 Answers0