I've tried this out as a more generalized approach. Rather than combining exactly one keyboard player and one controller player, it combines two IPlayer interfaces of any type, so I was able to test it with two keyboard inputs which worked. So the idea is that you initialize it by passing in the types of players you want to use, and it will figure it out from there.
The downside here is that the controller options dialog won't work until a specific controller type is selected by using it. So here's the player code:
[Serializable()]
public class AnyInputPlayer : IPlayer
{
private GameForm gf;
private int index;
private IPlayer pa;
private IPlayer pb;
public EitherInputPlayer(IPlayer p1, IPlayer p2, GameForm gameForm, int myIndex)
{
gf = gameForm;
index = myIndex;
pa = p1;
pb = p2;
}
new public bool Up
{
get
{
return a(pa.Up) || b(pb.Up);
}
}
new public bool Left
{
get
{
return a(pa.Left) || b(pb.Left);
}
}
new public bool Right
{
get
{
return a(pa.Right) || b(pb.Right);
}
}
new public bool Down
{
get
{
return a(pa.Down) || b(pb.Down);
}
}
new public bool Button1
{
get
{
return a(pa.Button1) || b(pb.Button1);
}
}
new public bool Button2
{
get
{
return a(pa.Button2) || b(pb.Button2);
}
}
new public bool Button3
{
get
{
return a(pa.Button3) || b(pb.Button3);
}
}
new public bool Button4
{
get
{
return a(pa.Button4) || b(pb.Button4);
}
}
private bool a(bool input)
{
if (input)
gf.Players[index] = pa;
return input;
}
private bool b(bool input)
{
if (input)
gf.Players[index] = pb;
return input;
}
}
and you'll have to make this change to Controls.cs:
if (Project.GameWindow.Players[SelectedPlayer] is KeyboardPlayer)
{
bLoading = true;
KeyboardPlayer player = (KeyboardPlayer)Project.GameWindow.Players[SelectedPlayer];
rdoKeyboard.Checked = true;
txtUp.Text = System.Enum.Format(typeof(Microsoft.DirectX.DirectInput.Key), player.key_up, "g");
txtLeft.Text = System.Enum.Format(typeof(Microsoft.DirectX.DirectInput.Key), player.key_left, "g");
txtRight.Text = System.Enum.Format(typeof(Microsoft.DirectX.DirectInput.Key), player.key_right, "g");
txtDown.Text = System.Enum.Format(typeof(Microsoft.DirectX.DirectInput.Key), player.key_down, "g");
txtButton1.Text = System.Enum.Format(typeof(Microsoft.DirectX.DirectInput.Key), player.key_button1, "g");
txtButton2.Text = System.Enum.Format(typeof(Microsoft.DirectX.DirectInput.Key), player.key_button2, "g");
txtButton3.Text = System.Enum.Format(typeof(Microsoft.DirectX.DirectInput.Key), player.key_button3, "g");
txtButton4.Text = System.Enum.Format(typeof(Microsoft.DirectX.DirectInput.Key), player.key_button4, "g");
bLoading = false;
}
else if (Project.GameWindow.Players[SelectedPlayer] is ControllerPlayer)
and this change to GameForm.cs:
if (controllers != null && controllers.Length > 0)
Players[0] = new EitherInputPlayer(new KeyboardPlayer(0), new ControllerPlayer(0), this, 0);
else
Players[0] = new KeyboardPlayer(0);