Commit 7fd78120 authored by Georgiy Yankovskiy's avatar Georgiy Yankovskiy

Basic gamepad support via PyGame Community (todo: gamepad polling terminate)

parent a14cd05f
...@@ -10,10 +10,13 @@ from ingame.models.GamesModel import GamesModel ...@@ -10,10 +10,13 @@ from ingame.models.GamesModel import GamesModel
def main(): def main():
app = QGuiApplication(sys.argv) app = QGuiApplication(sys.argv)
app_model = App()
app.aboutToQuit.connect(app_model.close_event)
qml_file = Path(__file__).resolve().parent / "../qml/qml.qml" qml_file = Path(__file__).resolve().parent / "../qml/qml.qml"
engine = QQmlApplicationEngine() engine = QQmlApplicationEngine()
app_model = App()
context = engine.rootContext() context = engine.rootContext()
context.setContextProperty("core_app", app_model) context.setContextProperty("core_app", app_model)
......
...@@ -4,9 +4,13 @@ import os.path ...@@ -4,9 +4,13 @@ import os.path
import subprocess import subprocess
from time import sleep from time import sleep
from pathlib import Path from pathlib import Path
from typing import AnyStr, Union
from PySide6 import QtCore from PySide6 import QtCore
from os.path import expanduser from os.path import expanduser
from desktop_parser import DesktopFile from desktop_parser import DesktopFile
from ingame.models.Gamepad import Gamepad
from ingame.models.GamesModel import Game, GamesModel from ingame.models.GamesModel import Game, GamesModel
from PySide6.QtCore import Property, Signal, Slot, QObject, Qt from PySide6.QtCore import Property, Signal, Slot, QObject, Qt
...@@ -22,13 +26,21 @@ class App(QtCore.QObject): ...@@ -22,13 +26,21 @@ class App(QtCore.QObject):
game_started = Signal(bool, name="gameStarted") game_started = Signal(bool, name="gameStarted")
game_ended = Signal(bool, name="gameEnded") game_ended = Signal(bool, name="gameEnded")
gamepad_clicked_LB = Signal(bool, name="gamepadClickedLB")
gamepad_clicked_RB = Signal(bool, name="gamepadClickedRB")
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.games_model = GamesModel() self.games_model: GamesModel = GamesModel()
self.home = expanduser('~') self.home: AnyStr = expanduser('~')
self.config_location = '/.config/PortProton.conf' self.config_location: str = '/.config/PortProton.conf'
self.portproton_location = '' self.portproton_location: str = ''
self.running_game_process = None self.running_game_process: Union[subprocess.Popen, None] = None
self.gamepad: Gamepad = Gamepad()
self.gamepad.lb_clicked = lambda: self.gamepad_clicked_LB.emit(True)
self.gamepad.rb_clicked = lambda: self.gamepad_clicked_RB.emit(True)
self.setup() self.setup()
def setup(self): def setup(self):
...@@ -72,12 +84,24 @@ class App(QtCore.QObject): ...@@ -72,12 +84,24 @@ class App(QtCore.QObject):
self.games_model.add_game(Game(name=_name, icon=_icon, exec=_exec)) self.games_model.add_game(Game(name=_name, icon=_icon, exec=_exec))
self.gamepad.run()
except FileNotFoundError: except FileNotFoundError:
print('File not found') print('File not found')
except Exception as e: except Exception as e:
print('An error occurred', e) print('An error occurred', e)
pass pass
### CALLBACKS ###
def close_event(self):
# do stuff
# if can_exit:
self.gamepad.terminate()
# event.accept() # let the window close
# else:
# event.ignore()
### SLOTS ### ### SLOTS ###
@Slot(str) @Slot(str)
......
import subprocess
import threading
from typing import Union
import pygame
from pygame.joystick import Joystick
class Gamepad:
LB_BUTTON = 4
RB_BUTTON = 5
def __init__(self):
self.joystick: Union[Joystick, None] = None
self.terminated: bool = False
self.last_rb_clicked: bool = False
self.last_lb_clicked: bool = False
self.lb_clicked: () = lambda: None
self.rb_clicked: () = lambda: None
self.thread: Union[threading.Thread, None] = None
pygame.init()
pygame.joystick.init()
def run(self):
joystick_count = pygame.joystick.get_count()
if joystick_count == 0:
print("No joysticks found.")
else:
self.joystick = pygame.joystick.Joystick(0)
self.joystick.init()
self.thread = threading.Thread(target=lambda t, _exec: t.cycle(), args=(self, exec))
self.thread.start()
def cycle(self):
while not self.terminated:
# pygame.event.pump()
pygame.event.wait()
lb_button = self.joystick.get_button(self.LB_BUTTON)
rb_button = self.joystick.get_button(self.RB_BUTTON)
# LB
if lb_button and not self.last_lb_clicked:
self.last_lb_clicked = not self.last_lb_clicked
self.lb_clicked()
if not lb_button and self.last_lb_clicked:
self.last_lb_clicked = not self.last_lb_clicked
# RB
if rb_button and not self.last_rb_clicked:
self.last_rb_clicked = not self.last_rb_clicked
self.rb_clicked()
if not rb_button and self.last_rb_clicked:
self.last_rb_clicked = not self.last_rb_clicked
# print(f"Button {self.LB_BUTTON}: {lb_button}")
# print(f"Button {self.RB_BUTTON}: {rb_button}")
# for i in range(self.joystick.get_numaxes()):
# axis = self.joystick.get_axis(i)
# print(f"Axis {i}: {axis}")
#
# for i in range(self.joystick.get_numbuttons()):
# button = self.joystick.get_button(i)
# print(f"Button {i}: {button}")
def terminate(self):
# TODO
# self.thread.
pass
pass
...@@ -235,6 +235,72 @@ files = [ ...@@ -235,6 +235,72 @@ files = [
] ]
[[package]] [[package]]
name = "pygame"
version = "2.5.2"
description = "Python Game Development"
optional = false
python-versions = ">=3.6"
files = [
{file = "pygame-2.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a0769eb628c818761755eb0a0ca8216b95270ea8cbcbc82227e39ac9644643da"},
{file = "pygame-2.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed9a3d98adafa0805ccbaaff5d2996a2b5795381285d8437a4a5d248dbd12b4a"},
{file = "pygame-2.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30d1618672a55e8c6669281ba264464b3ab563158e40d89e8c8b3faa0febebd"},
{file = "pygame-2.5.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:39690e9be9baf58b7359d1f3b2336e1fd6f92fedbbce42987be5df27f8d30718"},
{file = "pygame-2.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03879ec299c9f4ba23901b2649a96b2143f0a5d787f0b6c39469989e2320caf1"},
{file = "pygame-2.5.2-cp310-cp310-win32.whl", hash = "sha256:74e1d6284100e294f445832e6f6343be4fe4748decc4f8a51131ae197dae8584"},
{file = "pygame-2.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:485239c7d32265fd35b76ae8f64f34b0637ae11e69d76de15710c4b9edcc7c8d"},
{file = "pygame-2.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:34646ca20e163dc6f6cf8170f1e12a2e41726780112594ac061fa448cf7ccd75"},
{file = "pygame-2.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3b8a6e351665ed26ea791f0e1fd649d3f483e8681892caef9d471f488f9ea5ee"},
{file = "pygame-2.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc346965847aef00013fa2364f41a64f068cd096dcc7778fc306ca3735f0eedf"},
{file = "pygame-2.5.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35632035fd81261f2d797fa810ea8c46111bd78ceb6089d52b61ed7dc3c5d05f"},
{file = "pygame-2.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e24d05184e4195fe5ebcdce8b18ecb086f00182b9ae460a86682d312ce8d31f"},
{file = "pygame-2.5.2-cp311-cp311-win32.whl", hash = "sha256:f02c1c7505af18d426d355ac9872bd5c916b27f7b0fe224749930662bea47a50"},
{file = "pygame-2.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:6d58c8cf937815d3b7cdc0fa9590c5129cb2c9658b72d00e8a4568dea2ff1d42"},
{file = "pygame-2.5.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:1a2a43802bb5e89ce2b3b775744e78db4f9a201bf8d059b946c61722840ceea8"},
{file = "pygame-2.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1c289f2613c44fe70a1e40769de4a49c5ab5a29b9376f1692bb1a15c9c1c9bfa"},
{file = "pygame-2.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:074aa6c6e110c925f7f27f00c7733c6303407edc61d738882985091d1eb2ef17"},
{file = "pygame-2.5.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe0228501ec616779a0b9c4299e837877783e18df294dd690b9ab0eed3d8aaab"},
{file = "pygame-2.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31648d38ecdc2335ffc0e38fb18a84b3339730521505dac68514f83a1092e3f4"},
{file = "pygame-2.5.2-cp312-cp312-win32.whl", hash = "sha256:224c308856334bc792f696e9278e50d099a87c116f7fc314cd6aa3ff99d21592"},
{file = "pygame-2.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:dd2d2650faf54f9a0f5bd0db8409f79609319725f8f08af6507a0609deadcad4"},
{file = "pygame-2.5.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9b30bc1220c457169571aac998e54b013aaeb732d2fd8744966cb1cfab1f61d1"},
{file = "pygame-2.5.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78fcd7643358b886a44127ff7dec9041c056c212b3a98977674f83f99e9b12d3"},
{file = "pygame-2.5.2-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:35cf093a51cb294ede56c29d4acf41538c00f297fcf78a9b186fb7d23c0577b6"},
{file = "pygame-2.5.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fe323acbf53a0195c8c98b1b941eba7ac24e3e2b28ae48e8cda566f15fc4945"},
{file = "pygame-2.5.2-cp36-cp36m-win32.whl", hash = "sha256:5697528266b4716d9cdd44a5a1d210f4d86ef801d0f64ca5da5d0816704009d9"},
{file = "pygame-2.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edda1f7cff4806a4fa39e0e8ccd75f38d1d340fa5fc52d8582ade87aca247d92"},
{file = "pygame-2.5.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9bd738fd4ecc224769d0b4a719f96900a86578e26e0105193658a32966df2aae"},
{file = "pygame-2.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30a8d7cf12363b4140bf2f93b5eec4028376ca1d0fe4b550588f836279485308"},
{file = "pygame-2.5.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc12e4dea3e88ea8a553de6d56a37b704dbe2aed95105889f6afeb4b96e62097"},
{file = "pygame-2.5.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b34c73cb328024f8db3cb6487a37e54000148988275d8d6e5adf99d9323c937"},
{file = "pygame-2.5.2-cp37-cp37m-win32.whl", hash = "sha256:7d0a2794649defa57ef50b096a99f7113d3d0c2e32d1426cafa7d618eadce4c7"},
{file = "pygame-2.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:41f8779f52e0f6e6e6ccb8f0b5536e432bf386ee29c721a1c22cada7767b0cef"},
{file = "pygame-2.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:677e37bc0ea7afd89dde5a88ced4458aa8656159c70a576eea68b5622ee1997b"},
{file = "pygame-2.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:47a8415d2bd60e6909823b5643a1d4ef5cc29417d817f2a214b255f6fa3a1e4c"},
{file = "pygame-2.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ff21201df6278b8ca2e948fb148ffe88f5481fd03760f381dd61e45954c7dff"},
{file = "pygame-2.5.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d29a84b2e02814b9ba925357fd2e1df78efe5e1aa64dc3051eaed95d2b96eafd"},
{file = "pygame-2.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d78485c4d21133d6b2fbb504cd544ca655e50b6eb551d2995b3aa6035928adda"},
{file = "pygame-2.5.2-cp38-cp38-win32.whl", hash = "sha256:d851247239548aa357c4a6840fb67adc2d570ce7cb56988d036a723d26b48bff"},
{file = "pygame-2.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:88d1cdacc2d3471eceab98bf0c93c14d3a8461f93e58e3d926f20d4de3a75554"},
{file = "pygame-2.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4f1559e7efe4efb9dc19d2d811d702f325d9605f9f6f9ececa39ee6890c798f5"},
{file = "pygame-2.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cf2191b756ceb0e8458a761d0c665b0c70b538570449e0d39b75a5ba94ac5cf0"},
{file = "pygame-2.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cf2257447ce7f2d6de37e5fb019d2bbe32ed05a5721ace8bc78c2d9beaf3aee"},
{file = "pygame-2.5.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75cbbfaba2b81434d62631d0b08b85fab16cf4a36e40b80298d3868927e1299"},
{file = "pygame-2.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:daca456d5b9f52e088e06a127dec182b3638a775684fb2260f25d664351cf1ae"},
{file = "pygame-2.5.2-cp39-cp39-win32.whl", hash = "sha256:3b3e619e33d11c297d7a57a82db40681f9c2c3ae1d5bf06003520b4fe30c435d"},
{file = "pygame-2.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:1822d534bb7fe756804647b6da2c9ea5d7a62d8796b2e15d172d3be085de28c6"},
{file = "pygame-2.5.2-pp36-pypy36_pp73-win32.whl", hash = "sha256:e708fc8f709a0fe1d1876489345f2e443d47f3976d33455e2e1e937f972f8677"},
{file = "pygame-2.5.2-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c13edebc43c240fb0532969e914f0ccefff5ae7e50b0b788d08ad2c15ef793e4"},
{file = "pygame-2.5.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:263b4a7cbfc9fe2055abc21b0251cc17dea6dff750f0e1c598919ff350cdbffe"},
{file = "pygame-2.5.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e58e2b0c791041e4bccafa5bd7650623ba1592b8fe62ae0a276b7d0ecb314b6c"},
{file = "pygame-2.5.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0bd67426c02ffe6c9827fc4bcbda9442fbc451d29b17c83a3c088c56fef2c90"},
{file = "pygame-2.5.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dcff6cbba1584cf7732ce1dbdd044406cd4f6e296d13bcb7fba963fb4aeefc9"},
{file = "pygame-2.5.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ce4b6c0bfe44d00bb0998a6517bd0cf9455f642f30f91bc671ad41c05bf6f6ae"},
{file = "pygame-2.5.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:68c4e8e60b725ffc7a6c6ecd9bb5fcc5ed2d6e0e2a2c4a29a8454856ef16ad63"},
{file = "pygame-2.5.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f3849f97372a3381c66955f99a0d58485ccd513c3d00c030b869094ce6997a6"},
{file = "pygame-2.5.2.tar.gz", hash = "sha256:c1b89eb5d539e7ac5cf75513125fb5f2f0a2d918b1fd6e981f23bf0ac1b1c24a"},
]
[[package]]
name = "pyqtgraph" name = "pyqtgraph"
version = "0.13.6" version = "0.13.6"
description = "Scientific Graphics and GUI Library for Python" description = "Scientific Graphics and GUI Library for Python"
...@@ -364,4 +430,4 @@ zstd = ["zstandard (>=0.18.0)"] ...@@ -364,4 +430,4 @@ zstd = ["zstandard (>=0.18.0)"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = ">=3.11,<3.13" python-versions = ">=3.11,<3.13"
content-hash = "148761a9c03181d65c945a7b21a69a2e3f3212f99d361e52b26fddd665c7cba6" content-hash = "eb8f0983d734285d3ecb312cb9109e04a91a8ab6a0c28731fa0e061144da90a0"
...@@ -14,6 +14,7 @@ shiboken6 = "^6.7.0" ...@@ -14,6 +14,7 @@ shiboken6 = "^6.7.0"
pyqtgraph = "^0.13.6" pyqtgraph = "^0.13.6"
requests = "^2.31.0" requests = "^2.31.0"
desktop-parser = "^0.1.1" desktop-parser = "^0.1.1"
pygame = "^2.5.2"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
mypy = "^1.9.0" mypy = "^1.9.0"
......
...@@ -11,13 +11,19 @@ Window { ...@@ -11,13 +11,19 @@ Window {
Connections { Connections {
target: core_app target: core_app
function onGameStarted(done) { function onGameStarted(done) {
console.log("gameStarted!!"); console.log("core_app: gameStarted");
window.scene = SceneConstants.runningScene; window.scene = SceneConstants.runningScene;
} }
function onGameEnded(done) { function onGameEnded(done) {
console.log("gameEnded!!"); console.log("core_app: gameEnded");
window.scene = SceneConstants.gameInfoScene; window.scene = SceneConstants.gameInfoScene;
} }
function onGamepadClickedLB(done){
console.log("core_app: onGamepadClickedLB");
}
function onGamepadClickedRB(done){
console.log("core_app: onGamepadClickedRB");
}
} }
id: window id: window
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment