mirror of
https://github.com/marcriera/ddgo-converter.git
synced 2025-04-19 18:39:29 +02:00
Add threading, allow mapping events one-to-many
This commit is contained in:
parent
5052407e53
commit
9712d26508
5 changed files with 77 additions and 25 deletions
|
@ -55,24 +55,25 @@ class SwitchGamepad(PhysicalGamepad):
|
||||||
# time.sleep(5)
|
# time.sleep(5)
|
||||||
# print("Read from ZKNS-001 correct")
|
# print("Read from ZKNS-001 correct")
|
||||||
# return InputEvent(InputEvent.EventType.PRESS_BUTTON, InputEvent.Button.BUTTON_A)
|
# return InputEvent(InputEvent.EventType.PRESS_BUTTON, InputEvent.Button.BUTTON_A)
|
||||||
print(self.device.active_keys())
|
|
||||||
select([self.device], [], [], 5)
|
select([self.device], [], [], 5)
|
||||||
try:
|
try:
|
||||||
event = self.device.read_one()
|
event = self.device.read_one()
|
||||||
|
input_events = []
|
||||||
if event is not None:
|
if event is not None:
|
||||||
if event.type == evdev.ecodes.EV_KEY:
|
if event.type == evdev.ecodes.EV_KEY:
|
||||||
match event.code:
|
match event.code:
|
||||||
case 304: # Y
|
case 304: # Y
|
||||||
return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_A)
|
input_events.append(InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_A))
|
||||||
case 305: # B
|
case 305: # B
|
||||||
return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_B)
|
input_events.append(InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_B))
|
||||||
case 306: # A
|
case 306: # A
|
||||||
return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_C)
|
input_events.append(InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_C))
|
||||||
case 307: # X
|
case 307: # X
|
||||||
return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_D)
|
input_events.append(InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_D))
|
||||||
case 312: # MINUS
|
case 312: # MINUS
|
||||||
return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_SELECT)
|
input_events.append(InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_SELECT))
|
||||||
case 313: # PLUS
|
case 313: # PLUS
|
||||||
return InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_START)
|
input_events.append(InputEvent(InputEvent.EventType(event.value), InputEvent.Button.BUTTON_START))
|
||||||
|
return input_events
|
||||||
except OSError:
|
except OSError:
|
||||||
return (InputEvent(InputEvent.EventType.ERROR, None))
|
return [InputEvent(InputEvent.EventType.ERROR, None)]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import sys
|
import sys
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt, QTimer
|
||||||
from PyQt5.QtWidgets import QMainWindow, QTableWidgetItem, QHeaderView
|
from PyQt5.QtWidgets import QMainWindow, QTableWidgetItem, QHeaderView
|
||||||
|
import threading
|
||||||
from gui.main_ui import Ui_MainWindow
|
from gui.main_ui import Ui_MainWindow
|
||||||
import gamepads.physical as gamepad_physical
|
import gamepads.physical as gamepad_physical
|
||||||
import gamepads.emulated as gamepad_emulated
|
import gamepads.emulated as gamepad_emulated
|
||||||
|
@ -13,6 +14,8 @@ class MainWindow(QMainWindow):
|
||||||
self._gamepad_handler = gamepad_handler
|
self._gamepad_handler = gamepad_handler
|
||||||
self._gui = Ui_MainWindow()
|
self._gui = Ui_MainWindow()
|
||||||
self._gui.setupUi(self)
|
self._gui.setupUi(self)
|
||||||
|
self._emuthread = None
|
||||||
|
self._emuthread_stop = threading.Event()
|
||||||
|
|
||||||
self.gamepad_model = GamepadModel(self._gamepad_handler.find_gamepads())
|
self.gamepad_model = GamepadModel(self._gamepad_handler.find_gamepads())
|
||||||
self._gui.tableView_physicalControllerList.setModel(self.gamepad_model)
|
self._gui.tableView_physicalControllerList.setModel(self.gamepad_model)
|
||||||
|
@ -24,11 +27,18 @@ class MainWindow(QMainWindow):
|
||||||
|
|
||||||
self._gui.pushButton_physicalControllerRefresh.clicked.connect(self.controller_list_refresh)
|
self._gui.pushButton_physicalControllerRefresh.clicked.connect(self.controller_list_refresh)
|
||||||
self._gui.pushButton_emulatedControllerStart.clicked.connect(self.controller_emulator_start)
|
self._gui.pushButton_emulatedControllerStart.clicked.connect(self.controller_emulator_start)
|
||||||
|
self._gui.pushButton_emulatedControllerStop.clicked.connect(self.controller_emulator_stop)
|
||||||
|
|
||||||
|
self._gui.pushButton_emulatedControllerStop.setVisible(False)
|
||||||
|
|
||||||
|
def closeEvent(self, event):
|
||||||
|
self._emuthread_stop.set()
|
||||||
|
|
||||||
def controller_list_refresh(self):
|
def controller_list_refresh(self):
|
||||||
self.gamepad_model.beginResetModel()
|
self.gamepad_model.beginResetModel()
|
||||||
self.gamepad_model.gamepads = self._gamepad_handler.find_gamepads()
|
self.gamepad_model.gamepads = self._gamepad_handler.find_gamepads()
|
||||||
self.gamepad_model.endResetModel()
|
self.gamepad_model.endResetModel()
|
||||||
|
self.controller_list_selection_changed()
|
||||||
|
|
||||||
def controller_list_selection_changed(self):
|
def controller_list_selection_changed(self):
|
||||||
enabled = False
|
enabled = False
|
||||||
|
@ -37,10 +47,41 @@ class MainWindow(QMainWindow):
|
||||||
enabled = True
|
enabled = True
|
||||||
self._gui.pushButton_emulatedControllerStart.setEnabled(enabled)
|
self._gui.pushButton_emulatedControllerStart.setEnabled(enabled)
|
||||||
|
|
||||||
|
def lock_interface(self,):
|
||||||
|
self._gui.pushButton_emulatedControllerStart.setVisible(False)
|
||||||
|
self._gui.pushButton_emulatedControllerStop.setVisible(True)
|
||||||
|
self._gui.tableView_physicalControllerList.setEnabled(False)
|
||||||
|
self._gui.pushButton_physicalControllerRefresh.setEnabled(False)
|
||||||
|
self._gui.pushButton_physicalControllerConfig.setEnabled(False)
|
||||||
|
self._gui.comboBox_emulatedControllerModel.setEnabled(False)
|
||||||
|
|
||||||
|
def unlock_interface(self,):
|
||||||
|
self._gui.pushButton_emulatedControllerStart.setVisible(True)
|
||||||
|
self._gui.pushButton_emulatedControllerStop.setVisible(False)
|
||||||
|
self._gui.tableView_physicalControllerList.setEnabled(True)
|
||||||
|
self._gui.pushButton_physicalControllerRefresh.setEnabled(True)
|
||||||
|
self._gui.pushButton_physicalControllerConfig.setEnabled(True)
|
||||||
|
self._gui.comboBox_emulatedControllerModel.setEnabled(True)
|
||||||
|
|
||||||
def controller_emulator_start(self):
|
def controller_emulator_start(self):
|
||||||
self._gui.pushButton_emulatedControllerStart.setEnabled(False)
|
self.lock_interface()
|
||||||
|
self._gui.statusbar.showMessage("Gamepad emulator running...")
|
||||||
rows = self._gui.tableView_physicalControllerList.selectionModel().selectedRows()
|
rows = self._gui.tableView_physicalControllerList.selectionModel().selectedRows()
|
||||||
if rows:
|
if rows:
|
||||||
gamepad = self.gamepad_model.gamepads[rows[0].row()]
|
gamepad = self.gamepad_model.gamepads[rows[0].row()]
|
||||||
emulated_gamepad = gamepad_emulated.PC2HandleGamepad()
|
emulated_gamepad = gamepad_emulated.PC2HandleGamepad()
|
||||||
self._gamepad_handler.start_gamepad_emulator(gamepad, emulated_gamepad)
|
self._emuthread = threading.Thread(target=self._gamepad_handler.run_gamepad_emulator, args=(gamepad, emulated_gamepad, self._emuthread_stop))
|
||||||
|
self._emuthread.start()
|
||||||
|
|
||||||
|
def controller_emulator_stop(self):
|
||||||
|
self._gui.statusbar.showMessage("Stopping gamepad emulator...")
|
||||||
|
self._emuthread_stop.set()
|
||||||
|
self._emuthread.join(timeout=0.05)
|
||||||
|
if self._emuthread.is_alive():
|
||||||
|
QTimer.singleShot(50, self.controller_emulator_stop)
|
||||||
|
return
|
||||||
|
self._emuthread_stop.clear()
|
||||||
|
self.unlock_interface()
|
||||||
|
self.controller_list_refresh()
|
||||||
|
self._gui.statusbar.showMessage("Gamepad emulator stopped successfully!", 5000)
|
||||||
|
|
||||||
|
|
|
@ -70,8 +70,8 @@ class Ui_MainWindow(object):
|
||||||
sizePolicy.setVerticalStretch(0)
|
sizePolicy.setVerticalStretch(0)
|
||||||
sizePolicy.setHeightForWidth(self.comboBox_emulatedControllerModel.sizePolicy().hasHeightForWidth())
|
sizePolicy.setHeightForWidth(self.comboBox_emulatedControllerModel.sizePolicy().hasHeightForWidth())
|
||||||
self.comboBox_emulatedControllerModel.setSizePolicy(sizePolicy)
|
self.comboBox_emulatedControllerModel.setSizePolicy(sizePolicy)
|
||||||
|
self.comboBox_emulatedControllerModel.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents)
|
||||||
self.comboBox_emulatedControllerModel.setObjectName("comboBox_emulatedControllerModel")
|
self.comboBox_emulatedControllerModel.setObjectName("comboBox_emulatedControllerModel")
|
||||||
self.comboBox_emulatedControllerModel.addItem("")
|
|
||||||
self.horizontalLayout.addWidget(self.comboBox_emulatedControllerModel)
|
self.horizontalLayout.addWidget(self.comboBox_emulatedControllerModel)
|
||||||
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
self.horizontalLayout.addItem(spacerItem1)
|
self.horizontalLayout.addItem(spacerItem1)
|
||||||
|
@ -79,6 +79,9 @@ class Ui_MainWindow(object):
|
||||||
self.pushButton_emulatedControllerStart.setEnabled(False)
|
self.pushButton_emulatedControllerStart.setEnabled(False)
|
||||||
self.pushButton_emulatedControllerStart.setObjectName("pushButton_emulatedControllerStart")
|
self.pushButton_emulatedControllerStart.setObjectName("pushButton_emulatedControllerStart")
|
||||||
self.horizontalLayout.addWidget(self.pushButton_emulatedControllerStart)
|
self.horizontalLayout.addWidget(self.pushButton_emulatedControllerStart)
|
||||||
|
self.pushButton_emulatedControllerStop = QtWidgets.QPushButton(self.groupBox_emulatedController)
|
||||||
|
self.pushButton_emulatedControllerStop.setObjectName("pushButton_emulatedControllerStop")
|
||||||
|
self.horizontalLayout.addWidget(self.pushButton_emulatedControllerStop)
|
||||||
self.verticalLayout_main.addWidget(self.groupBox_emulatedController)
|
self.verticalLayout_main.addWidget(self.groupBox_emulatedController)
|
||||||
self.gridLayout.addLayout(self.verticalLayout_main, 0, 0, 1, 1)
|
self.gridLayout.addLayout(self.verticalLayout_main, 0, 0, 1, 1)
|
||||||
MainWindow.setCentralWidget(self.centralwidget)
|
MainWindow.setCentralWidget(self.centralwidget)
|
||||||
|
@ -97,5 +100,5 @@ class Ui_MainWindow(object):
|
||||||
self.pushButton_physicalControllerConfig.setText(_translate("MainWindow", "Configuration"))
|
self.pushButton_physicalControllerConfig.setText(_translate("MainWindow", "Configuration"))
|
||||||
self.groupBox_emulatedController.setTitle(_translate("MainWindow", "Emulated controller"))
|
self.groupBox_emulatedController.setTitle(_translate("MainWindow", "Emulated controller"))
|
||||||
self.label_emulatedControllerModel.setText(_translate("MainWindow", "Model"))
|
self.label_emulatedControllerModel.setText(_translate("MainWindow", "Model"))
|
||||||
self.comboBox_emulatedControllerModel.setItemText(0, _translate("MainWindow", "Two-handle controller for PC (DGOC-44U)"))
|
|
||||||
self.pushButton_emulatedControllerStart.setText(_translate("MainWindow", "Start"))
|
self.pushButton_emulatedControllerStart.setText(_translate("MainWindow", "Start"))
|
||||||
|
self.pushButton_emulatedControllerStop.setText(_translate("MainWindow", "Stop"))
|
||||||
|
|
|
@ -130,11 +130,9 @@
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<property name="sizeAdjustPolicy">
|
||||||
<property name="text">
|
<enum>QComboBox::AdjustToContents</enum>
|
||||||
<string>Two-handle controller for PC (DGOC-44U)</string>
|
</property>
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -160,6 +158,13 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="pushButton_emulatedControllerStop">
|
||||||
|
<property name="text">
|
||||||
|
<string>Stop</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from evdev import InputDevice, list_devices, ecodes as e, UInput, AbsInfo
|
from evdev import InputDevice, list_devices, ecodes as e, UInput, AbsInfo
|
||||||
|
import threading
|
||||||
import events.input as input_events
|
import events.input as input_events
|
||||||
import gamepads.physical as gamepad_physical
|
import gamepads.physical as gamepad_physical
|
||||||
import gamepads.emulated as gamepad_emulated
|
import gamepads.emulated as gamepad_emulated
|
||||||
|
@ -15,13 +16,14 @@ class GamepadHandler:
|
||||||
gamepads.append(gamepad_physical.create_gamepad(0x0f0d, 0x00c1, "Test gamepad"))
|
gamepads.append(gamepad_physical.create_gamepad(0x0f0d, 0x00c1, "Test gamepad"))
|
||||||
return gamepads
|
return gamepads
|
||||||
|
|
||||||
def start_gamepad_emulator(gamepad, emulated_gamepad):
|
def run_gamepad_emulator(gamepad, emulated_gamepad, stop_event):
|
||||||
while True:
|
while not stop_event.is_set():
|
||||||
event = gamepad.read_input()
|
events = gamepad.read_input()
|
||||||
if event is not None:
|
if events is not None:
|
||||||
if event.type == input_events.InputEvent.EventType.ERROR:
|
for event in events:
|
||||||
break
|
if event.type == input_events.InputEvent.EventType.ERROR:
|
||||||
emulated_gamepad.write_input(event)
|
break
|
||||||
|
emulated_gamepad.write_input(event)
|
||||||
|
|
||||||
|
|
||||||
""" cap = {
|
""" cap = {
|
||||||
|
|
Loading…
Add table
Reference in a new issue