Module Input
[hide private]
[frames] | no frames]

Source Code for Module Input

  1  ##################################################################### 
  2  # -*- coding: iso-8859-1 -*-                                        # 
  3  #                                                                   # 
  4  # Frets on Fire                                                     # 
  5  # Copyright (C) 2006 Sami Kyöstilä                                  # 
  6  #                                                                   # 
  7  # This program is free software; you can redistribute it and/or     # 
  8  # modify it under the terms of the GNU General Public License       # 
  9  # as published by the Free Software Foundation; either version 2    # 
 10  # of the License, or (at your option) any later version.            # 
 11  #                                                                   # 
 12  # This program is distributed in the hope that it will be useful,   # 
 13  # but WITHOUT ANY WARRANTY; without even the implied warranty of    # 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     # 
 15  # GNU General Public License for more details.                      # 
 16  #                                                                   # 
 17  # You should have received a copy of the GNU General Public License # 
 18  # along with this program; if not, write to the Free Software       # 
 19  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,        # 
 20  # MA  02110-1301, USA.                                              # 
 21  ##################################################################### 
 22   
 23  import pygame 
 24  import Log 
 25  import Audio 
 26   
 27  from Task import Task 
 28  from Player import Controls 
 29   
30 -class KeyListener:
31 - def keyPressed(self, key, unicode):
32 pass
33
34 - def keyReleased(self, key):
35 pass
36
37 -class MouseListener:
38 - def mouseButtonPressed(self, button, pos):
39 pass
40
41 - def mouseButtonReleased(self, button, pos):
42 pass
43
44 - def mouseMoved(self, pos, rel):
45 pass
46
47 -class SystemEventListener:
48 - def screenResized(self, size):
49 pass
50
51 - def restartRequested(self):
52 pass
53
54 - def musicFinished(self):
55 pass
56
57 - def quit(self):
58 pass
59 60 MusicFinished = pygame.USEREVENT 61 62 try: 63 reversed 64 except:
65 - def reversed(seq):
66 seq = seq[:] 67 seq.reverse() 68 return seq
69
70 -class Input(Task):
71 - def __init__(self):
72 Task.__init__(self) 73 self.mouse = pygame.mouse 74 self.mouseListeners = [] 75 self.keyListeners = [] 76 self.systemListeners = [] 77 self.priorityKeyListeners = [] 78 self.controls = Controls() 79 self.disableKeyRepeat() 80 81 # Initialize joysticks 82 pygame.joystick.init() 83 self.joystickAxes = {} 84 self.joystickHats = {} 85 86 self.joysticks = [pygame.joystick.Joystick(id) for id in range(pygame.joystick.get_count())] 87 for j in self.joysticks: 88 j.init() 89 self.joystickAxes[j.get_id()] = [0] * j.get_numaxes() 90 self.joystickHats[j.get_id()] = [(0, 0)] * j.get_numhats() 91 Log.debug("%d joysticks found." % (len(self.joysticks))) 92 93 # Enable music events 94 Audio.Music.setEndEvent(MusicFinished) 95 96 # Custom key names 97 self.getSystemKeyName = pygame.key.name 98 pygame.key.name = self.getKeyName
99
100 - def reloadControls(self):
101 self.controls = Controls()
102
103 - def disableKeyRepeat(self):
104 pygame.key.set_repeat(0, 0)
105
106 - def enableKeyRepeat(self):
107 pygame.key.set_repeat(300, 30)
108
109 - def addMouseListener(self, listener):
110 if not listener in self.mouseListeners: 111 self.mouseListeners.append(listener)
112
113 - def removeMouseListener(self, listener):
114 if listener in self.mouseListeners: 115 self.mouseListeners.remove(listener)
116
117 - def addKeyListener(self, listener, priority = False):
118 if priority: 119 if not listener in self.priorityKeyListeners: 120 self.priorityKeyListeners.append(listener) 121 else: 122 if not listener in self.keyListeners: 123 self.keyListeners.append(listener)
124
125 - def removeKeyListener(self, listener):
126 if listener in self.keyListeners: 127 self.keyListeners.remove(listener) 128 if listener in self.priorityKeyListeners: 129 self.priorityKeyListeners.remove(listener)
130
131 - def addSystemEventListener(self, listener):
132 if not listener in self.systemListeners: 133 self.systemListeners.append(listener)
134
135 - def removeSystemEventListener(self, listener):
136 if listener in self.systemListeners: 137 self.systemListeners.remove(listener)
138
139 - def broadcastEvent(self, listeners, function, *args):
140 for l in reversed(listeners): 141 if getattr(l, function)(*args): 142 return True 143 else: 144 return False
145
146 - def broadcastSystemEvent(self, name, *args):
147 return self.broadcastEvent(self.systemListeners, name, *args)
148
149 - def encodeJoystickButton(self, joystick, button):
150 return 0x10000 + (joystick << 8) + button
151
152 - def encodeJoystickAxis(self, joystick, axis, end):
153 return 0x20000 + (joystick << 8) + (axis << 4) + end
154
155 - def encodeJoystickHat(self, joystick, hat, pos):
156 v = int((pos[1] + 1) * 3 + (pos[0] + 1)) 157 return 0x30000 + (joystick << 8) + (hat << 4) + v
158
159 - def decodeJoystickButton(self, id):
160 id -= 0x10000 161 return (id >> 8, id & 0xff)
162
163 - def decodeJoystickAxis(self, id):
164 id -= 0x20000 165 return (id >> 8, (id >> 4) & 0xf, id & 0xf)
166
167 - def decodeJoystickHat(self, id):
168 id -= 0x30000 169 v = id & 0xf 170 x, y = (v % 3) - 1, (v / 3) - 1 171 return (id >> 8, (id >> 4) & 0xf, (x, y))
172
173 - def getKeyName(self, id):
174 if id >= 0x30000: 175 joy, axis, pos = self.decodeJoystickHat(id) 176 return "Joy #%d, hat %d %s" % (joy + 1, axis, pos) 177 elif id >= 0x20000: 178 joy, axis, end = self.decodeJoystickAxis(id) 179 return "Joy #%d, axis %d %s" % (joy + 1, axis, (end == 1) and "high" or "low") 180 elif id >= 0x10000: 181 joy, but = self.decodeJoystickButton(id) 182 return "Joy #%d, %s" % (joy + 1, chr(ord('A') + but)) 183 return self.getSystemKeyName(id)
184
185 - def run(self, ticks):
186 pygame.event.pump() 187 for event in pygame.event.get(): 188 if event.type == pygame.KEYDOWN: 189 if not self.broadcastEvent(self.priorityKeyListeners, "keyPressed", event.key, event.unicode): 190 self.broadcastEvent(self.keyListeners, "keyPressed", event.key, event.unicode) 191 elif event.type == pygame.KEYUP: 192 if not self.broadcastEvent(self.priorityKeyListeners, "keyReleased", event.key): 193 self.broadcastEvent(self.keyListeners, "keyReleased", event.key) 194 elif event.type == pygame.MOUSEMOTION: 195 self.broadcastEvent(self.mouseListeners, "mouseMoved", event.pos, event.rel) 196 elif event.type == pygame.MOUSEBUTTONDOWN: 197 self.broadcastEvent(self.mouseListeners, "mouseButtonPressed", event.button, event.pos) 198 elif event.type == pygame.MOUSEBUTTONUP: 199 self.broadcastEvent(self.mouseListeners, "mouseButtonReleased", event.button, event.pos) 200 elif event.type == pygame.VIDEORESIZE: 201 self.broadcastEvent(self.systemListeners, "screenResized", event.size) 202 elif event.type == pygame.QUIT: 203 self.broadcastEvent(self.systemListeners, "quit") 204 elif event.type == MusicFinished: 205 self.broadcastEvent(self.systemListeners, "musicFinished") 206 elif event.type == pygame.JOYBUTTONDOWN: # joystick buttons masquerade as keyboard events 207 id = self.encodeJoystickButton(event.joy, event.button) 208 if not self.broadcastEvent(self.priorityKeyListeners, "keyPressed", id, u'\x00'): 209 self.broadcastEvent(self.keyListeners, "keyPressed", id, u'\x00') 210 elif event.type == pygame.JOYBUTTONUP: 211 id = self.encodeJoystickButton(event.joy, event.button) 212 if not self.broadcastEvent(self.priorityKeyListeners, "keyReleased", id): 213 self.broadcastEvent(self.keyListeners, "keyReleased", id) 214 elif event.type == pygame.JOYAXISMOTION: 215 try: 216 threshold = .8 217 state = self.joystickAxes[event.joy][event.axis] 218 keyEvent = None 219 220 if event.value > threshold and state != 1: 221 self.joystickAxes[event.joy][event.axis] = 1 222 keyEvent = "keyPressed" 223 args = (self.encodeJoystickAxis(event.joy, event.axis, 1), u'\x00') 224 state = 1 225 elif event.value < -threshold and state != -1: 226 keyEvent = "keyPressed" 227 args = (self.encodeJoystickAxis(event.joy, event.axis, 0), u'\x00') 228 state = -1 229 elif state != 0: 230 keyEvent = "keyReleased" 231 args = (self.encodeJoystickAxis(event.joy, event.axis, (state == 1) and 1 or 0), ) 232 state = 0 233 234 if keyEvent: 235 self.joystickAxes[event.joy][event.axis] = state 236 if not self.broadcastEvent(self.priorityKeyListeners, keyEvent, *args): 237 self.broadcastEvent(self.keyListeners, keyEvent, *args) 238 except KeyError: 239 pass 240 elif event.type == pygame.JOYHATMOTION: 241 try: 242 state = self.joystickHats[event.joy][event.hat] 243 keyEvent = None 244 245 if event.value != (0, 0) and state == (0, 0): 246 self.joystickHats[event.joy][event.hat] = event.value 247 keyEvent = "keyPressed" 248 args = (self.encodeJoystickHat(event.joy, event.hat, event.value), u'\x00') 249 state = event.value 250 else: 251 keyEvent = "keyReleased" 252 args = (self.encodeJoystickHat(event.joy, event.hat, state), ) 253 state = (0, 0) 254 255 if keyEvent: 256 self.joystickHats[event.joy][event.hat] = state 257 if not self.broadcastEvent(self.priorityKeyListeners, keyEvent, *args): 258 self.broadcastEvent(self.keyListeners, keyEvent, *args) 259 except KeyError: 260 pass
261