Author Topic: Enable Joystick  (Read 16770 times)

Tanja

  • Clever
  • Fanatic
  • ***
  • Posts: 606
    • View Profile
Enable Joystick
« on: 2007-11-07, 01:42:50 PM »
in version 1 i found a box to be checked: Enable Joystick.
How do i the same with sgdk2?

first i thought i could change "SpriteBase.InputBits.Left" to another button, but it doesn't works.

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Enable Joystick
« Reply #1 on: 2007-11-07, 01:48:08 PM »
This is done by the player at runtime.  In the Options menu, the player can choose to use the keyboard or mouse.  There is no change necessary in the project itself to have a sprite be controlled by either a keyboard or joystick.
Edward Dassmesser

Tanja

  • Clever
  • Fanatic
  • ***
  • Posts: 606
    • View Profile
Re: Enable Joystick
« Reply #2 on: 2007-11-07, 02:34:37 PM »
ok. then i need to make a start screen with options and so on.
why does sgdk not recognizes if i press a key on keyboard or a button on my gamepad?
that's an extra move for the player which might isn't necessary. i find it a little uncomfortable.

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Enable Joystick
« Reply #3 on: 2007-11-07, 05:40:54 PM »
I think this is an improvement of SGDK2 over version 1.  Version 1 forces the game designer to choose what controls the player uses to play the game.  Usually the player wants to be in control of that.  You can change the default by editing the code in the SourceCode folder, or (I think) by setting the controls and saving the settings to a file (use the "IncludeInSaveUnit" function and the "SaveGame" function to save only the player settings) then using "LoadGame" to load the settings when the game starts.  (IncludeInSaveUnit and SaveGame could be part of your project temporarily -- just long enough to create the save file after your settings are set up; then you can delete them from your project.)

Tanja

  • Clever
  • Fanatic
  • ***
  • Posts: 606
    • View Profile
Re: Enable Joystick
« Reply #4 on: 2007-11-08, 09:15:17 AM »
i don't want to force some input device. what happens when i force gamepad and the user don't has one?
again, why does sgdk not recognizes if i press a key on keyboard or a button on my gamepad on (at?) runtime and deals with that input?
sure it`s an improvement that the player CAN choose.

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Enable Joystick
« Reply #5 on: 2007-11-08, 10:01:14 AM »
You could add a new type of player (by implementing the IPlayer interface) that accepts input from both the keyboard and the joystick somewhat easily.  Just look at Player.cs, which implements the two separately.  Then look at this code in GameForm.cs:

Code: [Select]
      Players[0] = new KeyboardPlayer(0);

      // Players 1 through (M-N) use keyboard while players (M-N+1) through M use controllers
      // where M is max player number and N is number of controllers.
      for (int playerIdx = 1; playerIdx<Project.MaxPlayers; playerIdx++)
      {
         if ((controllers != null) && (Project.MaxPlayers - playerIdx <= controllers.Length))
            Players[playerIdx] = new ControllerPlayer(playerIdx - (Project.MaxPlayers - controllers.Length));
         else
            Players[playerIdx] = new KeyboardPlayer(playerIdx);
      }

which sets which players get which input types.  I could see a player type that, upon the first input, sets itself to that type of input for the rest of the game.  Something like:

Code: [Select]
[Serializable()]
public class EitherInputPlayer : KeyboardPlayer
{
   public int deviceNumber;
   public int[] buttonMap;
   private GameForm gf;
   private int index;
   private int defaultSet;

   public EitherInputPlayer(int deviceNumber, int defaultSet, GameForm gameForm, int myIndex)
   {
      base(defaultSet);
  this.defaultSet = defaultSet;
      this.deviceNumber = deviceNumber;
      buttonMap = new int[4] {0, 1, 2, 3};
  gf = gameForm;
  index = myIndex;
   }

   public bool Up
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_up]) ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).Y < 0x4000);
      }
   }

   public bool Left
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_left] ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).X < 0x4000);
      }
   }

   public bool Right
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_right] ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).X > 0xC000);
      }
   }

   public bool Down
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_down] ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).Y > 0xC000);
      }
   }

   public bool Button1
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_button1] ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).GetButtons()[buttonMap[0]] != 0);
      }
   }

   public bool Button2
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_button2] ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).GetButtons()[buttonMap[1]] != 0);
      }
   }

   public bool Button3
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_button3] ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).GetButtons()[buttonMap[2]] != 0);
      }
   }

   public bool Button4
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_button4] ||
controller(Project.GameWindow.GetControllerState(deviceNumber).GetButtons()[buttonMap[3]] != 0);
      }
   }
   
   private bool keyboard(bool input)
   {
      if (input)
     gf.Players[index] = new KeyboardPlayer(defaultSet);
  return input;
   }
   
   private bool controller(bool input)
   {
      if (input)
     gf.Players[index] = new ControllerPlayer(deviceNumber);
  return input;
   }
}

and change the first line of the section of code previously mentioned in GameForm.cs to:

Code: [Select]
      if ((controllers != null) && (controllers.Length > 0))
         Players[0] = new EitherInputPlayer(0,0,this,0);
      else
         Players[0] = new KeyboardPlayer(0);

This hasn't been tested, so I don't know if it'll work.  But it's a general outline of how I'd go about it anyway.
Edward Dassmesser

Tanja

  • Clever
  • Fanatic
  • ***
  • Posts: 606
    • View Profile
Re: Enable Joystick
« Reply #6 on: 2007-11-11, 04:23:43 AM »
woohoo! i'll try that! thanks!

Tanja

  • Clever
  • Fanatic
  • ***
  • Posts: 606
    • View Profile
Re: Enable Joystick
« Reply #7 on: 2007-11-14, 03:00:00 PM »
tried it out now, but there are error messages.

one question in advance:
i am not sure if i did this right (change the first line of the section of code previously mentioned in GameForm.cs)
is it supposed to look like that?
Code: [Select]
// Player 0 always uses keyboard by default
         if ((controllers != null) && (controllers.Length > 0))
         Players[0] = new EitherInputPlayer(0,0,this,0);
      else
         Players[0] = new KeyboardPlayer(0);

      // Players 1 through (M-N) use keyboard while players (M-N+1) through M use controllers
      // where M is max player number and N is number of controllers.
      for (int playerIdx = 1; playerIdx<Project.MaxPlayers; playerIdx++)
      {
         if ((controllers != null) && (Project.MaxPlayers - playerIdx <= controllers.Length))
            Players[playerIdx] = new ControllerPlayer(playerIdx - (Project.MaxPlayers - controllers.Length));
         else
            Players[playerIdx] = new KeyboardPlayer(playerIdx);
      }

the other code i have pasted in, but you didn't mention the place. i guess it doesn't matters anyway.
here are the errors:

meins2\Player.cs(35,16) : warning CS0108: The keyword new is required on 'EitherInputPlayer.Up' because it hides inherited member 'KeyboardPlayer.Up'
meins2\Player.cs(44,16) : warning CS0108: The keyword new is required on 'EitherInputPlayer.Left' because it hides inherited member 'KeyboardPlayer.Left'
meins2\Player.cs(53,16) : warning CS0108: The keyword new is required on 'EitherInputPlayer.Right' because it hides inherited member 'KeyboardPlayer.Right'
meins2\Player.cs(62,16) : warning CS0108: The keyword new is required on 'EitherInputPlayer.Down' because it hides inherited member 'KeyboardPlayer.Down'
meins2\Player.cs(71,16) : warning CS0108: The keyword new is required on 'EitherInputPlayer.Button1' because it hides inherited member 'KeyboardPlayer.Button1'
meins2\Player.cs(80,16) : warning CS0108: The keyword new is required on 'EitherInputPlayer.Button2' because it hides inherited member 'KeyboardPlayer.Button2'
meins2\Player.cs(89,16) : warning CS0108: The keyword new is required on 'EitherInputPlayer.Button3' because it hides inherited member 'KeyboardPlayer.Button3'
meins2\Player.cs(98,16) : warning CS0108: The keyword new is required on 'EitherInputPlayer.Button4' because it hides inherited member 'KeyboardPlayer.Button4'
meins2\Player.cs(25,11) : error CS1501: No overload for method 'KeyboardPlayer' takes '0' arguments
meins2\Player.cs(27,7) : error CS0175: Use of keyword base is not valid in this context
meins2\Player.cs(49,84) : error CS1026: ) expected
meins2\Player.cs(58,84) : error CS1026: ) expected
meins2\Player.cs(67,84) : error CS1026: ) expected
meins2\Player.cs(76,105) : error CS1026: ) expected
meins2\Player.cs(85,105) : error CS1026: ) expected
meins2\Player.cs(94,105) : error CS1026: ) expected
meins2\Player.cs(103,99) : error CS1026: ) expected


i will try to do something about it, but have little hope.

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Enable Joystick
« Reply #8 on: 2007-11-14, 04:28:03 PM »
The change you made looks good in GameForm.cs

I fixed the errors in the code.  I made sure it compiled this time.  I've been programming in java lately, so I'm just a bit rusty.  This should be correct.  Pasting it at the bottom of Player.cs seems like a good place to put it, but it might also be a good idea to create it as its own separate code object, just in case you have to reset the code at some point for some reason.  There's no getting around the fact that you'd have to change GameForm.cs if you reset the code, but that's a minimal change.

Code: [Select]
[Serializable()]
public class EitherInputPlayer : KeyboardPlayer
{
   public int deviceNumber;
   public int[] buttonMap;
   private GameForm gf;
   private int index;
   private int defaultSet;

   public EitherInputPlayer(int deviceNumber, int defaultSet, GameForm gameForm, int myIndex) : base(defaultSet)
   {
      this.defaultSet = defaultSet;
      this.deviceNumber = deviceNumber;
      buttonMap = new int[4] {0, 1, 2, 3};
  gf = gameForm;
  index = myIndex;
   }

   new public bool Up
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_up]) ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).Y < 0x4000);
      }
   }

   new public bool Left
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_left]) ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).X < 0x4000);
      }
   }

   new public bool Right
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_right]) ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).X > 0xC000);
      }
   }

   new public bool Down
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_down]) ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).Y > 0xC000);
      }
   }

   new public bool Button1
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_button1]) ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).GetButtons()[buttonMap[0]] != 0);
      }
   }

   new public bool Button2
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_button2]) ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).GetButtons()[buttonMap[1]] != 0);
      }
   }

   new public bool Button3
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_button3]) ||
         controller(Project.GameWindow.GetControllerState(deviceNumber).GetButtons()[buttonMap[2]] != 0);
      }
   }

   new public bool Button4
   {
      get
      {
     return keyboard(Project.GameWindow.KeyboardState[key_button4]) ||
controller(Project.GameWindow.GetControllerState(deviceNumber).GetButtons()[buttonMap[3]] != 0);
      }
   }
   
   private bool keyboard(bool input)
   {
      if (input)
     gf.Players[index] = new KeyboardPlayer(defaultSet);
  return input;
   }
   
   private bool controller(bool input)
   {
      if (input)
     gf.Players[index] = new ControllerPlayer(deviceNumber);
  return input;
   }
}
Edward Dassmesser

Tanja

  • Clever
  • Fanatic
  • ***
  • Posts: 606
    • View Profile
Re: Enable Joystick
« Reply #9 on: 2007-11-17, 06:56:22 AM »
yes it compiles now. but the player type doesn't change automatically, it seems. when i create an .exe, i have to change to gamepad manually. any idea why it is how it is?

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Enable Joystick
« Reply #10 on: 2007-11-17, 09:30:23 AM »
I'm not sure what you mean.  Does it accept both types of input?  When did you check to see if it's changed?  The "Options" form will show that it's a keyboard player, because the EitherInputPlayer class inherits from the KeyboardPlayer, but it also implements code to interpret input from a controller.  The first time the game checks for input (with something like MapPlayerToInputs) and gets a result (some button is pressed) it will use that type of controller from then on.  Or it should anyway.

Please elaborate on the situation.
Edward Dassmesser

Tanja

  • Clever
  • Fanatic
  • ***
  • Posts: 606
    • View Profile
Re: Enable Joystick
« Reply #11 on: 2007-11-17, 10:31:45 AM »
the game doesn't react to gamepad inputs, unless i change the input type to game controller. ( in the compiled game)
apropos, i have the problem after i changed to game controller, i can't switch back to keyboard. you see why when you look at the attachment.

in debug mode the game doesn't react to my gamepad at all. i could upload my game so can take a look into it.

durnurd

  • Lead Lemming
  • Expert
  • Fanatic
  • *****
  • Posts: 1234
  • Games completed so far: 0
    • MSN Messenger - durnurd@hotmail.com
    • View Profile
    • Find My Ed
Re: Enable Joystick
« Reply #12 on: 2007-11-17, 04:36:09 PM »
Well, my main problem with testing is that I don't have a game controller to test with.  Although that does look like a possible bug with the form design.
Edward Dassmesser

Tanja

  • Clever
  • Fanatic
  • ***
  • Posts: 606
    • View Profile
Re: Enable Joystick
« Reply #13 on: 2007-11-18, 04:42:46 AM »
Well, my main problem with testing is that I don't have a game controller to test with.

well.... f***. ok, options will do it. (change to game controller).
with that window thing, maybe could bluemonkmn say something about that?

bluemonkmn

  • SGDK Author
  • Administrator
  • Fanatic
  • *****
  • Posts: 2761
    • ICQ Messenger - 2678251
    • MSN Messenger - BlueMonkMN@gmail.com
    • View Profile
    • http://sgdk2.sf.net/
    • Email
Re: Enable Joystick
« Reply #14 on: 2007-11-18, 08:21:59 AM »
The problem with the sizing of the controller options dialog was fixed after the beta was released.  You could fix it in your project pretty easily too:
  • Open Controls.cs from the SourceCode folder in your project.
  • Search for the first occurrence of "ClientSize".  It should occur after a line that says "cboPlayer.Hide".
  • At the end of the ClientSize line there is a number "185".  Change it to 270.

That's it!  Was that the only problem left relating to controllers, or was something else not working?

Hopefully I'll release a new beta version soon with a number of fixes.
« Last Edit: 2007-11-18, 08:25:25 AM by bluemonkmn »