""" A JoyTracker is a mixin that tracks the current state of the gamepad. We track the gamepad in this way: - Handle KeyDown and KeyUp events to set KeyState, a dictionary mapping keycodes to true or false - On a timer, check the joystick state - On a timer, use the current joystick and keycode states to set the gamepad state Most windows are JoyTracker windows, so that they can respond to gamepad input. Typically, dialogs are closed by button 1 or canceled by button 2. ButtonState is the effective gamepad state. RawButtonState is the raw state of what's pressed. Buttons that are pressed when we get focus are not considered pressed until they are released, then pressed again. """ import wx import Global import Config import Keystroke from Global import Log, LogException class JoyTracker: def __init__(self, *args, **kw): self.KeyState = {} self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus) self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) self.HasFocus = 0 self.FocusGamepadState = [0] * Config.KeyConfig.KeyCount # self.GetRawGamepad() self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_KEY_UP, self.OnKeyUp) def CheckJoystick(self): try: self.Joystick = wx.Joystick() except: self.Joystick = None if not self.Joystick: self.JoystickButtonState = 0 self.JoystickX = 32767 self.JoystickY = 32767 return self.JoystickButtonState = self.Joystick.GetButtonState() # Check for joystick directions: self.JoystickX = self.Joystick.GetPosition().x self.JoystickY = self.Joystick.GetPosition().y def SetManualFocus(self): #Log("MSF") #Log(""%self) self.HasFocus = 1 def KillManualFocus(self): #Log("MKF") #Log(""%self) self.HasFocus = 0 def OnSetFocus(self, Event): #Log(""%self) self.FocusGamepadState = self.GetRawGamepad() self.HasFocus = 1 Event.Skip() def OnKillFocus(self, Event): #Log(""%self) self.HasFocus = 0 Event.Skip() def OnKeyUp(self, Event): KeyCode = Event.GetKeyCode() self.KeyState[KeyCode] = 0 #self.CheckDoors() def OnKeyDown(self, Event): KeyCode = Event.GetKeyCode() self.KeyState[KeyCode] = 1 def ResetInputs(self): self.ButtonState = [0] * Config.KeyConfig.KeyCount self.KeyState = {} def GetRawGamepad(self): ButtonState = [0] * Config.KeyConfig.KeyCount self.CheckJoystick() for ButtonIndex in range(len(ButtonState)): ButtonState[ButtonIndex] = 0 KeyCode = Global.Config.KeyConfig[ButtonIndex] if KeyCode == Keystroke.JoystickButtons.Up: ButtonState[ButtonIndex] = (self.JoystickY == 0) elif KeyCode == Keystroke.JoystickButtons.Down: ButtonState[ButtonIndex] = (self.JoystickY == 65535) elif KeyCode == Keystroke.JoystickButtons.Left: ButtonState[ButtonIndex] = (self.JoystickX == 0) elif KeyCode == Keystroke.JoystickButtons.Right: ButtonState[ButtonIndex] = (self.JoystickX == 65535) elif KeyCode in range(Keystroke.JoystickButtons.Button1, Keystroke.JoystickButtons.Button8 + 1): JoyButtonIndex = KeyCode - Keystroke.JoystickButtons.Button1 ButtonState[ButtonIndex] = (self.JoystickButtonState >> JoyButtonIndex) & 0x1 else: # Keyboard input: ButtonState[ButtonIndex] = self.KeyState.get(KeyCode, 0) return ButtonState def SetGamepad(self): """ Update self.ButtonState. Usually called on a timer. """ PressedButtonState = self.GetRawGamepad() ButtonState = [0] * Config.KeyConfig.KeyCount for ButtonIndex in range(Config.KeyConfig.KeyCount): if self.FocusGamepadState[ButtonIndex]: if not PressedButtonState[ButtonIndex]: self.FocusGamepadState[ButtonIndex] = 0 else: if PressedButtonState[ButtonIndex]: ButtonState[ButtonIndex] = 1 #Log("Pressed: %s"%PressedButtonState) #Log(" Buttons: %s"%ButtonState) self.ButtonState = ButtonState