Overriding InputMapper

Sep 26, 2009 at 3:52 AM
Edited Sep 26, 2009 at 3:53 AM

Hello,

I am currently designing the Control System for the game I'm developing. Ultimately I'm going to want to let players modify controls how they see fit. They way I'm going about doing this is creating a class that overrides Xen.Input.Mapping.InputMapper which will handle the conversion of the physical button press to the virtual button presses that my engine recognizes.

However, I'm running into some difficulty. When I override the UpdateState for a GamePad:

protected override void UpdateState(UpdateState gameState, InputState input, GamePadState state)

I don't understand how to map from the GamePadState to the InputState. For example, if I want to swap the A and the B buttons, I don't know how to set

input.Buttons.A; // Type Xen.Input.State.Button and Read-Only
input.Buttons.B;

So that they have the values contained in

state.Buttons.B; // Type Microsoft.Xna.Framework.Input.ButtonState
state.Buttons.A;

My first thought was to check how Xen.Input.Mapping.InputMapper implements:

protected virtual void UpdateState(UpdateState gameState, InputState input, GamePadState state)

There I found that InputMapper takes advantage of the internal Xen.Input.State.Button.SetState() method. Right now, the only solution I've thought of is modifying Xen so that the SetState method is no longer internal, but Public. I'd rather not do this (it's not much of a change, but I like to work with unmodified frameworks as much as possible). I can see no alternative to using the SetState method in order to modify the value of the InputState. So my question is this:

Am I doing something completely wrong? If not, is there something I'm not seeing that makes this work? Short of that, is the solution to make SetState a public method, rather than an internal method?

Thanks so much for the help (I've been poking through the forums with various other little hang-ups that I've had, and your answers are almost always thoughtful and helpful).

-Noah Callaway

Edit: Cleaned up the formatting (removed excess line-breaks)

 

Coordinator
Sep 27, 2009 at 7:40 PM
Edited Sep 27, 2009 at 7:40 PM

Hello :-)

You are quite correct. This is an oversight on my part. However I don't really like the idea of SetState being public, this would give the impression that button state can be changed directly by the application (bad! :)
Perhaps, what would make more sense is a 'SetState' protected method as part of the InputMapper class itself - which calls the internal method.

In the mean time feel free to make it public in your own copy. :-) Do anything you like, really.
In the next update (eventually!) I'll put in a sneaky little protected method or two to bypass it.

Sep 27, 2009 at 8:27 PM

Awesome, thanks for the clarification.

Oct 10, 2009 at 4:09 AM

Hey, a quick update in case anyone is attempting something similar.

I made the Button.SetState method public, and was using this (as discussed previously) in my InputMapper class. I was trying to run:

 

input.Buttons.A.SetState(true, tick)

As sort-of mentioned above. I was having trouble because, for the life of me, I couldn't get my InputMapper to work (it appeared as though no buttons were ever being pressed). A little digging, and I realized the silly mistake I had made. The classes InputButtons and Button are structs. So when I accessed the public accessors

 

input.Buttons; // and
input.Buttons.A

I was getting a copy of the struct. I would then SetState to my heart's content, and not actually make any changes to the structs that input was keeping track of.

My solution was to make

 

InputState.buttons
Buttons.a
Buttons.b
Buttons.x
Buttons.Y
//etc

public instead of internal. This way I can access the structs without getting useless (well, useless if you're trying to change them, anyway :) copies.

If I've done anything that seems terribly stupid, please feel free to correct me. Cheers,

-Noah Callaway