From aeeb5f9ff044979c21050bd0b453b916ec051f61 Mon Sep 17 00:00:00 2001 From: Alberto Fanjul Date: Fri, 21 Feb 2025 14:33:13 +0100 Subject: [PATCH] Control for autocenter controlled by wheel This switch is a feature for thrustmaster devices --- data/udev/99-thrustmaster-wheel-perms.rules | 2 +- oversteer/device.py | 26 ++++++++++++- oversteer/gtk_handlers.py | 3 ++ oversteer/gtk_ui.py | 9 +++++ oversteer/main.ui | 43 +++++++++++++++++++++ oversteer/model.py | 11 ++++++ 6 files changed, 91 insertions(+), 3 deletions(-) diff --git a/data/udev/99-thrustmaster-wheel-perms.rules b/data/udev/99-thrustmaster-wheel-perms.rules index d53e0f9..0f0f63a 100644 --- a/data/udev/99-thrustmaster-wheel-perms.rules +++ b/data/udev/99-thrustmaster-wheel-perms.rules @@ -44,7 +44,7 @@ GOTO="end" LABEL="t150" # Thrustmaster T150 Racing Wheel (USB) -ATTRS{idProduct}=="b677", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain autocenter'" +ATTRS{idProduct}=="b677", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain autocenter enable_autocenter'" # Thrustmaster TMX Racing Wheel (USB) ATTRS{idProduct}=="b67f", RUN+="/bin/sh -c 'cd %S%p; chmod 666 range gain autocenter'" diff --git a/oversteer/device.py b/oversteer/device.py index 039990f..aa6e335 100644 --- a/oversteer/device.py +++ b/oversteer/device.py @@ -192,6 +192,7 @@ def get_autocenter(self): with open(path, "r") as file: data = file.read() autocenter = data.strip() + return int(round((int(autocenter) * 100) / 65535)) def set_autocenter(self, autocenter): @@ -205,7 +206,8 @@ def set_autocenter(self, autocenter): file.write(autocenter) else: input_device = self.get_input_device() - input_device.write(ecodes.EV_FF, ecodes.FF_AUTOCENTER, int(autocenter)) + if input_device: + input_device.write(ecodes.EV_FF, ecodes.FF_AUTOCENTER, int(autocenter)) return True def get_ff_gain(self): @@ -334,6 +336,24 @@ def center_wheel(self): time.sleep(1) self.set_autocenter(0) + def get_autocenter_controlled_by_wheel(self): + if self.usb_id in [wid.TM_T150]: + path = self.checked_device_file("enable_autocenter") + if not path: + return False + with open(path, "r") as file: + data = file.read() + value = data.strip() + return value == 'y' + + def set_autocenter_controlled_by_wheel(self, value): + if self.usb_id in [wid.TM_T150]: + path = self.checked_device_file("enable_autocenter") + if not path: + return False + with open(path, "w") as file: + file.write('y' if value else 'n') + def check_permissions(self): logging.debug("check_permissions: %s", self.dev_path) if not os.access(self.dev_path, os.F_OK | os.R_OK | os.X_OK): @@ -348,6 +368,8 @@ def check_permissions(self): return False if not self.check_file_permissions('autocenter'): return False + if not self.check_file_permissions('enable_autocenter'): + return False if not self.check_file_permissions('spring_level'): return False if not self.check_file_permissions('damper_level'): @@ -365,7 +387,7 @@ def get_last_axis_value(self, axis): def get_input_device(self): if self.input_device is None or self.input_device.fd == -1: - if os.access(self.dev_name, os.R_OK): + if self.dev_name and os.access(self.dev_name, os.R_OK): self.input_device = InputDevice(self.dev_name) return self.input_device diff --git a/oversteer/gtk_handlers.py b/oversteer/gtk_handlers.py index e7bb146..2156264 100644 --- a/oversteer/gtk_handlers.py +++ b/oversteer/gtk_handlers.py @@ -97,6 +97,9 @@ def on_autocenter_value_changed(self, widget): autocenter = int(widget.get_value()) self.model.set_autocenter(autocenter) + def on_autocenter_controlled_by_wheel_set(self, widget, state): + self.model.set_autocenter_controlled_by_wheel(state) + def on_check_permissions_state_set(self, widget, state): self.controller.set_check_permissions(state) diff --git a/oversteer/gtk_ui.py b/oversteer/gtk_ui.py index 8cd63b5..01b6aa1 100644 --- a/oversteer/gtk_ui.py +++ b/oversteer/gtk_ui.py @@ -299,6 +299,13 @@ def set_autocenter(self, autocenter): self.autocenter.set_sensitive(True) self.autocenter.set_value(int(autocenter)) + def set_autocenter_controlled_by_wheel(self, value): + if value is None: + self.autocenter_controlled_by_wheel.set_sensitive(False) + else: + self.autocenter_controlled_by_wheel.set_sensitive(True) + self.autocenter_controlled_by_wheel.set_state(value) + def set_ff_gain(self, ff_gain): if ff_gain is None: self.ff_gain.set_sensitive(False) @@ -590,6 +597,8 @@ def _set_builder_objects(self): self.combine_brakes = self.builder.get_object('combine_brakes') self.combine_clutch = self.builder.get_object('combine_clutch') self.autocenter = self.builder.get_object('autocenter') + self.autocenter_controlled_by_wheel = self.builder.get_object('autocenter_controlled_by_wheel') + self.autocenter_controlled_by_wheel_row = self.builder.get_object('autocenter_controlled_by_wheel_row') self.ff_gain = self.builder.get_object('ff_gain') self.ff_spring_level = self.builder.get_object('ff_spring_level') self.ff_damper_level = self.builder.get_object('ff_damper_level') diff --git a/oversteer/main.ui b/oversteer/main.ui index b5ad218..9606df7 100644 --- a/oversteer/main.ui +++ b/oversteer/main.ui @@ -2166,6 +2166,49 @@ + + + 70 + True + True + False + False + + + True + False + Enable autocenter controlled by wheel. + center + 64 + + + True + False + start + Autocenter controller by wheel + + + True + True + 0 + + + + + True + True + + + + False + True + 1 + + + + + + diff --git a/oversteer/model.py b/oversteer/model.py index efd3885..45248f7 100644 --- a/oversteer/model.py +++ b/oversteer/model.py @@ -11,6 +11,7 @@ class Model: 'range': None, 'ff_gain': None, 'autocenter': None, + 'enable_autocenter': None, 'combine_pedals': None, 'spring_level': None, 'damper_level': None, @@ -28,6 +29,7 @@ class Model: 'range': 'integer', 'ff_gain': 'integer', 'autocenter': 'integer', + 'enable_autocenter': 'boolean', 'combine_pedals': 'integer', 'spring_level': 'integer', 'damper_level': 'integer', @@ -75,6 +77,7 @@ def read_device_settings(self): 'range': self.device.get_range(), 'ff_gain': self.device.get_ff_gain(), 'autocenter': self.device.get_autocenter(), + 'enable_autocenter': self.device.get_autocenter_controlled_by_wheel(), 'combine_pedals': self.device.get_combine_pedals(), 'spring_level': self.device.get_spring_level(), 'damper_level': self.device.get_damper_level(), @@ -193,6 +196,13 @@ def set_autocenter(self, value): def get_autocenter(self): return self.data['autocenter'] + def set_autocenter_controlled_by_wheel(self, value): + if self.set_if_changed('enable_autocenter', value): + self.device.set_autocenter_controlled_by_wheel(value) + + def get_autocenter_controlled_by_wheel(selfe): + return self.data['enable_autocenter'] + def set_combine_pedals(self, value): value = int(value) if self.set_if_changed('combine_pedals', value): @@ -294,6 +304,7 @@ def flush_ui(self, data = None): self.ui.set_range(data['range']) self.ui.set_ff_gain(data['ff_gain']) self.ui.set_autocenter(data['autocenter']) + self.ui.set_autocenter_controlled_by_wheel(data['enable_autocenter']) self.ui.set_combine_pedals(data['combine_pedals']) self.ui.set_spring_level(data['spring_level']) self.ui.set_damper_level(data['damper_level'])