New Input Handling

Nov 7, 2007 at 9:22 AM
In order to do the Console I needed to create a new way of handling input. I've rewritten the InputSubSystem so that it how will raise the following messages:
KeyDown     // A key has been pressed on the keyboard
KeyUp       // A key has been released on the keyboard
KeyPress    // A key is currently being pressed
MouseDown   // One of the 4 mouse buttons has been pressed
MouseUp     // One of the 4 mouse buttons has been released
MousePress  // One of the 4 mouse buttons is being pressed
MouseMove   // The mouse has been moved - Currently abolute position
MouseScroll // The scroll value has changed - Currently absolute value
These are integers (for performance reasons) and are defined in MessageType (which is a static class and not an enumeration)
Currently GamePad and Joystick is missing, I'm going to add GamePad, but joystick has to wait.

I've done some changes to the model, one I've renamed the system to InputSystem, loosing the sub and it didn't really add any meaning, should I do this for all systems?
I've changed the way you register input handling, it's now required to add the handlers which should be used, i.e.:
public void InitializeCore()
{
    IInputSystem input = this.Services.GetService(typeof(IInputSystem)) as IInputSystem;
#ifdef !XENON
    input.RegisterHandler(new MouseHandler(this.Game));
#endif
 
    input.RegisterHandler(new KeyboardHandler(this.Game));  // As it's possible to have a keyboard on the XBox360
    input.RegisterHandler(new GamePadHandler(this.Game));
}
I'm going to restructure the EngineMessage as well as it should try to handle all message types in one file (also this scales badly for custom messages).
Nov 7, 2007 at 1:24 PM
So client code no longer registers custom event types? i.e. no more BindKeyMapping()?
Nov 7, 2007 at 2:46 PM
No inside Game_EngineMessage you would just write something similar to
private void Game_EngineMessage(EngineMessage message)
{
    switch (message.Type)
    {
        case MessageType.KeyDown:
            switch (message.Value)   // I'm currently thinking about reworking this
            {
                case (int)Keys.Escape:
                    this.Game.Exit();
                    return;
            }
            break;
 
        case MessageType.MouseDown:
            ...
            break;
    }
}
Nov 7, 2007 at 3:37 PM
Alright, I understand the decision for doing this. I'll factor out the mapping code and put it in a separate component in Common. That way, clients can use the mappings instead if they so choose (and most games probably would for user-customized key mappings). So, it could look something like this:

private void Game_EngineMessage(EngineMessage message)
{
    switch (message.Type)
    {
        case MessageType.KeyDown:
            MyGameEvent evt;
            if(inputMapping.TryGetKeyMapping(message.Value, out evt))
            {
                switch(evt)
                {
                    // ...
                }
            }
            break;
 
        case MessageType.MouseDown:
            ...
            break;
    }
}

What part of "message.Value" are you thinking about reworking? I think we need to decide as a team what should be in that message structure. It would be nice to use inheritance or "object" references to pass along only message-specific data, but then you you're going to be penalized with boxing and/or a much more complex message recycler.