summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Environment.py13
-rw-r--r--lib/SendKey.py96
-rw-r--r--main.py14
3 files changed, 117 insertions, 6 deletions
diff --git a/lib/Environment.py b/lib/Environment.py
index 8ef2320..86f1e47 100644
--- a/lib/Environment.py
+++ b/lib/Environment.py
@@ -9,6 +9,7 @@ from lib.EventHandler import JoyHandler, KeyHandler
9from lib.Keyboards import ControllerKeyboard, Sectors, ShiftPairs 9from lib.Keyboards import ControllerKeyboard, Sectors, ShiftPairs
10from lib.HeadsUpDisplay import HUD as HeadsUpDisplay, Locations as HudLocs 10from lib.HeadsUpDisplay import HUD as HeadsUpDisplay, Locations as HudLocs
11from lib.xinput import XInputJoystick 11from lib.xinput import XInputJoystick
12from lib.SendKey import TypeKey
12 13
13class EnvironmentController(object): 14class EnvironmentController(object):
14 def __init__(self, clock=None): 15 def __init__(self, clock=None):
@@ -51,6 +52,10 @@ class EnvironmentController(object):
51 self.take_screenshot = False 52 self.take_screenshot = False
52 53
53 #self.controller.handler.dump_bindings() 54 #self.controller.handler.dump_bindings()
55 self.focused = True
56
57 def set_focus(self, focus=True):
58 self.focused = focus
54 59
55 def update(self): 60 def update(self):
56 #self.current_handler.update() 61 #self.current_handler.update()
@@ -89,8 +94,6 @@ class EnvironmentController(object):
89 ## Simple deadzone stuff. Less accuracy though. 94 ## Simple deadzone stuff. Less accuracy though.
90 value = int((value * 10) / 10) 95 value = int((value * 10) / 10)
91 96
92
93
94 def type_key(self, key): 97 def type_key(self, key):
95 key = key.lower() 98 key = key.lower()
96 if len(key) == 1: 99 if len(key) == 1:
@@ -100,6 +103,12 @@ class EnvironmentController(object):
100 else: 103 else:
101 key = key.upper() 104 key = key.upper()
102 self.TxtObject.add_text(key) 105 self.TxtObject.add_text(key)
106
107 ## DO NOT send Windows the key if the pygame window is focused. It
108 ## will keep sending the same character over and over again until
109 ## it crashes.
110 if not self.focused:
111 TypeKey(key)
103 else: 112 else:
104 if key == 'backspace': 113 if key == 'backspace':
105 self.TxtObject.remove_text(1) 114 self.TxtObject.remove_text(1)
diff --git a/lib/SendKey.py b/lib/SendKey.py
new file mode 100644
index 0000000..ca76864
--- /dev/null
+++ b/lib/SendKey.py
@@ -0,0 +1,96 @@
1
2## Taken from https://stackoverflow.com/questions/13564851/generate-keyboard-events#13615802
3import ctypes
4from ctypes import wintypes
5import time
6
7user32 = ctypes.WinDLL('user32', use_last_error=True)
8
9INPUT_MOUSE = 0
10INPUT_KEYBOARD = 1
11INPUT_HARDWARE = 2
12
13KEYEVENTF_EXTENDKEY = 0x0001
14KEYEVENTF_KEYUP = 0x0002
15KEYEVENTF_UNICODE = 0x0003
16KEYEVENTF_SCANCODE = 0x0004
17
18MAPVK_VK_TO_VSC = 0
19
20wintypes.ULONG_PTR = wintypes.WPARAM
21
22class MOUSEINPUT(ctypes.Structure):
23 _fields_ = (("dx", wintypes.LONG),
24 ("dy", wintypes.LONG),
25 ("mouseData", wintypes.DWORD),
26 ("dwFlags", wintypes.DWORD),
27 ("time", wintypes.DWORD),
28 ("dwExtraInfo", wintypes.ULONG_PTR))
29
30class KEYBDINPUT(ctypes.Structure):
31 _fields_ = (("wVk", wintypes.WORD),
32 ("wScan", wintypes.WORD),
33 ("dwFlags", wintypes.DWORD),
34 ("time", wintypes.DWORD),
35 ("dwExtraInfo", wintypes.ULONG_PTR))
36
37 def __init__(self, *args, **kwds):
38 super(KEYBDINPUT, self).__init__(*args, **kwds)
39 if not self.dwFlags & KEYEVENTF_UNICODE:
40 self.wScan = user32.MapVirtualKeyExW(self.wVk, MAPVK_VK_TO_VSC, 0)
41
42class HARDWAREINPUT(ctypes.Structure):
43 _fileds_ = (("uMsg", wintypes.DWORD),
44 ("wParamL", wintypes.WORD),
45 ("wParamH", wintypes.WORD))
46
47class INPUT(ctypes.Structure):
48 class _INPUT(ctypes.Union):
49 _fields_ = (("ki", KEYBDINPUT),
50 ("mi", MOUSEINPUT),
51 ("hi", HARDWAREINPUT))
52 _anonymous_ = ("_input",)
53 _fields_ = (("type", wintypes.DWORD),
54 ("_input", _INPUT))
55
56LPINPUT = ctypes.POINTER(INPUT)
57
58def _check_count(result, func, args):
59 if result == 0:
60 raise ctypes.WinError(ctypes.get_last_error())
61 return args
62
63user32.SendInput.errcheck = _check_count
64user32.SendInput.argtypes = (wintypes.UINT, LPINPUT, ctypes.c_int)
65
66def PressKey(hexKeyCode):
67 x = INPUT(type=INPUT_KEYBOARD, ki=KEYBDINPUT(wVk=hexKeyCode))
68 user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
69
70def ReleaseKey(hexKeyCode):
71 x = INPUT(type=INPUT_KEYBOARD, ki=KEYBDINPUT(wVk=hexKeyCode, dwFlags=KEYEVENTF_KEYUP))
72 user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
73##
74## End of stack overflow code
75##
76
77key_mappings = {
78 'a': 0x41, 'b': 0x42, 'c': 0x43, 'd': 0x44,
79 'e': 0x45, 'f': 0x46, 'g': 0x47, 'h': 0x48,
80 'i': 0x49, 'j': 0x4a, 'k': 0x4b, 'l': 0x4c,
81 'm': 0x4d, 'n': 0x4e, 'o': 0x4f, 'p': 0x50,
82 'q': 0x51, 'r': 0x52, 's': 0x53, 't': 0x54,
83 'u': 0x55, 'v': 0x56, 'w': 0x57, 'x': 0x58,
84 'y': 0x59, 'z': 0x5a,
85
86 '0': 0x30, '1': 0x31, '2': 0x32, '3': 0x33,
87 '4': 0x34, '5': 0x35, '6': 0x36, '7': 0x37,
88 '8': 0x38, '9': 0x39,
89}
90
91## Wrapper for above
92def TypeKey(char):
93 char = char.lower()
94 if char in key_mappings:
95 PressKey(key_mappings[char])
96 ReleaseKey(key_mappings[char])
diff --git a/main.py b/main.py
index bfe99e0..485df6f 100644
--- a/main.py
+++ b/main.py
@@ -54,10 +54,15 @@ class Game(object):
54 ## JoyHandler. 54 ## JoyHandler.
55 elif event.type == pygame.JOYBUTTONDOWN: 55 elif event.type == pygame.JOYBUTTONDOWN:
56 self.controller.do_joydown(event) 56 self.controller.do_joydown(event)
57 pass
58 elif event.type == pygame.JOYBUTTONUP: 57 elif event.type == pygame.JOYBUTTONUP:
59 self.controller.do_joyup(event) 58 self.controller.do_joyup(event)
60 pass 59
60 ## Send the focus state to the controller.
61 elif event.type == pygame.ACTIVEEVENT:
62 if event.state == 2:
63 self.controller.set_focus(False)
64 elif event.state == 6:
65 self.controller.set_focus(True)
61 66
62 if running == False: 67 if running == False:
63 continue 68 continue
@@ -65,13 +70,14 @@ class Game(object):
65 self.controller.update() 70 self.controller.update()
66 self.controller.draw(self.screen) 71 self.controller.draw(self.screen)
67 pygame.display.flip() 72 pygame.display.flip()
68 self.clock.tick(self.tps) 73 if self.tps > 0:
74 self.clock.tick(self.tps)
69 75
70 else: 76 else:
71 pygame.joystick.quit() 77 pygame.joystick.quit()
72 pygame.quit() 78 pygame.quit()
73 79
74if __name__ == '__main__': 80if __name__ == '__main__':
75 g = Game() 81 g = Game(cap=5000, w=720, h=720)
76 g.main() 82 g.main()
77 83