Created
May 2, 2022 21:44
-
-
Save btumbleson/9aff2079f364c95305c63a996e0eef6d to your computer and use it in GitHub Desktop.
SuzoHapp Trackball Fix for Linux
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# SuzoHapp Trackball Fix | |
# v0.1 - 11/09/2021 | |
# https://bentumbleson.com | |
# | |
# Requires python-evdev: https://python-evdev.readthedocs.io/en/latest/ | |
# | |
# This script will constantly read the input from your SuzoHapp trackball | |
# and automatically inject a theoretical large relative movement into to system when | |
# a large rotation (determined by acceleration) of the trackball is detected. | |
# | |
# This works because when the analog trackball spins too quickly, the sensor | |
# will either read "0" because it's moving too fast, nothing at all, or a very | |
# low number which is not representative of the actual speed of the trackball. | |
# | |
# In MAME games like Golden Tee (gtfore06), we have to inject movement before | |
# any of the 0's or small numbers can register, or else your swing in the game in | |
# the game will sputter, leading to undesired results. This is why the script doesn't | |
# listen for unexpected "drops" in relative movement, and rather needs to proactively | |
# attempt to determine when a drop is likely to happen so it can correct beforehand. | |
# | |
# Thus, an arbitary measure of acceleration is calculated between each instance of | |
# a relative movement by the trackball, and if it is less than -100k, then a relative | |
# action is pushed to the system ten times, each 0.08 seconds after another. | |
from evdev import InputDevice, InputEvent, list_devices, ecodes as e | |
import datetime | |
import time | |
devices = [InputDevice(path) for path in list_devices()] | |
for device in devices: | |
if device.name == "HID 1241:1111": # this is the name of your SuzoHapp Trackball - replace as needed! | |
# set dev equal to the matched device | |
dev = InputDevice(device.path) | |
# display the device name to start | |
print(dev) | |
# this method is used to send a simulated value to the computer | |
def pushValue(value): | |
repeatCount = 10 # replace with whatever you need, I found 10 was needed in many cases | |
for _ in range(repeatCount): | |
# pass the value as a relative Y movement | |
dev.write(e.EV_REL, e.REL_Y, value) | |
# sync | |
dev.write(e.EV_SYN, 0, 0) | |
# sleep equivilant to 120hz | |
time.sleep(0.008) | |
# we need to build up the current time so we can set define `last` before the loop starts for the first time | |
# this is messy and there's probably a better way to do this? | |
dt = datetime.datetime.now().timestamp() | |
sec = int(dt) | |
usec = int(str(dt - int(dt)).split(".")[1]) | |
last = InputEvent(sec, usec, e.EV_REL, e.REL_Y, 0) | |
# process each movement of the trackball | |
for event in dev.read_loop(): | |
# 2 = Relative Movement, we only want these | |
if event.type == 2: | |
# event.code of 1 = REL_Y (relative Y, since we aren't interested in x movements) | |
if event.code == 1: | |
# calculate the different of relative movement values between the last event of this type | |
diffValue = abs(event.value - (last.value or 0)) | |
# calculate acceleration | |
diffInTimestampsSquared = (event.timestamp() - last.timestamp()) ** 2 | |
if diffInTimestampsSquared == 0: | |
accel = 0 | |
else: | |
accel = (event.value - last.value) / (diffInTimestampsSquared) | |
# uncomment to test acceleration calculation based on values | |
print(accel, " ---- ", event.value, last.value, (event.timestamp() - last.timestamp())) | |
# negative acceleration is forward movement, 100k | |
if accel < -100000: | |
pushValue(-35) # -35 is the equivialant of smacking the trackball quite hard | |
# set the current event to the last so we can compare to it on the next event | |
last = event |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment