Designing a new Input system


#1

I’m starting work on re-designing VectorStorm’s old input system; the original one was based around a “virtual controller” that was supposed to be shared among all games. We mapped keyboard, mouse, and other input sources onto that virtual controller, and then games just used that virtual controller directly.

But I’m now getting to the point where I’d really like to add about twelve more buttons, and etc. The whole “virtual controller” model is kind of falling over; I really need to allow individual games to specify their own set of controls for the vsInput system to manage.

While I’m here, I’ve noticed that VectorStorm’s input remapping code only works for joystick and gamepads; I need to make that work for keyboard and mouse controls, too! This probably means a rewrite of a lot of the input system…

I’ve kind of been banging my head against the design of this system for the last couple hours. Think I’m getting closer, though!


#2

Something else we’ve never supported before; multiplayer; VectorStorm has always provided only a single virtual controller as an input device to games.

So while I’m re-architecting this system, I should probably be adding a vsController or vsGamepad concept, or something like that. So a game can decide “Hey, there are four players, let’s have separate objects for binding/reading their inputs”.

Then each player’s controls can be configured independently… player 1 could be on a gamepad, player 2 on a keyboard, etc. And the game doesn’t have to know about any of it; the input system just puts the right control inputs in the right object, and off we go. Hm…


#3

Okay, starting to get this sorted out! From a programmer’s point of view, this new system works by running a couple macros to define your control scheme:

DEFAULT_BIND_KEY( CID_LUp, SDL_SCANCODE_W );
DEFAULT_BIND_KEY( CID_LUp, SDL_SCANCODE_UP );

Those two lines create a control axis “CID_LUp” (if it doesn’t already exist), and sets ‘W’ and ‘Up’ as the default binds for that axis. There are similar macros for binding mouse buttons, the mouse wheel, and so on.

Not yet working, but soon: if the user has already bound commands to these control axes, then we’ll use the ones which the user had previously bound, instead of the ones specified here by the programmer. This means that it’ll be possible for users to use different keys, instead of ‘WASD’, if they want.

The best bit about this approach (from my point of view) is that it makes it trivial for an individual game to decide that it doesn’t want to use the default controller layout, and to provide its own set of buttons to watch. So if I want to watch twenty or thirty keyboard buttons, I can do that really easily, without complicating the base input setup!

I’ve also made a pretty good start at proper gamepad support. I still need to figure out precisely how the input system will work with multiple controllers connected simultaneously, but I might leave that for tomorrow.

Apologies for the technical posts, today! Forcing myself to write this stuff out as prose really helps me figure it out.