• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

Querying DirectInput button status

Messages
531
Country
france
Hello experts,

I know how to use DirectInput to read a DirectX device status, axis and buttons, no problem. The question I have here is about the ability to read a button status even if nothing happens, no user action.
What I mean here is that DirectInput is event-based, it will give you the status of a button only when it is pressed or released. Most of the time, this is OK. But for some specific devices, such as the Honeycomb yoke, buttons are used with switches: when off, it appears as a released button and when on, it appears as a pressed button. Consequently, there might be a discrepancy between the real device and its counterpart in the sim. For example, if I have a switch mapped for the battery, when I start the sim the battery is OFF, and if the physical switch is ON, it is not consistent.
This is why I ask: is there a way to interrogate the switch status to position the switch in the sim accordingly?
In that example, I would read the switch status, and if I see it is ON, I turn on the battery in my initialization sequence.
I couldn't find a way to do it. I was able to read the switch status only if it is moved, If the status changes. If there is a way to do it, I would be glad to know.

Thanks,
Eric
 
I'm not sure how you are using DirectInput, but in my experience it is not event based (at least, I have never attached a window handle to it).

I use the device->Poll function every sim frame for each device followed by device->GetDeviceState function which outputs a struct containing all axis positions, all button and POV hat states. I then have some functions that I call in my system code to query the state of a particular control which checks the device and button that control is mapped to and returns the state.
 
I agree with you, this is exactly what I also do, but it doesn't always work as expected. Imagine if you have a switch that is ON, seen by DirectX as a pressed button, and you call the poll function, the status you will get is a released button even if the button is pressed (with the switch on). The poll function will return the correct value only when the switch will be moved, and it will always be correct afterwards. Only the initial status is problematic and this is the meaning of my question, the initial status only.

By the way, this can be seen in the USB Game Controller panel of Windows. If you launch it without touching any button, it can be wrong, especially if you have switches connected to button inputs. All become valid as soon as their position has moved once.
This is why I wrote it is event based, even if I am aware that from a programming perspective, it isn't.
 
Just to make my question clearer, here are some images with the Windows USB Game Controller panel that explain better.

First, I open the game controller panel on my device that has 2 switch buttons and a selector. Pay attention on the number 4 only, which is the left switch I will use here.
The panel shows this while the physical switch (the left one) is OFF, everything looks OK and consistent:

Status1.jpg


Now let's move the left switch to turn it ON, the situation looks like this:

Status2.jpg


Again, everything looks OK, the panel indicates button 4 is pressed because the left switch is ON, perfect.

Now let's keep the left switch ON and close the panel, then re-open it. This is what we see:

Status3.jpg


Now this is inconsistent. This is because no switch has moved yet, no event has occurred, so DirectX believes the device is in its initial status with all buttons released. After all, DirectX can believe this because all the joystick buttons are released until you press one of them, but this is wrong when switches are used.
As soon as you change a status of a button, in my case I can move the right switch or the selector, or I can turn the left switch OFF, then DirectX really polls the device status and everything becomes correct:

Status2.jpg


Not only the button 4 correctly shows the status of the left switch but the axis position is also updated to become correct. I use no axis on this device, so the axis position is seen by DirectX as full right, full bottom, as shown on the image.

Conclusion: when using DirectImput, the initial status is ALWAYS made of all buttons released and axis centered, with all axis centered. This can be wrong sometimes and not consistent with the real physical status of the device, which leads to a discrepancy between the device and the aircraft in the sim.
This is why I would like to be able to interrogate a DirectX device to correctly set the initial status in the sim, according to the status of the real device.

Please let me know if my explanations are not clear :)

Eric
 
I do not believe there is a way to do what you seek, with DirectX. Any training systems I've worked on have used custom software and hardware and never relied on DirectX for input.
 
Unfortunately this is what I thought.
Even if I never worked with professional training systems, the devices I have from CPFlight and CockpitSonic don't use DirectX either and they can be queried in any way to make sure their status is always consistent with what appears in the sim.
I wanted to use these 2 switches for battery and alternator in MSFS light aircraft, but if I can't be sure the position of the physical switches is always consistent with the positions of the sim switches, it is useless...
 
Hi Eric,

I understand exactly what you are trying to accomplish, since have the same problem (I think) as you.
In my simple home cockpit, I'm using 4 Gameport-to-USB devices, each of which are seen by in Windows as a standard USB-controller with 2 axis and 4 buttons.
Using potmeters and on/off switches on the gameport-side of the device, to simulate axis and buttons, giving me 8 axis and 16 buttons to work with in FS.

Now, what you observe (like with your pictures above in the Windows Controller TEST tab (but for a 2-axis, 8-button gamepad controller driver) is exactly what I see:
When I open the TEST tab for a Gameport-to-USB device, all axis are centered and all buttons are Off; UNTIL I move one of the potmeters or switches; then ALL of the states (axis/buttons) are displayed correctly.
And exactly the same happens with my Logitech USB joystick.

So I don't think this "intial state" problem is a limitation of DirectX per-sé, but a limitation of the USB serial protocol as implemented between the controller HW and the standard USB controllers/drivers in Windows.
In short: it's not a limitation of DirectX, but the way that simple USB drivers work (as usually implemented in simple Windows drivers).
Said in other words:
The standard Windows USB drivers don't 'interrogate' a connected USB device for their axis/button status, but the controller device itself just 'dumps' all axis/buttons data (via the serial protocol through the USB cable) whenever there is a change in any of the physical axis/buttons.

Now, I don't know how you connected the switches and knob in your pictures, but I suspect you are using some re-wired, existing USB device... Right ??
If so, I don't think you can solve your 'initial state' problem this way; because you simply can't read the actual, initial states of the USB controller devices via DirectX.
Again: not a limitation of DirectX, or the USB protocol itself, but a limitation of how the data exchange is implemented between standard USB drivers and external USB controllers.

Assuming your problem (initial states) is the same as I have, and how you connect these switches as "buttons" via a USB controller:
This is how I 'bypassed' it in my home cockpit setup, using these 4 Gameport-to-USB devices.
I have one (multi-contacts) pushbutton on/off button that short-circuits 1 button per device, acting as a "sync" button.
So when pressing/releasing that button during aircraft load, it forces Windows to initialise ALL axis and switches to their actual state: axis (potmeter) position and switch (button) state.

Of course, it's not perfect, and a work-around.
And, needless to say, this only solves initial settings.
You need a lot of extra code and/or additional hardware to keep external controller levers/switches in sync with the actual settings in the sim during flight.
Like: (in your example): you need to block any event (caused by keystroke, buttonpress or mouseclick) that changes the Battery state other then via your external physical switch.

Rob
 
Hi Rob,

What you wrote here is very interesting. I never thought this was because of the USB itself, because of the way it works. I should have thought about this, it is so clear now.
I fully understood what you wrote, except the part about the solution you propose, I am not sure. You say you have 1 button on each device connected to a button that you press during aircraft load to "sync" all the device inputs, am I right? Is it a manual action you have to do?
If so, another solution might be to build a small oscillator that opens/closes this circuit 10 times per second. You could just ignore it when flying, as the aircraft load takes more than 1/10 second, you would be sure the devices are automatically synced without the need of a manual button press. My skills in electronics should allow me to build such device :)
It is certainly an ugly solution, but if it works, it might be worth a try...

Eric
 
Back
Top