Gathering information on input systems

Started by
7 comments, last by NightCreature83 10 years, 2 months ago

Hi,

i'm currently trying to gather as much information on input systems as possible.

In order to this i looked up some different libraries like GLFW and SDL.

While getting in touch with them, i noticed that it is required to have an instance of a window to actually gain input information from the underlaying OS via that libraries.

So here is my question(s):

Would you call it a bad practice if one would try to gain input information directly from the OS even if there is no window instance? (the input system should run fine without a window to do its job)

The game itself would then decide whether to handle the input event that is emited by the input system or not because it has some knowledge about the window it is running in.

If the window of the game has focus then the event would be handled. If the window has no focus then the event would be consumed or whatever but not handled.

If doing so - are there any pitfalls one would have to deal with while the project is growing?

What are typical approaches in commercial products to do things like this?

I really appreciate any information on this subject.

Thank you in advance.

Advertisement

Not all input is passed by the OS' windowing system anyhow. Advanced USB input devices may need to be driven by using HID or a similar API.

When gathering input it is generally important to not store states (only) but transitions where appropriate, and to store a timestamp of occurrence with it. This allows for temporal affiliation and combo detection. It is even more important to not miss input, so you perhaps need a separate thread for input gathering (depending on how the APIs provide the input).

Some events you need to get are actually bound to a window, like window resizing and closing. Such event must not be ignored when running in windowed mode, of course.

Thank you for your reply.

The timestamp is a nice hint though - didn't think of this.

Some events you need to get are actually bound to a window, like window resizing and closing. Such event must not be ignored when running in windowed mode, of course.

That is quite true, but this is exactly the point that i want to avoid.

Events related to a window should be handled by a window handler or a similar instance because that isn't input that will affect the behavior of entities within the game (like a player that is moving). Ok, if you're closing the window, then the game is affected but i think this would also be part of the window handler. This instance has to make sure that this kind of event is propagated to a kind of main system that is able to shutdown all parts of an engine, or a game in more general.

So this is why i found it pretty awkward that a window instance is required to handle game related input. But maybe its just me thinking in a wrong direction.

But i will definitely have a look on a HID API and try to implement a prototype of my input system using it (Sending information to a USB device, like ForceFeedbackInformation seems to be an advantage over other libraries, like the ones mentioned in my initial post).

http://molecularmusings.wordpress.com/2011/09/05/properly-handling-keyboard-input/

http://molecularmusings.wordpress.com/2011/09/29/wiring-physical-devices-to-abstract-inputs/

There is no need to have a HWND, the RawInput API on windows allows you to grab the input on the fly. XINPUT doesnt need a hwnd either and is porbably the easiest way to get a controller to work on windows.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

Hi NightCreature83,

thank you for your reply.

Your offered links are pretty interesting and cover a lot of things i was thinking about.

Unfortunately it is based on Windows and i want the input system to be running on other platforms as Linux and Mac as well (sry, i didn't mention this in my initial post).

So in order to this there is a need for some standard that needs to be supported by all of these platforms and USB seems to get it right (on a low level).

While looking for some HID APIs, i came across the following one:

http://libusbx.org/

It looks right for testing some stuff and trying to implement a prototype using it.

Events related to a window should be handled by a window handler or a similar instance because that isn't input that will affect the behavior of entities within the game (like a player that is moving). Ok, if you're closing the window, then the game is affected but i think this would also be part of the window handler. This instance has to make sure that this kind of event is propagated to a kind of main system that is able to shutdown all parts of an engine, or a game in more general.

It depends on where you draw the border. I've running a thread to gather input, to translate it from OS to engine events, and push them into a queue. The thread that runs the game loop reads the queue when the InputServices is updated. This services instance has the ability to plug-in input listeners, so to say. Entity components like the PlayerController puts to use this, as well as sub-systems can do so. E.g. the Graphics sub-system can install an input listener to get window size changes. And the loop itself could install a listener to detect quit conditions if wanted so, or even better the GameServices instance should do so.

EDIT: Notice that I do not consume events in the game loop. Instead, events become deprecated at some time and will be removed then. This allows several units to detect relevant events. This is another use case for the timestamp here.

Hi NightCreature83,

thank you for your reply.

Your offered links are pretty interesting and cover a lot of things i was thinking about.

Unfortunately it is based on Windows and i want the input system to be running on other platforms as Linux and Mac as well (sry, i didn't mention this in my initial post).

So in order to this there is a need for some standard that needs to be supported by all of these platforms and USB seems to get it right (on a low level).

While looking for some HID APIs, i came across the following one:

http://libusbx.org/

It looks right for testing some stuff and trying to implement a prototype using it.

Actually only the first part is windows only the second link is platform agnostic an can be applied to all platforms, and it is also at that level that you make this code platform unaware.

Btw if you want multi-platform in input, you are going to have to write platform specific code, dealing with hardware devices is pretty hardwired into the platforms. Even between console generations of the same manufacturer this is different. The only other way out is writing your own HID interface but even then you run into platform differences, when dealing with hardware on different OSes sadly you will always have to write platform specific code.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

It depends on where you draw the border. I've running a thread to gather input, to translate it from OS to engine events, and push them into a queue. The thread that runs the game loop reads the queue when the InputServices is updated. This services instance has the ability to plug-in input listeners, so to say. Entity components like the PlayerController puts to use this, as well as sub-systems can do so. E.g. the Graphics sub-system can install an input listener to get window size changes. And the loop itself could install a listener to detect quit conditions if wanted so, or even better the GameServices instance should do so.

Yeah that's right.

The procedure that you've explained will get important right after the input has been gathered in a raw state.

Nevertheless i would separate the window input and the usual game input. A very raw sketch of my thoughts to this is attached to this post.

The "IOHandler" will be the entry point to the system. One can't dive deeper into it to keep it as high level as possible. So in order to this, you need to register or deregister listener right there.

Btw if you want multi-platform in input, you are going to have to write platform specific code, dealing with hardware devices is pretty hardwired into the platforms. Even between console generations of the same manufacturer this is different. The only other way out is writing your own HID interface but even then you run into platform differences, when dealing with hardware on different OSes sadly you will always have to write platform specific code.

I guess you are right.

One way would be to implement a high-level api that uses low-level stuff depending on the platform that you're using. So you have to deal with platform specific stuff just at a single point in the low-level part (Please correct me if i'm wrong).

For sure it's sad to see everything being high-end and then one is struggling when implementing an input system caused by platform specific "standards".

But libusbx needs a chance. Even if it's just for the sake of learning something new i'll go to try it out.

Thanks for the feedback so far.

It depends on where you draw the border. I've running a thread to gather input, to translate it from OS to engine events, and push them into a queue. The thread that runs the game loop reads the queue when the InputServices is updated. This services instance has the ability to plug-in input listeners, so to say. Entity components like the PlayerController puts to use this, as well as sub-systems can do so. E.g. the Graphics sub-system can install an input listener to get window size changes. And the loop itself could install a listener to detect quit conditions if wanted so, or even better the GameServices instance should do so.

Yeah that's right.

The procedure that you've explained will get important right after the input has been gathered in a raw state.

Nevertheless i would separate the window input and the usual game input. A very raw sketch of my thoughts to this is attached to this post.

The "IOHandler" will be the entry point to the system. One can't dive deeper into it to keep it as high level as possible. So in order to this, you need to register or deregister listener right there.

Btw if you want multi-platform in input, you are going to have to write platform specific code, dealing with hardware devices is pretty hardwired into the platforms. Even between console generations of the same manufacturer this is different. The only other way out is writing your own HID interface but even then you run into platform differences, when dealing with hardware on different OSes sadly you will always have to write platform specific code.

I guess you are right.

One way would be to implement a high-level api that uses low-level stuff depending on the platform that you're using. So you have to deal with platform specific stuff just at a single point in the low-level part (Please correct me if i'm wrong).

For sure it's sad to see everything being high-end and then one is struggling when implementing an input system caused by platform specific "standards".

But libusbx needs a chance. Even if it's just for the sake of learning something new i'll go to try it out.

Thanks for the feedback so far.

Yeah that is definitely the way games are written platform specifics get hidden behind interfaces and so the game code actually only see the non platform specific interface. Offcourse you can check middleware out, however I often found that the middleware doesn't always do stuff the way I want it to work, and in those case you are better off writing it yourself. But without trying the middleware you will never know this off course and You will alwasy learn something in the process.

PS: your actually in luck because I was working on this stuff myself and the links I gave you are the best I found in dealing with this stuff in a non event manner. I like to have my objects actually poll for the input themselves instead of responding to events, makes it easier to turn them off when needed by just passing a dummy input to them.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

This topic is closed to new replies.

Advertisement