205 lines
7.1 KiB
Python
205 lines
7.1 KiB
Python
from time import time as get_secs
|
|
|
|
from pygame import joystick as joy
|
|
from pygame.key import get_pressed
|
|
from pygame.locals import *
|
|
|
|
from GameChild import *
|
|
|
|
class Input(GameChild):
|
|
|
|
def __init__(self, game):
|
|
GameChild.__init__(self, game)
|
|
self.last_mouse_down_left = None
|
|
self.joystick = Joystick()
|
|
self.delegate = self.get_delegate()
|
|
self.load_configuration()
|
|
self.set_any_press_ignore_list()
|
|
self.unsuppress()
|
|
self.subscribe_to_events()
|
|
self.build_key_map()
|
|
self.build_joy_button_map()
|
|
|
|
def load_configuration(self):
|
|
self.release_suffix = self.get_configuration("input", "release-suffix")
|
|
self.key_commands = self.get_configuration().items("keys")
|
|
self.double_click_time_limit = self.get_configuration(
|
|
"mouse", "double-click-time-limit")
|
|
|
|
def set_any_press_ignore_list(self):
|
|
self.any_press_ignored = set(["capture-screen", "toggle-fullscreen",
|
|
"reset-game", "record-video", "quit",
|
|
"mute", "toggle-interpolator"])
|
|
self.any_press_ignored_keys = set()
|
|
|
|
def unsuppress(self):
|
|
self.suppressed = False
|
|
|
|
def subscribe_to_events(self):
|
|
self.subscribe(self.translate_key, KEYDOWN)
|
|
self.subscribe(self.translate_key, KEYUP)
|
|
self.subscribe(self.translate_joy_button, JOYBUTTONDOWN)
|
|
self.subscribe(self.translate_joy_button, JOYBUTTONUP)
|
|
self.subscribe(self.translate_axis_motion, JOYAXISMOTION)
|
|
self.subscribe(self.translate_mouse_input, MOUSEBUTTONDOWN)
|
|
self.subscribe(self.translate_mouse_input, MOUSEBUTTONUP)
|
|
|
|
def build_key_map(self):
|
|
key_map = {}
|
|
for command, keys in self.key_commands:
|
|
key_map[command] = []
|
|
if type(keys) == str:
|
|
keys = [keys]
|
|
for key in keys:
|
|
key_map[command].append(globals()[key])
|
|
self.key_map = key_map
|
|
|
|
def build_joy_button_map(self):
|
|
self.joy_button_map = self.get_configuration("joy")
|
|
|
|
def suppress(self):
|
|
self.suppressed = True
|
|
|
|
def translate_key(self, event):
|
|
if not self.suppressed:
|
|
cancel = event.type == KEYUP
|
|
posted = None
|
|
key = event.key
|
|
for cmd, keys in self.key_map.iteritems():
|
|
if key in keys:
|
|
self.post_command(cmd, cancel=cancel)
|
|
posted = cmd
|
|
if (not posted or posted not in self.any_press_ignored) and \
|
|
key not in self.any_press_ignored_keys:
|
|
self.post_any_command(key, cancel)
|
|
|
|
def post_command(self, cmd, **attributes):
|
|
self.delegate.post(cmd, **attributes)
|
|
|
|
def post_any_command(self, id, cancel=False):
|
|
self.post_command("any", id=id, cancel=cancel)
|
|
|
|
def translate_joy_button(self, event):
|
|
if not self.suppressed:
|
|
cancel = event.type == JOYBUTTONUP
|
|
posted = None
|
|
for command, button in self.joy_button_map.iteritems():
|
|
if button == event.button:
|
|
self.post_command(command, cancel=cancel)
|
|
posted = command
|
|
if not posted or posted not in self.any_press_ignored:
|
|
self.post_any_command(event.button, cancel)
|
|
|
|
def translate_axis_motion(self, event):
|
|
if not self.suppressed:
|
|
axis = event.axis
|
|
value = event.value
|
|
if not value:
|
|
for command in "up", "right", "down", "left":
|
|
self.post_command(command, cancel=True)
|
|
if command not in self.any_press_ignored:
|
|
self.post_any_command(command, True)
|
|
else:
|
|
if axis == 1:
|
|
if value < 0:
|
|
command = "up"
|
|
elif value > 0:
|
|
command = "down"
|
|
else:
|
|
if value > 0:
|
|
command = "right"
|
|
elif value < 0:
|
|
command = "left"
|
|
self.post_command(command)
|
|
if command not in self.any_press_ignored:
|
|
self.post_any_command(command)
|
|
|
|
def is_command_active(self, command):
|
|
if not self.suppressed:
|
|
if self.is_key_pressed(command):
|
|
return True
|
|
joystick = self.joystick
|
|
joy_map = self.joy_button_map
|
|
if command in joy_map and joystick.get_button(joy_map[command]):
|
|
return True
|
|
if command == "up":
|
|
return joystick.is_direction_pressed(Joystick.up)
|
|
elif command == "right":
|
|
return joystick.is_direction_pressed(Joystick.right)
|
|
elif command == "down":
|
|
return joystick.is_direction_pressed(Joystick.down)
|
|
elif command == "left":
|
|
return joystick.is_direction_pressed(Joystick.left)
|
|
|
|
def is_key_pressed(self, command):
|
|
poll = get_pressed()
|
|
for key in self.key_map[command]:
|
|
if poll[key]:
|
|
return True
|
|
|
|
def translate_mouse_input(self, event):
|
|
button = event.button
|
|
pos = event.pos
|
|
post = self.post_command
|
|
if event.type == MOUSEBUTTONDOWN:
|
|
if button == 1:
|
|
last = self.last_mouse_down_left
|
|
if last:
|
|
limit = self.double_click_time_limit
|
|
if get_secs() - last < limit:
|
|
post("mouse-double-click-left", pos=pos)
|
|
last = get_secs()
|
|
self.last_mouse_down_left = last
|
|
|
|
def get_axes(self):
|
|
axes = {}
|
|
for direction in "up", "right", "down", "left":
|
|
axes[direction] = self.is_command_active(direction)
|
|
return axes
|
|
|
|
def register_any_press_ignore(self, *args, **attributes):
|
|
self.any_press_ignored.update(args)
|
|
self.any_press_ignored_keys.update(self.extract_keys(attributes))
|
|
|
|
def extract_keys(self, attributes):
|
|
keys = []
|
|
if "keys" in attributes:
|
|
keys = attributes["keys"]
|
|
if type(keys) == int:
|
|
keys = [keys]
|
|
return keys
|
|
|
|
def unregister_any_press_ignore(self, *args, **attributes):
|
|
self.any_press_ignored.difference_update(args)
|
|
self.any_press_ignored_keys.difference_update(
|
|
self.extract_keys(attributes))
|
|
|
|
|
|
class Joystick:
|
|
|
|
(up, right, down, left) = range(4)
|
|
|
|
def __init__(self):
|
|
js = None
|
|
if joy.get_count() > 0:
|
|
js = joy.Joystick(0)
|
|
js.init()
|
|
self.js = js
|
|
|
|
def is_direction_pressed(self, direction):
|
|
js = self.js
|
|
if not js or direction > 4:
|
|
return False
|
|
if direction == 0:
|
|
return js.get_axis(1) < 0
|
|
elif direction == 1:
|
|
return js.get_axis(0) > 0
|
|
elif direction == 2:
|
|
return js.get_axis(1) > 0
|
|
elif direction == 3:
|
|
return js.get_axis(0) < 0
|
|
|
|
def get_button(self, id):
|
|
if self.js:
|
|
return self.js.get_button(id)
|