6

I'm using a pygame.joystick.Joystick object and want to be able to print a message asking the user to reconnect a usb joystick once it's been unplugged.

right now I have (roughly):

js = pygame.joystick.Joystick(0)
#... some game code and stuff
pygame.joystick.quit()
pygame.joystick.init()
while pygame.joystick.get_count() == 0:
    print 'please reconnect joystick'
    pygame.joystick.quit()
    pygame.joystick.init()

js = pygame.joystick.Joystick(0)
js.init()

but it doesn't reconnect properly, idk what exactly it's doing, but it's definitely wrong. Any direction on this would be helpful

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
  • Please don't tell me you are doing this because your joystick is half broken. – LtWorf Apr 04 '13 at 05:28
  • @LtWorf no haha, I'm making something fully controlled by a joystick so it would be useful for the program to be able to continue when someone unplugs it temporarily. – Ryan Haining Apr 04 '13 at 05:40
  • You are out of luck with here I think, since pygame is based on SDL, and SDL does not support dynamically connecting and disconnecting joysticks. But I heard rumors future versions of SDL should support this... – sloth Apr 04 '13 at 09:17
  • @RyanHaining does my answer work?! – Noelkd May 15 '13 at 22:13
  • @Noelkd I haven't gotten back to my system in the last couple days (finals week) but I'm gonna try it soon. I think I tried something like this already and doing the quit() followed by init() on the joystick module caused some undesirable effects – Ryan Haining May 16 '13 at 03:50
  • @RyanHaining good luck with your finals, when you get back to this tell us how it goes. – Noelkd May 16 '13 at 17:45

3 Answers3

3

Here is pygame events for device add and remove.

joystick = pygame.joystick.Joystick(0)

while True:
    event = pygame.event.wait()

    if event.type == pygame.JOYDEVICEREMOVED:
        joystick.quit()

    elif event.type == pygame.JOYDEVICEADDED:
        joystick.init()

https://www.pygame.org/docs/ref/joystick.html

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
Rahul
  • 71
  • 3
2

Had to fire up the old xbox pad but I made a function that checks for disconnections and seems to work ok:

discon = False
def check_pad():
    global discon
    pygame.joystick.quit()
    pygame.joystick.init()
    joystick_count = pygame.joystick.get_count()
    for i in range(joystick_count):
        joystick = pygame.joystick.Joystick(i)
        joystick.init()
    if not joystick_count: 
        if not discon:
           print "reconnect you meat bag"
           discon = True
        clock.tick(20)
        check_pad()
    else:
        discon = False

So if you run this function in your main loop it'll just keep running itself until it gets a joystick connection back. It works for the little test code I found:

http://programarcadegames.com/python_examples/show_file.php?file=joystick_calls.py

Also found:

http://demolishun.net/?p=21

Where I stole the idea from, he didn't have any code examples which was lame

And lastly, because you should always check the docs:

http://www.pygame.org/docs/ref/joystick.html

Noelkd
  • 7,686
  • 2
  • 29
  • 43
  • I had something like this at first, but it doesn't work because the it loses track of the gamepads actions with all the `quit`ing and `init`ing. This works initially to check if a controller is plugged in at all, but not to effectively check while running – Ryan Haining May 20 '13 at 17:51
  • works in my code while running, by that I mean in the example linked in the comment I can discon and reconn and all the buttons and do-dads on my xbox pad work on the displays? What's happing with yours? some buttons not working after the restart or just weird behaviour? (how did you finals go?) – Noelkd May 20 '13 at 17:55
  • 1
    it might just be the way I have everything else set up, or my controller. I get 0's on my axes and unpressed for all buttons over and over. finals went good btw haha thanks – Ryan Haining May 20 '13 at 18:01
  • I'm going to have another look at this then when I get some time, you got the code your working on on github? – Noelkd May 20 '13 at 18:05
2

I managed to get mine working with Noelkd's suggestion, but I had a similar issue described by Ryan Haining

I had something like this at first, but it doesn't work because the it loses track of the gamepads actions with all the quiting and initing. This works initially to check if a controller is plugged in at all, but not to effectively check while running

I had this issue too. I think you are correct, calling quit too often doesn't give the pad enough time to re-initialise - at least on my computer. I found that if you limit the calls to every second, it works.

It can cause the player input to temporarily disconnect though, so any calls on a joystick won't work.

It's better to only run this code if you detect that there has been no input for a while (say 5 seconds or something). This way you won't quit while a user is actually using the device

import pygame
import time

INACTIVITY_RECONNECT_TIME = 5
RECONNECT_TIMEOUT = 1

class ControllerInput():
  def __init__(self):
    pygame.joystick.init()
    self.lastTime = 0
    self.lastActive = 0

  def getButtons(self, joystickId):
    joystick = pygame.joystick.Joystick(joystickId)
    joystick.init()

    buttons = {}

    for i in range(joystick.get_numbuttons()):
      buttons[i] = joystick.get_button(i)
      if buttons[i]:
        self.lastActive = time.time()

    return buttons

  def hasController(self):
    now = time.time()
    if now - self.lastActive > INACTIVITY_RECONNECT_TIME and now - self.lastTime > RECONNECT_TIMEOUT:
      self.lastTime = now
      pygame.joystick.quit()
      pygame.joystick.init()

    return pygame.joystick.get_count() > 0

Usage

# ... some constructor
controller = ControllerInput()

# ... game loop
if not controller.hasController():
  # handle disconnect
  print('reconnect')
  return

buttons = controller.getButtons(0)

if buttons[0]:
  # buttons[0] was pressed!
AlexMorley-Finch
  • 6,785
  • 15
  • 68
  • 103