Teensy: Keyboard vs Joystick Decision

Got an idea for a project? Found a cool project you want to share? Post it here!
yves1984
Posts: 85
Joined: Thu May 05, 2016 7:55 am
Location: Zürich (Switzerland)
Has thanked: 13 times
Been thanked: 3 times
Contact:

Re: Teensy: Keyboard vs Joystick Decision

Post by yves1984 » Wed May 18, 2016 9:25 am

prerunnerseth wrote:I'm using the GPIO pins and the retro game c-code modified for my gpio pin choices. Works awesome and accepts more than one input at a time.
i try the same one to use the GPIO from Pi0.
i already do a wiring schema for the pcb to Pi0 ;)

but don't know to config the GPIO, but hope i found some "how to" on the internet :D

prerunnerseth
Posts: 279
Joined: Fri May 06, 2016 5:36 pm
Has thanked: 16 times
Been thanked: 229 times

Re: Teensy: Keyboard vs Joystick Decision

Post by prerunnerseth » Wed May 18, 2016 10:29 am

yves1984 wrote:
prerunnerseth wrote:I'm using the GPIO pins and the retro game c-code modified for my gpio pin choices. Works awesome and accepts more than one input at a time.
i try the same one to use the GPIO from Pi0.
i already do a wiring schema for the pcb to Pi0 ;)

but don't know to config the GPIO, but hope i found some "how to" on the internet :D
I did a full tutorial in the guides section of this board.

User avatar
crispy_tofu
Posts: 340
Joined: Thu May 05, 2016 1:51 am
Location: Australia
Been thanked: 5 times

Re: Teensy: Keyboard vs Joystick Decision

Post by crispy_tofu » Wed May 18, 2016 6:38 pm

In case anybody seeing this in the future can't find the link, here it is:
http://www.sudomod.com/forum/viewtopic.php?f=22&t=57
:)

User avatar
Robots86
Posts: 268
Joined: Thu May 05, 2016 1:18 am
Location: Birmingham, UK
Has thanked: 39 times
Been thanked: 28 times

Re: Teensy: Keyboard vs Joystick Decision

Post by Robots86 » Mon May 23, 2016 7:21 am

How is everyone getting on programing the teensy. Have you gone with keyboard or gamepad?

User avatar
hencethus
Posts: 27
Joined: Thu May 05, 2016 9:20 am
Been thanked: 4 times

Re: Teensy: Keyboard vs Joystick Decision

Post by hencethus » Tue May 31, 2016 5:39 pm

I posted about this already, in this thread: http://www.sudomod.com/forum/viewtopic. ... =373#p3993

But I went the joystick route for my GBZ. Here's the code I used:

Code: Select all

/* Modified example code from Teensyduino
   You must select Joystick from the "Tools > USB Type" menu
*/

#include <Bounce.h>

// Create Bounce objects for each button. The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
  Bounce GBZ_LEFT = Bounce(0, 10);
  Bounce GBZ_UP = Bounce(1, 10);  // 10 = 10 ms debounce time
  Bounce GBZ_DOWN = Bounce(2, 10);  // which is appropriate for
  Bounce GBZ_RIGHT = Bounce(3, 10);  // most mechanical pushbuttons
  Bounce GBZ_SELECT = Bounce(4, 10);
  Bounce GBZ_START = Bounce(5, 10);
  Bounce GBZ_X = Bounce(6, 10);
  Bounce GBZ_Y = Bounce(7, 10);
  Bounce GBZ_B = Bounce(8, 10);
  Bounce GBZ_A = Bounce(9, 10);
  Bounce GBZ_L = Bounce(10, 10);
  Bounce GBZ_R = Bounce(11, 10);

  const int numButtons = 12;

  uint8_t hatu = 0;
  uint8_t hatr = 0;
  uint8_t hatd = 0;
  uint8_t hatl = 0;

  // ganked this bit from https://gist.github.com/cleure/5820004
  // bitwise operations return 4 possible states of each d-pad axis
  // so that d-pad value can be looked up from 4x4 array
  /*
  
          0
          UP
      315    45
 270 LT   -1   RT 90
      225    135
          DN
          180
  
  */
  int GetHatState() {
    uint8_t x, y;
    const static int16_t dpad_lookup[4][4] = {
      { -1, 270,  90, -1},
      {  0, 315,  45, -1},
      {180, 225, 135, -1},
      { -1,  -1,  -1, -1}
    };
    
    y = hatu | (hatd << 1);
    x = hatl | (hatr << 1);
    
    return dpad_lookup[y][x];
  }

void setup() {
  // Configure the pins for input mode with pullup resistors.
  // The pushbuttons connect from each pin to ground.  When
  // the button is pressed, the pin reads LOW because the button
  // shorts it to ground.  When released, the pin reads HIGH
  // because the pullup resistor connects to +5 volts inside
  // the chip.
  for (int i=0; i<numButtons; i++) {
    pinMode(i, INPUT_PULLUP);
  }
  
  //  Set all axes to defaults
  Joystick.X(512);
  Joystick.Y(512);
  Joystick.Z(512);
  Joystick.Zrotate(512);
  Joystick.sliderLeft(512);
  Joystick.sliderRight(512);
  Joystick.hat(-1);
}

void loop() {
  // Update all the buttons.  There should not be any long
  // delays in loop(), so this runs repetitively at a rate
  // faster than the buttons could be pressed and released.
  GBZ_LEFT.update();   // 0
  GBZ_UP.update();     // 1
  GBZ_DOWN.update();   // 2
  GBZ_RIGHT.update();  // 3
  GBZ_SELECT.update(); // 4
  GBZ_START.update();  // 5
  GBZ_X.update();      // 6
  GBZ_Y.update();      // 7
  GBZ_B.update();      // 8
  GBZ_A.update();      // 9
  GBZ_L.update();      // 10
  GBZ_R.update();      // 11

  // Check each button for "falling" edge.
  // Update the Joystick buttons only upon changes.

  if (GBZ_B.fallingEdge()) {
    Joystick.button(1, 1);
  }
  if (GBZ_A.fallingEdge()) {
    Joystick.button(2, 1);
  }
  if (GBZ_Y.fallingEdge()) {
    Joystick.button(3, 1);
  }
  if (GBZ_X.fallingEdge()) {
    Joystick.button(4, 1);
  }
  if (GBZ_L.fallingEdge()) {
    Joystick.button(5, 1);
  }
  if (GBZ_R.fallingEdge()) {
    Joystick.button(6, 1);
  }
  if (GBZ_SELECT.fallingEdge()) {
    Joystick.button(7, 1);
  }
  if (GBZ_START.fallingEdge()) {
    Joystick.button(8, 1);
  }
  if (GBZ_UP.fallingEdge()) {
    hatu = 1;
    Joystick.hat(GetHatState());
  }
  if (GBZ_RIGHT.fallingEdge()) {
    hatr = 1;
    Joystick.hat(GetHatState());
  }
  if (GBZ_DOWN.fallingEdge()) {
    hatd = 1;
    Joystick.hat(GetHatState());
  }
  if (GBZ_LEFT.fallingEdge()) {
    hatl = 1;
    Joystick.hat(GetHatState());
  }

  // Check each button for "rising" edge
  // Update the Joystick buttons only upon changes.

  if (GBZ_B.risingEdge()) {
    Joystick.button(1, 0);
  }
  if (GBZ_A.risingEdge()) {
    Joystick.button(2, 0);
  }
  if (GBZ_Y.risingEdge()) {
    Joystick.button(3, 0);
  }
  if (GBZ_X.risingEdge()) {
    Joystick.button(4, 0);
  }
  if (GBZ_L.risingEdge()) {
    Joystick.button(5, 0);
  }
  if (GBZ_R.risingEdge()) {
    Joystick.button(6, 0);
  }
  if (GBZ_SELECT.risingEdge()) {
    Joystick.button(7, 0);
  }
  if (GBZ_START.risingEdge()) {
    Joystick.button(8, 0);
  }
  if (GBZ_UP.risingEdge()) {
    hatu = 0;
    Joystick.hat(GetHatState());
  }
  if (GBZ_RIGHT.risingEdge()) {
    hatr = 0;
    Joystick.hat(GetHatState());
  }
  if (GBZ_DOWN.risingEdge()) {
    hatd = 0;
    Joystick.hat(GetHatState());
  }
  if (GBZ_LEFT.risingEdge()) {
    hatl = 0;
    Joystick.hat(GetHatState());
  }
}
One thing that wasn't immediately obvious was that if you don't initialize all the analog axes to their resting states (512), then as soon as any button is input they all go to zero and cause anything expecting analog inputs to glitch out. Also, to get the d-pad working as a hat switch I borrowed some code I found on github which nicely handles all possible combinations of d-pad input.

User avatar
Fleder
Posts: 849
Joined: Thu May 05, 2016 9:04 am
Location: Germany
Has thanked: 183 times
Been thanked: 258 times

Re: Teensy: Keyboard vs Joystick Decision

Post by Fleder » Tue May 31, 2016 11:43 pm

hencethus wrote:I posted about this already, in this thread: http://www.sudomod.com/forum/viewtopic. ... =373#p3993

But I went the joystick route for my GBZ. Here's the code I used:
Hey there, are you familiar with coding for arduino as well?
I am looking for some help on my code.

User avatar
hencethus
Posts: 27
Joined: Thu May 05, 2016 9:20 am
Been thanked: 4 times

Re: Teensy: Keyboard vs Joystick Decision

Post by hencethus » Wed Jun 01, 2016 8:03 am

Fleder wrote:Hey there, are you familiar with coding for arduino as well?
I am looking for some help on my code.
No, sorry :/
This is the first project I've done with the Teensy, and most of the code I used was straight from the example code that's packaged with Teensyduino.

It does look like hopefully most of the work has been done for you though, as I was able to find a library on Github for using Arduino as a game controller: https://github.com/MHeironimus/ArduinoJoystickLibrary

Here's an tutorial that uses that library: http://www.instructables.com/id/Arduino ... rJoystick/

Hope that helps.

User avatar
Robots86
Posts: 268
Joined: Thu May 05, 2016 1:18 am
Location: Birmingham, UK
Has thanked: 39 times
Been thanked: 28 times

Re: Teensy: Keyboard vs Joystick Decision

Post by Robots86 » Wed Jun 01, 2016 8:12 am

hencethus wrote:I posted about this already, in this thread: http://www.sudomod.com/forum/viewtopic. ... =373#p3993

But I went the joystick route for my GBZ. Here's the code I used:

Code: Select all

/* Modified example code from Teensyduino
   You must select Joystick from the "Tools > USB Type" menu
*/

#include <Bounce.h>

// Create Bounce objects for each button. The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
  Bounce GBZ_LEFT = Bounce(0, 10);
  Bounce GBZ_UP = Bounce(1, 10);  // 10 = 10 ms debounce time
  Bounce GBZ_DOWN = Bounce(2, 10);  // which is appropriate for
  Bounce GBZ_RIGHT = Bounce(3, 10);  // most mechanical pushbuttons
  Bounce GBZ_SELECT = Bounce(4, 10);
  Bounce GBZ_START = Bounce(5, 10);
  Bounce GBZ_X = Bounce(6, 10);
  Bounce GBZ_Y = Bounce(7, 10);
  Bounce GBZ_B = Bounce(8, 10);
  Bounce GBZ_A = Bounce(9, 10);
  Bounce GBZ_L = Bounce(10, 10);
  Bounce GBZ_R = Bounce(11, 10);

  const int numButtons = 12;

  uint8_t hatu = 0;
  uint8_t hatr = 0;
  uint8_t hatd = 0;
  uint8_t hatl = 0;

  // ganked this bit from https://gist.github.com/cleure/5820004
  // bitwise operations return 4 possible states of each d-pad axis
  // so that d-pad value can be looked up from 4x4 array
  /*
  
          0
          UP
      315    45
 270 LT   -1   RT 90
      225    135
          DN
          180
  
  */
  int GetHatState() {
    uint8_t x, y;
    const static int16_t dpad_lookup[4][4] = {
      { -1, 270,  90, -1},
      {  0, 315,  45, -1},
      {180, 225, 135, -1},
      { -1,  -1,  -1, -1}
    };
    
    y = hatu | (hatd << 1);
    x = hatl | (hatr << 1);
    
    return dpad_lookup[y][x];
  }

void setup() {
  // Configure the pins for input mode with pullup resistors.
  // The pushbuttons connect from each pin to ground.  When
  // the button is pressed, the pin reads LOW because the button
  // shorts it to ground.  When released, the pin reads HIGH
  // because the pullup resistor connects to +5 volts inside
  // the chip.
  for (int i=0; i<numButtons; i++) {
    pinMode(i, INPUT_PULLUP);
  }
  
  //  Set all axes to defaults
  Joystick.X(512);
  Joystick.Y(512);
  Joystick.Z(512);
  Joystick.Zrotate(512);
  Joystick.sliderLeft(512);
  Joystick.sliderRight(512);
  Joystick.hat(-1);
}

void loop() {
  // Update all the buttons.  There should not be any long
  // delays in loop(), so this runs repetitively at a rate
  // faster than the buttons could be pressed and released.
  GBZ_LEFT.update();   // 0
  GBZ_UP.update();     // 1
  GBZ_DOWN.update();   // 2
  GBZ_RIGHT.update();  // 3
  GBZ_SELECT.update(); // 4
  GBZ_START.update();  // 5
  GBZ_X.update();      // 6
  GBZ_Y.update();      // 7
  GBZ_B.update();      // 8
  GBZ_A.update();      // 9
  GBZ_L.update();      // 10
  GBZ_R.update();      // 11

  // Check each button for "falling" edge.
  // Update the Joystick buttons only upon changes.

  if (GBZ_B.fallingEdge()) {
    Joystick.button(1, 1);
  }
  if (GBZ_A.fallingEdge()) {
    Joystick.button(2, 1);
  }
  if (GBZ_Y.fallingEdge()) {
    Joystick.button(3, 1);
  }
  if (GBZ_X.fallingEdge()) {
    Joystick.button(4, 1);
  }
  if (GBZ_L.fallingEdge()) {
    Joystick.button(5, 1);
  }
  if (GBZ_R.fallingEdge()) {
    Joystick.button(6, 1);
  }
  if (GBZ_SELECT.fallingEdge()) {
    Joystick.button(7, 1);
  }
  if (GBZ_START.fallingEdge()) {
    Joystick.button(8, 1);
  }
  if (GBZ_UP.fallingEdge()) {
    hatu = 1;
    Joystick.hat(GetHatState());
  }
  if (GBZ_RIGHT.fallingEdge()) {
    hatr = 1;
    Joystick.hat(GetHatState());
  }
  if (GBZ_DOWN.fallingEdge()) {
    hatd = 1;
    Joystick.hat(GetHatState());
  }
  if (GBZ_LEFT.fallingEdge()) {
    hatl = 1;
    Joystick.hat(GetHatState());
  }

  // Check each button for "rising" edge
  // Update the Joystick buttons only upon changes.

  if (GBZ_B.risingEdge()) {
    Joystick.button(1, 0);
  }
  if (GBZ_A.risingEdge()) {
    Joystick.button(2, 0);
  }
  if (GBZ_Y.risingEdge()) {
    Joystick.button(3, 0);
  }
  if (GBZ_X.risingEdge()) {
    Joystick.button(4, 0);
  }
  if (GBZ_L.risingEdge()) {
    Joystick.button(5, 0);
  }
  if (GBZ_R.risingEdge()) {
    Joystick.button(6, 0);
  }
  if (GBZ_SELECT.risingEdge()) {
    Joystick.button(7, 0);
  }
  if (GBZ_START.risingEdge()) {
    Joystick.button(8, 0);
  }
  if (GBZ_UP.risingEdge()) {
    hatu = 0;
    Joystick.hat(GetHatState());
  }
  if (GBZ_RIGHT.risingEdge()) {
    hatr = 0;
    Joystick.hat(GetHatState());
  }
  if (GBZ_DOWN.risingEdge()) {
    hatd = 0;
    Joystick.hat(GetHatState());
  }
  if (GBZ_LEFT.risingEdge()) {
    hatl = 0;
    Joystick.hat(GetHatState());
  }
}
One thing that wasn't immediately obvious was that if you don't initialize all the analog axes to their resting states (512), then as soon as any button is input they all go to zero and cause anything expecting analog inputs to glitch out. Also, to get the d-pad working as a hat switch I borrowed some code I found on github which nicely handles all possible combinations of d-pad input.

Thanks hencethus. Do you know if this code will sort the issue im having with fba not recognising the dpad? I setup as a button joystick which works fine on the majority of emulators but im not having any luck with fba...

User avatar
Fleder
Posts: 849
Joined: Thu May 05, 2016 9:04 am
Location: Germany
Has thanked: 183 times
Been thanked: 258 times

Re: Teensy: Keyboard vs Joystick Decision

Post by Fleder » Wed Jun 01, 2016 8:19 am

hencethus wrote:No, sorry :/
This is the first project I've done with the Teensy, and most of the code I used was straight from the example code that's packaged with Teensyduino.

It does look like hopefully most of the work has been done for you though, as I was able to find a library on Github for using Arduino as a game controller: https://github.com/MHeironimus/ArduinoJoystickLibrary

Here's an tutorial that uses that library: http://www.instructables.com/id/Arduino ... rJoystick/

Hope that helps.
Thank you, this might help. I will test it as soon as i get home.
I really tried to do it myself and get help in the arduino forum, but they are neither really helpful nor patient. :/

User avatar
hencethus
Posts: 27
Joined: Thu May 05, 2016 9:20 am
Been thanked: 4 times

Re: Teensy: Keyboard vs Joystick Decision

Post by hencethus » Wed Jun 01, 2016 4:06 pm

Robots86 wrote:Thanks hencethus. Do you know if this code will sort the issue im having with fba not recognising the dpad? I setup as a button joystick which works fine on the majority of emulators but im not having any luck with fba...
I just tried the CPS1 game 1941: Counter Attack on FBA and it works.

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest