|
@@ -16,229 +16,230 @@ from io import BytesIO
|
|
|
|
|
|
# Add local WASD binding ...
|
|
# Add local WASD binding ...
|
|
if True:
|
|
if True:
|
|
- # Tweaked ...
|
|
|
|
- KEYBIND = {
|
|
|
|
- pygame.K_w: pygame.K_UP, # Forward
|
|
|
|
- pygame.K_a: pygame.K_COMMA, # Strafe left
|
|
|
|
- pygame.K_s: pygame.K_DOWN, # Back
|
|
|
|
- pygame.K_d: pygame.K_PERIOD, # Strafe right
|
|
|
|
- pygame.K_e: pygame.K_SPACE, # Use
|
|
|
|
- }
|
|
|
|
- DISABLE_MOUSE_Y = True
|
|
|
|
|
|
+ # Tweaked ...
|
|
|
|
+ KEYBIND = {
|
|
|
|
+ pygame.K_w: pygame.K_UP, # Forward
|
|
|
|
+ pygame.K_a: pygame.K_COMMA, # Strafe left
|
|
|
|
+ pygame.K_s: pygame.K_DOWN, # Back
|
|
|
|
+ pygame.K_d: pygame.K_PERIOD, # Strafe right
|
|
|
|
+ pygame.K_e: pygame.K_SPACE, # Use
|
|
|
|
+ }
|
|
|
|
+ DISABLE_MOUSE_Y = True
|
|
else:
|
|
else:
|
|
- # Original controls
|
|
|
|
- KEYBIND = {}
|
|
|
|
- DISABLE_MOUSE_Y = False
|
|
|
|
|
|
+ # Original controls
|
|
|
|
+ KEYBIND = {}
|
|
|
|
+ DISABLE_MOUSE_Y = False
|
|
|
|
|
|
|
|
|
|
def map_key(k):
|
|
def map_key(k):
|
|
|
|
|
|
- KEYVAL = {
|
|
|
|
- 'KEY_LEFTARROW': 0,
|
|
|
|
- 'KEY_RIGHTARROW': 1,
|
|
|
|
- 'KEY_DOWNARROW': 2,
|
|
|
|
- 'KEY_UPARROW': 3,
|
|
|
|
- 'KEY_RSHIFT': 4,
|
|
|
|
- 'KEY_RCTRL': 5,
|
|
|
|
- 'KEY_RALT': 6,
|
|
|
|
- 'KEY_ESCAPE': 7,
|
|
|
|
- 'KEY_ENTER': 8,
|
|
|
|
- 'KEY_TAB': 9,
|
|
|
|
- 'KEY_BACKSPACE': 10,
|
|
|
|
- 'KEY_PAUSE': 11,
|
|
|
|
- 'KEY_EQUALS': 12,
|
|
|
|
- 'KEY_MINUS': 13,
|
|
|
|
- 'KEY_F1': 14,
|
|
|
|
- 'KEY_F2': 15,
|
|
|
|
- 'KEY_F3': 16,
|
|
|
|
- 'KEY_F4': 17,
|
|
|
|
- 'KEY_F5': 18,
|
|
|
|
- 'KEY_F6': 19,
|
|
|
|
- 'KEY_F7': 20,
|
|
|
|
- 'KEY_F8': 21,
|
|
|
|
- 'KEY_F9': 22,
|
|
|
|
- 'KEY_F10': 23,
|
|
|
|
- 'KEY_F11': 24,
|
|
|
|
- 'KEY_F12': 25,
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- KEYMAP = {
|
|
|
|
- pygame.K_LEFT: 'KEY_LEFTARROW',
|
|
|
|
- pygame.K_RIGHT: 'KEY_RIGHTARROW',
|
|
|
|
- pygame.K_DOWN: 'KEY_DOWNARROW',
|
|
|
|
- pygame.K_UP: 'KEY_UPARROW',
|
|
|
|
- pygame.K_RSHIFT: 'KEY_RSHIFT',
|
|
|
|
- pygame.K_LSHIFT: 'KEY_RSHIFT',
|
|
|
|
- pygame.K_RCTRL: 'KEY_RCTRL',
|
|
|
|
- pygame.K_LCTRL: 'KEY_RCTRL',
|
|
|
|
- pygame.K_RALT: 'KEY_RALT',
|
|
|
|
- pygame.K_LALT: 'KEY_RALT',
|
|
|
|
- pygame.K_ESCAPE: 'KEY_ESCAPE',
|
|
|
|
- pygame.K_RETURN: 'KEY_ENTER',
|
|
|
|
- pygame.K_TAB: 'KEY_TAB',
|
|
|
|
- pygame.K_BACKSPACE: 'KEY_BACKSPACE',
|
|
|
|
- pygame.K_PAUSE: 'KEY_PAUSE',
|
|
|
|
- pygame.K_EQUALS: 'KEY_EQUALS',
|
|
|
|
- pygame.K_MINUS: 'KEY_MINUS',
|
|
|
|
- pygame.K_F1: 'KEY_F1',
|
|
|
|
- pygame.K_F2: 'KEY_F2',
|
|
|
|
- pygame.K_F3: 'KEY_F3',
|
|
|
|
- pygame.K_F4: 'KEY_F4',
|
|
|
|
- pygame.K_F5: 'KEY_F5',
|
|
|
|
- pygame.K_F6: 'KEY_F6',
|
|
|
|
- pygame.K_F7: 'KEY_F7',
|
|
|
|
- pygame.K_F8: 'KEY_F8',
|
|
|
|
- pygame.K_F9: 'KEY_F9',
|
|
|
|
- pygame.K_F10: 'KEY_F10',
|
|
|
|
- pygame.K_F11: 'KEY_F11',
|
|
|
|
- pygame.K_F12: 'KEY_F12',
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- # Default is no mapping
|
|
|
|
- rc = None
|
|
|
|
-
|
|
|
|
- # Check for local keybindings
|
|
|
|
- if k in KEYBIND:
|
|
|
|
- k = KEYBIND[k]
|
|
|
|
-
|
|
|
|
- # Check for spcial mapping
|
|
|
|
- if k in KEYMAP:
|
|
|
|
- rc = KEYVAL[KEYMAP[k]]
|
|
|
|
-
|
|
|
|
- # Map upper case to lowercase
|
|
|
|
- elif ord('A') <= k <= ord('Z'):
|
|
|
|
- rc = k - ord('A') + ord('a')
|
|
|
|
-
|
|
|
|
- # Default is to map 1:1 for anything in printable ascii range
|
|
|
|
- elif 32 <= k <= 127:
|
|
|
|
- rc = k
|
|
|
|
-
|
|
|
|
- return rc
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-def main(argv0, dev='/dev/ttyUSB1'):
|
|
|
|
-
|
|
|
|
- # Init PyGame
|
|
|
|
- pygame.init()
|
|
|
|
-
|
|
|
|
- # Load logo
|
|
|
|
- logo = pygame.image.load(
|
|
|
|
- BytesIO(base64.decodebytes(LOGO_DATA)),
|
|
|
|
- 'logo.jpg'
|
|
|
|
- )
|
|
|
|
-
|
|
|
|
- # Init screen
|
|
|
|
- screen = pygame.display.set_mode([logo.get_width(), logo.get_height()])
|
|
|
|
- pygame.display.set_caption("Doom controller")
|
|
|
|
-
|
|
|
|
- pygame.time.set_timer(pygame.USEREVENT, 50)
|
|
|
|
-
|
|
|
|
- # Open port
|
|
|
|
- port = serial.Serial(dev, baudrate=1000000)
|
|
|
|
-
|
|
|
|
- # Main loop
|
|
|
|
- running = True
|
|
|
|
- held = set()
|
|
|
|
-
|
|
|
|
- mouse_active = False
|
|
|
|
- mdx = 0
|
|
|
|
- mdy = 0
|
|
|
|
-
|
|
|
|
- while running:
|
|
|
|
- # Process event
|
|
|
|
- pygame.event.pump()
|
|
|
|
- event = pygame.event.wait()
|
|
|
|
-
|
|
|
|
- if event.type == pygame.QUIT:
|
|
|
|
- running = False
|
|
|
|
-
|
|
|
|
- elif event.type == pygame.VIDEORESIZE:
|
|
|
|
- screen.blit(pygame.transform.scale(logo, event.dict['size']), (0, 0))
|
|
|
|
- pygame.display.update()
|
|
|
|
-
|
|
|
|
- elif event.type == pygame.VIDEOEXPOSE:
|
|
|
|
- screen.blit(pygame.transform.scale(logo, screen.get_size()), (0, 0))
|
|
|
|
- pygame.display.update()
|
|
|
|
-
|
|
|
|
- elif event.type == pygame.KEYDOWN:
|
|
|
|
- kv = map_key(event.key)
|
|
|
|
- if (kv is not None) and (kv not in held):
|
|
|
|
- held.add(kv)
|
|
|
|
- cmd = (kv | 0x80).to_bytes(1, 'little')
|
|
|
|
- port.write(cmd)
|
|
|
|
-
|
|
|
|
- elif event.type == pygame.KEYUP:
|
|
|
|
- if mouse_active and (event.key in (pygame.K_LMETA, pygame.K_RMETA)):
|
|
|
|
- # Release mouse
|
|
|
|
- pygame.mouse.set_visible(True)
|
|
|
|
- pygame.event.set_grab(False)
|
|
|
|
-
|
|
|
|
- # Release all pressed buttons
|
|
|
|
- for kv in [28, 29, 30]:
|
|
|
|
- if kv in held:
|
|
|
|
- held.remove(kv)
|
|
|
|
- cmd = kv.to_bytes(1, 'little')
|
|
|
|
- port.write(cmd)
|
|
|
|
-
|
|
|
|
- # Not active
|
|
|
|
- mouse_active = False
|
|
|
|
-
|
|
|
|
- kv = map_key(event.key)
|
|
|
|
- if (kv is not None) and (kv in held):
|
|
|
|
- held.remove(kv)
|
|
|
|
- cmd = kv.to_bytes(1, 'little')
|
|
|
|
- port.write(cmd)
|
|
|
|
-
|
|
|
|
- elif event.type == pygame.MOUSEBUTTONDOWN:
|
|
|
|
- if mouse_active:
|
|
|
|
- # We have the mouse, send events
|
|
|
|
- kv = (28 + event.button - 1) if (1 <= event.button <= 3) else None
|
|
|
|
- if (kv is not None) and (kv not in held):
|
|
|
|
- held.add(kv)
|
|
|
|
- cmd = (kv | 0x80).to_bytes(1, 'little')
|
|
|
|
- port.write(cmd)
|
|
|
|
-
|
|
|
|
- elif event.button == 1:
|
|
|
|
- # If button 1, grab mouse
|
|
|
|
- pygame.mouse.set_visible(False)
|
|
|
|
- pygame.event.set_grab(True)
|
|
|
|
-
|
|
|
|
- # Active
|
|
|
|
- mouse_active = True
|
|
|
|
-
|
|
|
|
- elif event.type == pygame.MOUSEBUTTONUP:
|
|
|
|
- if mouse_active:
|
|
|
|
- # We have the mouse, send events
|
|
|
|
- kv = (28 + event.button - 1) if (1 <= event.button <= 3) else None
|
|
|
|
- if (kv is not None) and (kv in held):
|
|
|
|
- held.remove(kv)
|
|
|
|
- cmd = kv.to_bytes(1, 'little')
|
|
|
|
- port.write(cmd)
|
|
|
|
-
|
|
|
|
- elif event.type == pygame.MOUSEMOTION:
|
|
|
|
- if mouse_active:
|
|
|
|
- # We accumulate mouse events to not overwhelm
|
|
|
|
- # target ...
|
|
|
|
- mdx += event.rel[0]
|
|
|
|
- mdy += event.rel[1]
|
|
|
|
-
|
|
|
|
- elif event.type == pygame.USEREVENT:
|
|
|
|
- # Hack
|
|
|
|
- if DISABLE_MOUSE_Y:
|
|
|
|
- mdy = 0
|
|
|
|
-
|
|
|
|
- # Send pending mouse events
|
|
|
|
- if (mdx != 0) or (mdy != 0):
|
|
|
|
-
|
|
|
|
- # Send what we can
|
|
|
|
- x = max(min(mdx, 127), -128)
|
|
|
|
- y = max(min(mdy, 127), -128)
|
|
|
|
-
|
|
|
|
- mdx -= x
|
|
|
|
- mdy -= y
|
|
|
|
-
|
|
|
|
- # Send it
|
|
|
|
- port.write(struct.pack('bbb', 31, x, y))
|
|
|
|
|
|
+ KEYVAL = {
|
|
|
|
+ 'KEY_LEFTARROW': 0,
|
|
|
|
+ 'KEY_RIGHTARROW': 1,
|
|
|
|
+ 'KEY_DOWNARROW': 2,
|
|
|
|
+ 'KEY_UPARROW': 3,
|
|
|
|
+ 'KEY_RSHIFT': 4,
|
|
|
|
+ 'KEY_RCTRL': 5,
|
|
|
|
+ 'KEY_RALT': 6,
|
|
|
|
+ 'KEY_ESCAPE': 7,
|
|
|
|
+ 'KEY_ENTER': 8,
|
|
|
|
+ 'KEY_TAB': 9,
|
|
|
|
+ 'KEY_BACKSPACE': 10,
|
|
|
|
+ 'KEY_PAUSE': 11,
|
|
|
|
+ 'KEY_EQUALS': 12,
|
|
|
|
+ 'KEY_MINUS': 13,
|
|
|
|
+ 'KEY_F1': 14,
|
|
|
|
+ 'KEY_F2': 15,
|
|
|
|
+ 'KEY_F3': 16,
|
|
|
|
+ 'KEY_F4': 17,
|
|
|
|
+ 'KEY_F5': 18,
|
|
|
|
+ 'KEY_F6': 19,
|
|
|
|
+ 'KEY_F7': 20,
|
|
|
|
+ 'KEY_F8': 21,
|
|
|
|
+ 'KEY_F9': 22,
|
|
|
|
+ 'KEY_F10': 23,
|
|
|
|
+ 'KEY_F11': 24,
|
|
|
|
+ 'KEY_F12': 25,
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ KEYMAP = {
|
|
|
|
+ pygame.K_LEFT: 'KEY_LEFTARROW',
|
|
|
|
+ pygame.K_RIGHT: 'KEY_RIGHTARROW',
|
|
|
|
+ pygame.K_DOWN: 'KEY_DOWNARROW',
|
|
|
|
+ pygame.K_UP: 'KEY_UPARROW',
|
|
|
|
+ pygame.K_RSHIFT: 'KEY_RSHIFT',
|
|
|
|
+ pygame.K_LSHIFT: 'KEY_RSHIFT',
|
|
|
|
+ pygame.K_RCTRL: 'KEY_RCTRL',
|
|
|
|
+ pygame.K_LCTRL: 'KEY_RCTRL',
|
|
|
|
+ pygame.K_RALT: 'KEY_RALT',
|
|
|
|
+ pygame.K_LALT: 'KEY_RALT',
|
|
|
|
+ pygame.K_ESCAPE: 'KEY_ESCAPE',
|
|
|
|
+ pygame.K_RETURN: 'KEY_ENTER',
|
|
|
|
+ pygame.K_TAB: 'KEY_TAB',
|
|
|
|
+ pygame.K_BACKSPACE: 'KEY_BACKSPACE',
|
|
|
|
+ pygame.K_PAUSE: 'KEY_PAUSE',
|
|
|
|
+ pygame.K_EQUALS: 'KEY_EQUALS',
|
|
|
|
+ pygame.K_MINUS: 'KEY_MINUS',
|
|
|
|
+ pygame.K_F1: 'KEY_F1',
|
|
|
|
+ pygame.K_F2: 'KEY_F2',
|
|
|
|
+ pygame.K_F3: 'KEY_F3',
|
|
|
|
+ pygame.K_F4: 'KEY_F4',
|
|
|
|
+ pygame.K_F5: 'KEY_F5',
|
|
|
|
+ pygame.K_F6: 'KEY_F6',
|
|
|
|
+ pygame.K_F7: 'KEY_F7',
|
|
|
|
+ pygame.K_F8: 'KEY_F8',
|
|
|
|
+ pygame.K_F9: 'KEY_F9',
|
|
|
|
+ pygame.K_F10: 'KEY_F10',
|
|
|
|
+ pygame.K_F11: 'KEY_F11',
|
|
|
|
+ pygame.K_F12: 'KEY_F12',
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ # Default is no mapping
|
|
|
|
+ rc = None
|
|
|
|
+
|
|
|
|
+ # Check for local keybindings
|
|
|
|
+ if k in KEYBIND:
|
|
|
|
+ k = KEYBIND[k]
|
|
|
|
+
|
|
|
|
+ # Check for spcial mapping
|
|
|
|
+ if k in KEYMAP:
|
|
|
|
+ rc = KEYVAL[KEYMAP[k]]
|
|
|
|
+
|
|
|
|
+ # Map upper case to lowercase
|
|
|
|
+ elif ord('A') <= k <= ord('Z'):
|
|
|
|
+ rc = k - ord('A') + ord('a')
|
|
|
|
+
|
|
|
|
+ # Default is to map 1:1 for anything in printable ascii range
|
|
|
|
+ elif 32 <= k <= 127:
|
|
|
|
+ rc = k
|
|
|
|
+
|
|
|
|
+ return rc
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+def main(argv0, dev='/dev/ttyUSB6'):
|
|
|
|
+
|
|
|
|
+ # Init PyGame
|
|
|
|
+ pygame.init()
|
|
|
|
+
|
|
|
|
+ # Load logo
|
|
|
|
+ logo = pygame.image.load(
|
|
|
|
+ BytesIO(base64.decodebytes(LOGO_DATA)),
|
|
|
|
+ 'logo.jpg'
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ # Init screen
|
|
|
|
+ screen = pygame.display.set_mode([logo.get_width(), logo.get_height()])
|
|
|
|
+ pygame.display.set_caption("Doom controller")
|
|
|
|
+
|
|
|
|
+ pygame.time.set_timer(pygame.USEREVENT, 50)
|
|
|
|
+
|
|
|
|
+ # Open port
|
|
|
|
+ port = serial.Serial(dev, baudrate=1000000)
|
|
|
|
+
|
|
|
|
+ # Main loop
|
|
|
|
+ running = True
|
|
|
|
+ held = set()
|
|
|
|
+
|
|
|
|
+ mouse_active = False
|
|
|
|
+ mdx = 0
|
|
|
|
+ mdy = 0
|
|
|
|
+
|
|
|
|
+ while running:
|
|
|
|
+ # Process event
|
|
|
|
+ pygame.event.pump()
|
|
|
|
+ event = pygame.event.wait()
|
|
|
|
+
|
|
|
|
+ if event.type == pygame.QUIT:
|
|
|
|
+ running = False
|
|
|
|
+
|
|
|
|
+ elif event.type == pygame.VIDEORESIZE:
|
|
|
|
+ screen.blit(pygame.transform.scale(logo, event.dict['size']), (0, 0))
|
|
|
|
+ pygame.display.update()
|
|
|
|
+
|
|
|
|
+ elif event.type == pygame.VIDEOEXPOSE:
|
|
|
|
+ screen.blit(pygame.transform.scale(logo, screen.get_size()), (0, 0))
|
|
|
|
+ pygame.display.update()
|
|
|
|
+
|
|
|
|
+ elif event.type == pygame.KEYDOWN:
|
|
|
|
+ kv = map_key(event.key)
|
|
|
|
+ if (kv is not None) and (kv not in held):
|
|
|
|
+ held.add(kv)
|
|
|
|
+ cmd = (kv | 0x80).to_bytes(1, 'little')
|
|
|
|
+ print("Kendown")
|
|
|
|
+ port.write(cmd)
|
|
|
|
+
|
|
|
|
+ elif event.type == pygame.KEYUP:
|
|
|
|
+ if mouse_active and (event.key in (pygame.K_LMETA, pygame.K_RMETA)):
|
|
|
|
+ # Release mouse
|
|
|
|
+ pygame.mouse.set_visible(True)
|
|
|
|
+ pygame.event.set_grab(False)
|
|
|
|
+
|
|
|
|
+ # Release all pressed buttons
|
|
|
|
+ for kv in [28, 29, 30]:
|
|
|
|
+ if kv in held:
|
|
|
|
+ held.remove(kv)
|
|
|
|
+ cmd = kv.to_bytes(1, 'little')
|
|
|
|
+ port.write(cmd)
|
|
|
|
+
|
|
|
|
+ # Not active
|
|
|
|
+ mouse_active = False
|
|
|
|
+
|
|
|
|
+ kv = map_key(event.key)
|
|
|
|
+ if (kv is not None) and (kv in held):
|
|
|
|
+ held.remove(kv)
|
|
|
|
+ cmd = kv.to_bytes(1, 'little')
|
|
|
|
+ port.write(cmd)
|
|
|
|
+
|
|
|
|
+ elif event.type == pygame.MOUSEBUTTONDOWN:
|
|
|
|
+ if mouse_active:
|
|
|
|
+ # We have the mouse, send events
|
|
|
|
+ kv = (28 + event.button - 1) if (1 <= event.button <= 3) else None
|
|
|
|
+ if (kv is not None) and (kv not in held):
|
|
|
|
+ held.add(kv)
|
|
|
|
+ cmd = (kv | 0x80).to_bytes(1, 'little')
|
|
|
|
+ port.write(cmd)
|
|
|
|
+
|
|
|
|
+ elif event.button == 1:
|
|
|
|
+ # If button 1, grab mouse
|
|
|
|
+ pygame.mouse.set_visible(False)
|
|
|
|
+ pygame.event.set_grab(True)
|
|
|
|
+
|
|
|
|
+ # Active
|
|
|
|
+ mouse_active = True
|
|
|
|
+
|
|
|
|
+ elif event.type == pygame.MOUSEBUTTONUP:
|
|
|
|
+ if mouse_active:
|
|
|
|
+ # We have the mouse, send events
|
|
|
|
+ kv = (28 + event.button - 1) if (1 <= event.button <= 3) else None
|
|
|
|
+ if (kv is not None) and (kv in held):
|
|
|
|
+ held.remove(kv)
|
|
|
|
+ cmd = kv.to_bytes(1, 'little')
|
|
|
|
+ port.write(cmd)
|
|
|
|
+
|
|
|
|
+ elif event.type == pygame.MOUSEMOTION:
|
|
|
|
+ if mouse_active:
|
|
|
|
+ # We accumulate mouse events to not overwhelm
|
|
|
|
+ # target ...
|
|
|
|
+ mdx += event.rel[0]
|
|
|
|
+ mdy += event.rel[1]
|
|
|
|
+
|
|
|
|
+ elif event.type == pygame.USEREVENT:
|
|
|
|
+ # Hack
|
|
|
|
+ if DISABLE_MOUSE_Y:
|
|
|
|
+ mdy = 0
|
|
|
|
+
|
|
|
|
+ # Send pending mouse events
|
|
|
|
+ if (mdx != 0) or (mdy != 0):
|
|
|
|
+
|
|
|
|
+ # Send what we can
|
|
|
|
+ x = max(min(mdx, 127), -128)
|
|
|
|
+ y = max(min(mdy, 127), -128)
|
|
|
|
+
|
|
|
|
+ mdx -= x
|
|
|
|
+ mdy -= y
|
|
|
|
+
|
|
|
|
+ # Send it
|
|
|
|
+ port.write(struct.pack('bbb', 31, x, y))
|
|
|
|
|
|
|
|
|
|
LOGO_DATA = b"""
|
|
LOGO_DATA = b"""
|
|
@@ -561,4 +562,4 @@ g0sunxImITTo08RVgqKvT1Q+61/q7CEISRQklRf4RpI00mnemM1An1sOqCao08DOIGmnDGqQ2yvS
|
|
"""
|
|
"""
|
|
|
|
|
|
if __name__ == '__main__':
|
|
if __name__ == '__main__':
|
|
- sys.exit(main(*sys.argv))
|
|
|
|
|
|
+ sys.exit(main(*sys.argv))
|