Waydroid
Installation
# sudo pacman -S linux-xanmod-anbox linux-xanmod-anbox-headers
sudo pacman -S linux-zen linux-zen-headers
sudo rm -rf /var/lib/waydroid /home/.waydroid ~/waydroid ~/.share/waydroid ~/.local/share/applications/*aydroid* ~/.local/share/waydroid
sudo pacman -S waydroid
sudo waydroid init -s GAPPS
# waydroid-extras: https://aur.archlinux.org/waydroid-script-git.git
# For amd use libndk
sudo waydroid-extras install libndk widevine magisk
sudo systemctl enable waydroid-container
sudo systemctl start waydroid-container
# Using cage since I use xorg.
cage waydroid show-full-ui
Google Play certification
https://docs.waydro.id/faq/google-play-certification
Shadowfight Arena 4
Setup udev waydroid to detect Joystick
Emulate Joystick
git clone https://github.com/iosonofabio/virtual_gamepad
paru -S python-uinput python-pynput
# For script to work load uinput
sudo modprobe uinput
# Load module on boot
sudo echo uinput >> /etc/modules-load.d/uinput.conf
# To use script without sudo:
sudo groupadd uinput
sudo usermod -aG uinput "$USER"
sudo chmod g+rw /dev/uinput
sudo chgrp uinput /dev/uinput
For permissions to persist across reboot:
Play
virtual_gamepad.py with hjkl bindings
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_THUMBL,
uinput.BTN_THUMBR,
uinput.ABS_X + (0, 255, 0, 0),
uinput.ABS_Y + (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)
keymap = {
'right': 'l',
'left': 'h',
'up': 'k',
'down': 'j',
'kick': 'd',
'fight': 'f',
'shadow': 's',
'range': 'a',
'jumpleft': 'i',
'jumpright': 'o',
'rollleft': 'n',
'rollleft2': 'b',
'rollright': 'm',
'range': 'a',
'confirm': '0',
'?': '-',
'requests/cancel': '9',
'zoomout': '8',
'back': 'p',
}
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['kick']:
device.emit(uinput.BTN_A, 1)
elif k == keymap['fight']:
device.emit(uinput.BTN_B, 1)
elif k == keymap['shadow']:
device.emit(uinput.BTN_X, 1)
elif k == keymap['range']:
device.emit(uinput.BTN_Y, 1)
elif k == keymap['confirm']:
device.emit(uinput.BTN_TL, 1)
elif k == keymap['?']:
device.emit(uinput.BTN_TR, 1)
elif k == keymap['requests/cancel']:
device.emit(uinput.BTN_THUMBL, 1)
elif k == keymap['zoomout']:
device.emit(uinput.BTN_THUMBR, 1)
elif k == keymap['up']:
device.emit(uinput.ABS_Y, 0) # Zero Y
elif k == keymap['jumpleft']:
device.emit(uinput.ABS_Y, 0) # Zero Y
device.emit(uinput.ABS_X, 0) # Zero X
elif k == keymap['jumpright']:
device.emit(uinput.ABS_Y, 0) # Zero Y
device.emit(uinput.ABS_X, 255) # Zero X
elif k == keymap['down']:
device.emit(uinput.ABS_Y, 255) # Max Y
elif k == keymap['rollleft']:
device.emit(uinput.ABS_Y, 255) # Max Y
device.emit(uinput.ABS_X, 0) # Zero X
elif k == keymap['rollleft2']:
device.emit(uinput.ABS_Y, 255) # Max Y
device.emit(uinput.ABS_X, 0) # Zero X
elif k == keymap['rollright']:
device.emit(uinput.ABS_Y, 255) # Max Y
device.emit(uinput.ABS_X, 255) # Max X
elif k == keymap['left']:
device.emit(uinput.ABS_X, 0) # Zero X
elif k == keymap['right']:
device.emit(uinput.ABS_X, 255) # Max X
return True
def on_release(key):
k = find_key(key)
if k is True:
return True
if k == keymap['kick']:
device.emit(uinput.BTN_A, 0)
elif k == keymap['fight']:
device.emit(uinput.BTN_B, 0)
elif k == keymap['shadow']:
device.emit(uinput.BTN_X, 0)
elif k == keymap['range']:
device.emit(uinput.BTN_Y, 0)
elif k == keymap['confirm']:
device.emit(uinput.BTN_TL, 0)
elif k == keymap['?']:
device.emit(uinput.BTN_TR, 0)
elif k == keymap['requests/cancel']:
device.emit(uinput.BTN_THUMBL, 0)
elif k == keymap['zoomout']:
device.emit(uinput.BTN_THUMBR, 0)
elif k == keymap['up']:
device.emit(uinput.ABS_Y, 128) # Center Y
elif k == keymap['jumpleft']:
device.emit(uinput.ABS_Y, 128) # Zero Y
device.emit(uinput.ABS_X, 128) # Zero X
elif k == keymap['jumpright']:
device.emit(uinput.ABS_Y, 128) # Zero Y
device.emit(uinput.ABS_X, 128) # Zero X
elif k == keymap['rollright']:
device.emit(uinput.ABS_Y, 128) # Zero Y
device.emit(uinput.ABS_X, 128) # Zero X
elif k == keymap['rollleft']:
device.emit(uinput.ABS_Y, 128) # Zero Y
device.emit(uinput.ABS_X, 128) # Zero X
elif k == keymap['rollleft2']:
device.emit(uinput.ABS_Y, 128) # Zero Y
device.emit(uinput.ABS_X, 128) # Zero X
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
#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
taunts with xdotool and xbindkeys
I don't think there's a way to get taunts working just with joystick. You need to make use of the mouse and screen. I did this using xdotool and xbindkeys.
~/.xbindkeysrc
"~/bin/taunts.sh z"
m:0x0 + c:52
z
"~/bin/taunts.sh x"
m:0x0 + c:53
x
"~/bin/taunts.sh c"
m:0x0 + c:54
c
"~/bin/taunts.sh v"
m:0x0 + c:55
v
~/bin/taunts.sh
#!/bin/bash
if [[ $1 == "z" ]];
then
xdotool mousemove 3326 937
xdotool mousedown 1
xdotool mousemove 3285 921
sleep 0.1
xdotool mouseup 1
elif [[ $1 == "x" ]];
then
xdotool mousemove 3326 937
xdotool mousedown 1
xdotool mousemove 3326 852
sleep 0.1
xdotool mouseup 1
elif [[ $1 == "c" ]];
then
xdotool mousemove 3326 937
xdotool mousedown 1
xdotool mousemove 3435 921
sleep 0.1
xdotool mouseup 1
elif [[ $1 == "v" ]];
then
xdotool mousemove 3326 937
xdotool mousedown 1
xdotool mousemove 3285 1001
sleep 0.1
xdotool mouseup 1
fi
I found the appropriate location for mouse using xdotool getmouselocation --shell
.
I run xbindkeys with xbindkeys -n
so that I simply ctrl-c the script to
revert keybindings.