Good day. We want to combine Joypad and Keyboard/Mouse on the same application (example: Divinity Co-Op). The problem is that usually this is either completely incompatible and requires two Joypads or the one device interrupting the other if they not the same. So i’m searching for a good Virtual Joypad app. Tried MoltenGamepad from Aur but doesn’t compile.
I’ve been using antimicrox-git
(more info), which can be found in the extra repo.
Edit: I just realized this isn’t helpful in the way you need. Please excuse the reply.
Edit 2: The build errors are known in moltengamepad
, and this PR fixes the issue: Add missing <memory> include by hopibel · Pull Request #99 · jgeumlek/MoltenGamepad · GitHub
Ok, and how i include this myself?
Found virtual_gamepad. Did the rest by my self. Leaving it here if someone wants it. Also i’m working on Mouse Events, help will be appreciated.
from collections import defaultdict
import pynput
import uinput
import time
events = (
uinput.BTN_A,
uinput.BTN_B,
uinput.BTN_X,
uinput.BTN_Y,
uinput.BTN_TL,
uinput.BTN_TR,
uinput.BTN_TL2,
uinput.BTN_TR2,
uinput.BTN_THUMBL,
uinput.BTN_THUMBR,
uinput.BTN_SELECT,
uinput.BTN_START,
uinput.BTN_DPAD_UP,
uinput.BTN_DPAD_DOWN,
uinput.BTN_DPAD_LEFT,
uinput.BTN_DPAD_RIGHT,
uinput.ABS_X + (0, 255, 0, 0),
uinput.ABS_Y + (0, 255, 0, 0),
uinput.ABS_RX + (0, 255, 0, 0),
uinput.ABS_RY + (0, 255, 0, 0),
)
device = uinput.Device(
events,
vendor=0x045e,
product=0x028e,
version=0x110,
name="Microsoft X-Box 360 pad",
)
# Center joystick
# syn=False to emit an "atomic" (128, 128) event.
device.emit(uinput.ABS_X, 128, syn=False)
device.emit(uinput.ABS_Y, 128)
device.emit(uinput.ABS_RX, 128, syn=False)
device.emit(uinput.ABS_RY, 128)
keymap = {
'right': 'd',
'left': 'a',
'up': 'w',
'down': 's',
'A': 'space',
'B': 'shift',
'X': 'c',
'Y': 'f',
'LB': 'q',
'RB': 'e',
'LT': 'tab',
'RT': 'r',
'LC': 'z',
'RC': 'x',
'>>': 'l',
'<<': 'j',
'^^': 'i',
'vv': 'k',
'select': '[',
'start': ']',
'd-up': 'up',
'd-down': 'down',
'd-left': 'left',
'd-right': 'right',
}
keys = list(keymap.values())
def find_key(key):
#if key == keyboard.Key.esc:
# return False # stop listener
try:
k = key.char # single-char keys
except:
k = key.name # other keys
if k not in keys:
return True
return k
#print('Key pressed: ' + k)
#return False # stop listener; remove this if want more keys
def on_press(key):
k = find_key(key)
if k is True:
return True
if k == keymap['A']:
device.emit(uinput.BTN_A, 1)
elif k == keymap['B']:
device.emit(uinput.BTN_B, 1)
elif k == keymap['X']:
device.emit(uinput.BTN_X, 1)
elif k == keymap['Y']:
device.emit(uinput.BTN_Y, 1)
elif k == keymap['LB']:
device.emit(uinput.BTN_TL, 1)
elif k == keymap['RB']:
device.emit(uinput.BTN_TR, 1)
elif k == keymap['LT']:
device.emit(uinput.BTN_TL2, 1)
elif k == keymap['RT']:
device.emit(uinput.BTN_TR2, 1)
elif k == keymap['LC']:
device.emit(uinput.BTN_THUMBL, 1)
elif k == keymap['RC']:
device.emit(uinput.BTN_THUMBR, 1)
elif k == keymap['select']:
device.emit(uinput.BTN_SELECT, 1)
elif k == keymap['start']:
device.emit(uinput.BTN_START, 1)
elif k == keymap['d-up']:
device.emit(uinput.BTN_DPAD_UP, 1)
elif k == keymap['d-down']:
device.emit(uinput.BTN_DPAD_DOWN, 1)
elif k == keymap['d-left']:
device.emit(uinput.BTN_DPAD_LEFT, 1)
elif k == keymap['d-right']:
device.emit(uinput.BTN_DPAD_RIGHT, 1)
elif k == keymap['up']:
device.emit(uinput.ABS_Y, 0) # Zero Y
elif k == keymap['down']:
device.emit(uinput.ABS_Y, 255) # Max Y
elif k == keymap['left']:
device.emit(uinput.ABS_X, 0) # Zero X
elif k == keymap['right']:
device.emit(uinput.ABS_X, 255) # Max X
elif k == keymap['^^']:
device.emit(uinput.ABS_RY, 0) # Zero RY
elif k == keymap['vv']:
device.emit(uinput.ABS_RY, 255) # Max RY
elif k == keymap['<<']:
device.emit(uinput.ABS_RX, 0) # Zero RX
elif k == keymap['>>']:
device.emit(uinput.ABS_RX, 255) # Max RX
return True
def on_release(key):
k = find_key(key)
if k is True:
return True
if k == keymap['A']:
device.emit(uinput.BTN_A, 0)
elif k == keymap['B']:
device.emit(uinput.BTN_B, 0)
elif k == keymap['X']:
device.emit(uinput.BTN_X, 0)
elif k == keymap['Y']:
device.emit(uinput.BTN_Y, 0)
elif k == keymap['LB']:
device.emit(uinput.BTN_TL, 0)
elif k == keymap['RB']:
device.emit(uinput.BTN_TR, 0)
elif k == keymap['LT']:
device.emit(uinput.BTN_TL2, 0)
elif k == keymap['RT']:
device.emit(uinput.BTN_TR2, 0)
elif k == keymap['LC']:
device.emit(uinput.BTN_THUMBL, 0)
elif k == keymap['RC']:
device.emit(uinput.BTN_THUMBR, 0)
elif k == keymap['select']:
device.emit(uinput.BTN_SELECT, 0)
elif k == keymap['start']:
device.emit(uinput.BTN_START, 0)
elif k == keymap['d-up']:
device.emit(uinput.BTN_DPAD_UP, 0)
elif k == keymap['d-down']:
device.emit(uinput.BTN_DPAD_DOWN, 0)
elif k == keymap['d-left']:
device.emit(uinput.BTN_DPAD_LEFT, 0)
elif k == keymap['d-right']:
device.emit(uinput.BTN_DPAD_RIGHT, 0)
elif k == keymap['up']:
device.emit(uinput.ABS_Y, 128) # Center Y
elif k == keymap['down']:
device.emit(uinput.ABS_Y, 128) # Center Y
elif k == keymap['left']:
device.emit(uinput.ABS_X, 128) # Center Y
elif k == keymap['right']:
device.emit(uinput.ABS_X, 128) # Center Y
elif k == keymap['^^']:
device.emit(uinput.ABS_RY, 128) # Center RY
elif k == keymap['vv']:
device.emit(uinput.ABS_RY, 128) # Center RY
elif k == keymap['<<']:
device.emit(uinput.ABS_RX, 128) # Center RY
elif k == keymap['>>']:
device.emit(uinput.ABS_RX, 128) # Center RY
#time.sleep(.02) # Poll every 20ms (otherwise CPU load gets too high)
return True
if True:
listener = pynput.keyboard.Listener(
on_press=on_press,
on_release=on_release,
)
listener.start() # start to listen on a separate thread
listener.join() # remove if main thread is polling self.keys