pygameControls 0.0.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 CodingPirates
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: pygameControls
3
+ Version: 0.0.4
4
+ Summary: A simple controller class for pygame.
5
+ Home-page:
6
+ Author: Jan Lerking
7
+ Author-email:
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.12
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Dynamic: author
15
+ Dynamic: classifier
16
+ Dynamic: description
17
+ Dynamic: description-content-type
18
+ Dynamic: license-file
19
+ Dynamic: requires-python
20
+ Dynamic: summary
21
+
22
+ # PyGame-Controller
23
+
24
+ Small module to make it easy to add controller support.
@@ -0,0 +1,3 @@
1
+ # PyGame-Controller
2
+
3
+ Small module to make it easy to add controller support.
@@ -0,0 +1 @@
1
+ from . import controller
@@ -0,0 +1,31 @@
1
+ import pygame
2
+ from .controlsbase import ControlsBase
3
+ from .dualsense_controller import DualSenseController
4
+ from .dualsense_edge_controller import DualSenseEdgeController
5
+ from .logitech_f310_controller import LogitechF310Controller
6
+ from .logitech_f510_controller import LogitechF510Controller
7
+ from .logitech_f710_controller import LogitechF710Controller
8
+ from .xbox_series_x_controller import XboxSeriesXController
9
+ from .generic_controller import GenericController
10
+ from .logitech_dual_action_controller import LogitechDualActionController
11
+
12
+ __version__ = "0.0.4"
13
+
14
+ CONTROLLERS = {
15
+ "DualSense Wireless Controller": DualSenseController,
16
+ "DualSense Edge Wireless Controller": DualSenseEdgeController,
17
+ "Logitech Gamepad F310": LogitechF310Controller,
18
+ "Logitech Gamepad F510": LogitechF510Controller,
19
+ "Logitech Gamepad F710": LogitechF710Controller,
20
+ "Logitech Dual Action": LogitechDualActionController,
21
+ "X box Series X Controller": XboxSeriesXController
22
+ }
23
+
24
+ class Controllers:
25
+ def __init__(self, joy):
26
+ self.controllers = []
27
+ if not joy.get_name() in CONTROLLERS:
28
+ self.controllers.append(GenericController(joy))
29
+ else:
30
+ self.controllers.append(CONTROLLERS[joy.get_name()](joy))
31
+
@@ -0,0 +1,33 @@
1
+ """
2
+ This is an abstract baseclass for the controls of snake.
3
+ """
4
+ from abc import ABC, abstractmethod
5
+
6
+ class ControlsBase(ABC):
7
+ @abstractmethod
8
+ def handle_input(self, event):
9
+ pass
10
+
11
+ @abstractmethod
12
+ def left(self):
13
+ pass
14
+
15
+ @abstractmethod
16
+ def right(self):
17
+ pass
18
+
19
+ @abstractmethod
20
+ def up(self):
21
+ pass
22
+
23
+ @abstractmethod
24
+ def down(self):
25
+ pass
26
+
27
+ @abstractmethod
28
+ def pause(self):
29
+ pass
30
+
31
+ @abstractmethod
32
+ def rumble(self):
33
+ pass
@@ -0,0 +1,70 @@
1
+ import os
2
+ import time
3
+ import numpy as np
4
+ import sounddevice as sd
5
+ import alsaaudio
6
+ import pulsectl
7
+
8
+ class DualSenseAudio:
9
+ def __init__(self):
10
+ self.alsa_devices = self._get_alsa_devices()
11
+ self.pulse_devices = self._get_pulseaudio_devices()
12
+ self.dualsense_device = self._detect_dualsense()
13
+
14
+ def _get_alsa_devices(self):
15
+ try:
16
+ cards = alsaaudio.cards()
17
+ return cards
18
+ except Exception as e:
19
+ print("ALSA detection failed:", e)
20
+ return []
21
+
22
+ def _get_pulseaudio_devices(self):
23
+ try:
24
+ pulse = pulsectl.Pulse("dualsense-audio")
25
+ sinks = pulse.sink_list()
26
+ return sinks
27
+ except Exception as e:
28
+ print("PulseAudio detection failed:", e)
29
+ return []
30
+
31
+ def _detect_dualsense(self):
32
+ # Check ALSA names
33
+ for card in self.alsa_devices:
34
+ if "DualSense" in card:
35
+ return {'type': 'alsa', 'name': card}
36
+
37
+ # Check PulseAudio sinks
38
+ for sink in self.pulse_devices:
39
+ if "dualsense" in sink.description.lower():
40
+ return {'type': 'pulse', 'name': sink.name}
41
+
42
+ return None
43
+
44
+ def play_tone(self, frequency=440.0, duration=2.0, volume=0.5):
45
+ if not self.dualsense_device:
46
+ print("DualSense speaker not found.")
47
+ return
48
+
49
+ print(f"Playing tone on DualSense ({self.dualsense_device['type']})...")
50
+
51
+ fs = 48000 # Sample rate
52
+ t = np.linspace(0, duration, int(fs * duration), False)
53
+ tone = np.sin(frequency * 2 * np.pi * t) * volume
54
+ audio = tone.astype(np.float32)
55
+
56
+ if self.dualsense_device['type'] == 'pulse':
57
+ sd.play(audio, samplerate=fs, device=self.dualsense_device['name'])
58
+ elif self.dualsense_device['type'] == 'alsa':
59
+ device_index = self.alsa_devices.index(self.dualsense_device['name'])
60
+ sd.play(audio, samplerate=fs, device=device_index)
61
+ sd.wait()
62
+
63
+ def list_devices(self):
64
+ print("ALSA Devices:")
65
+ for card in self.alsa_devices:
66
+ print(f" - {card}")
67
+ print("\nPulseAudio Devices:")
68
+ for sink in self.pulse_devices:
69
+ print(f" - {sink.name} ({sink.description})")
70
+
@@ -0,0 +1,74 @@
1
+ from pygameControls.controlsbase import ControlsBase
2
+ from pydualsense import *
3
+
4
+ BATTERY_STATE = {
5
+ "0": "Discharging",
6
+ "1": "Charging",
7
+ "2": "Full",
8
+ "11": "Not charging",
9
+ "15": "Error",
10
+ "10": "Temp or voltage out of range"
11
+ }
12
+
13
+ class DualSenseController(ControlsBase):
14
+ def __init__(self, joy):
15
+ self.device = pydualsense()
16
+ self.device.init()
17
+ self.name = self.device.device.get_product_string()
18
+ self.powerlevel = self.device.battery.Level
19
+ self.batterystate = BATTERY_STATE[str(self.device.battery.State)]
20
+ self.set_player_id(PlayerID.PLAYER_1)
21
+ print(f"{self.name} connected")
22
+ print(f"Power level: {self.powerlevel}")
23
+ print(f"Battery state: {self.batterystate}")
24
+
25
+ def handle_input(self, event):
26
+ pass
27
+
28
+ def set_led(self, red: int, green: int, blue: int):
29
+ self.device.light.setColorI(red, green, blue)
30
+
31
+ def set_player_id(self, playerid: PlayerID):
32
+ self.device.light.setPlayerID(playerid)
33
+
34
+ def left(self):
35
+ pass
36
+
37
+ def right(self):
38
+ pass
39
+
40
+ def up(self):
41
+ pass
42
+
43
+ def down(self):
44
+ pass
45
+
46
+ def pause(self):
47
+ pass
48
+
49
+ def rumble(self):
50
+ pass
51
+
52
+ @property
53
+ def name(self) -> str:
54
+ return self._name
55
+
56
+ @name.setter
57
+ def name(self, name: str) -> None:
58
+ self._name = name
59
+
60
+ @property
61
+ def powerlevel(self) -> str:
62
+ return self._powerlevel
63
+
64
+ @powerlevel.setter
65
+ def powerlevel(self, lvl: str) -> None:
66
+ self._powerlevel = lvl
67
+
68
+ @property
69
+ def batterystate(self) -> int:
70
+ return self._batterystate
71
+
72
+ @batterystate.setter
73
+ def batterystate(self, state) -> None:
74
+ self._batterystate = state
@@ -0,0 +1,199 @@
1
+ import time
2
+ import threading
3
+ import numpy as np
4
+ import sounddevice as sd
5
+ import alsaaudio
6
+ import pulsectl
7
+ from pydualsense import *
8
+
9
+
10
+ class DualSenseEdgeController:
11
+ def __init__(self):
12
+ # DualSense input/output interface
13
+ self.ds = pydualsense()
14
+ self.ds.init()
15
+ self._listening = False
16
+ self._bindings = {}
17
+
18
+ # Audio detection
19
+ self.alsa_devices = self._get_alsa_devices()
20
+ self.pulse_devices = self._get_pulseaudio_devices()
21
+ self.dualsense_audio_device = self._detect_dualsense_audio()
22
+
23
+ print("DualSense initialized.")
24
+
25
+ # ---------------------- Device Controls ----------------------
26
+
27
+ def set_rumble(self, small_motor: int, big_motor: int):
28
+ self.ds.setRumble(small_motor, big_motor)
29
+
30
+ def stop_rumble(self):
31
+ self.set_rumble(0, 0)
32
+
33
+ def set_led_color(self, r: int, g: int, b: int):
34
+ self.ds.setLightBarColor(r, g, b)
35
+
36
+ def set_trigger_effects(self, left_mode='Off', right_mode='Off', force=0):
37
+ left = getattr(TriggerModes, left_mode.upper(), TriggerModes.Off)
38
+ right = getattr(TriggerModes, right_mode.upper(), TriggerModes.Off)
39
+ self.ds.triggerL.setMode(left)
40
+ self.ds.triggerR.setMode(right)
41
+ if force > 0:
42
+ self.ds.triggerL.setForce(force)
43
+ self.ds.triggerR.setForce(force)
44
+
45
+ # ---------------------- Predefined Rumble Patterns ----------------------
46
+
47
+ def rumble_pattern(self, pattern: str, duration: float = 1.0):
48
+ patterns = {
49
+ "pulse": self._pulse_rumble,
50
+ "heartbeat": self._heartbeat_rumble,
51
+ "buzz": self._buzz_rumble,
52
+ "wave": self._wave_rumble,
53
+ "alarm": self._alarm_rumble,
54
+ }
55
+ if pattern in patterns:
56
+ threading.Thread(target=patterns[pattern], args=(duration,), daemon=True).start()
57
+ else:
58
+ print(f"Unknown rumble pattern: {pattern}")
59
+
60
+ def _pulse_rumble(self, duration):
61
+ end = time.time() + duration
62
+ while time.time() < end:
63
+ self.set_rumble(50, 150)
64
+ time.sleep(0.2)
65
+ self.stop_rumble()
66
+ time.sleep(0.2)
67
+
68
+ def _heartbeat_rumble(self, duration):
69
+ end = time.time() + duration
70
+ while time.time() < end:
71
+ self.set_rumble(200, 200)
72
+ time.sleep(0.1)
73
+ self.stop_rumble()
74
+ time.sleep(0.1)
75
+ self.set_rumble(100, 100)
76
+ time.sleep(0.1)
77
+ self.stop_rumble()
78
+ time.sleep(0.4)
79
+
80
+ def _buzz_rumble(self, duration):
81
+ self.set_rumble(80, 255)
82
+ time.sleep(duration)
83
+ self.stop_rumble()
84
+
85
+ def _wave_rumble(self, duration):
86
+ start = time.time()
87
+ while time.time() - start < duration:
88
+ for i in range(0, 256, 25):
89
+ self.set_rumble(i, 255 - i)
90
+ time.sleep(0.05)
91
+ for i in reversed(range(0, 256, 25)):
92
+ self.set_rumble(i, 255 - i)
93
+ time.sleep(0.05)
94
+ self.stop_rumble()
95
+
96
+ def _alarm_rumble(self, duration):
97
+ end = time.time() + duration
98
+ while time.time() < end:
99
+ self.set_rumble(255, 0)
100
+ time.sleep(0.1)
101
+ self.set_rumble(0, 255)
102
+ time.sleep(0.1)
103
+ self.stop_rumble()
104
+
105
+ # ---------------------- Input Listener + Bindings ----------------------
106
+
107
+ def bind(self, button: str, action: callable):
108
+ """Bind a button to a callable. Ex: controller.bind('cross', lambda: rumble_pattern('buzz'))"""
109
+ self._bindings[button] = action
110
+
111
+ def start_input_listener(self):
112
+ def listen():
113
+ while self._listening:
114
+ #self.ds.update()
115
+ for button, action in self._bindings.items():
116
+ if getattr(self.ds, button, False):
117
+ action()
118
+ self._listening = True
119
+ thread = threading.Thread(target=listen, daemon=True)
120
+ thread.start()
121
+
122
+ def stop_input_listener(self):
123
+ self._listening = False
124
+
125
+ # ---------------------- Audio Output ----------------------
126
+
127
+ def _get_alsa_devices(self):
128
+ try:
129
+ return alsaaudio.cards()
130
+ except Exception:
131
+ return []
132
+
133
+ def _get_pulseaudio_devices(self):
134
+ try:
135
+ pulse = pulsectl.Pulse("dualsense-audio")
136
+ return pulse.sink_list()
137
+ except Exception:
138
+ return []
139
+
140
+ def _detect_dualsense_audio(self):
141
+ # Check ALSA names
142
+ for card in self.alsa_devices:
143
+ if "DualSense" in card:
144
+ return {'type': 'alsa', 'name': card}
145
+
146
+ # Check PulseAudio sinks
147
+ for sink in self.pulse_devices:
148
+ if "dualsense" in sink.description.lower():
149
+ return {'type': 'pulse', 'name': sink.name}
150
+
151
+ return None
152
+
153
+ def play_tone(self, frequency=440.0, duration=2.0, volume=0.5):
154
+ if not self.dualsense_audio_device:
155
+ print("DualSense speaker not detected.")
156
+ return
157
+
158
+ print(f"Playing tone on DualSense ({self.dualsense_audio_device['type']})...")
159
+
160
+ fs = 48000 # Sample rate
161
+ t = np.linspace(0, duration, int(fs * duration), False)
162
+ tone = np.sin(frequency * 2 * np.pi * t) * volume
163
+ audio = tone.astype(np.float32)
164
+
165
+ try:
166
+ if self.dualsense_audio_device['type'] == 'pulse':
167
+ sd.play(audio, samplerate=fs, device=self.dualsense_audio_device['name'])
168
+ elif self.dualsense_audio_device['type'] == 'alsa':
169
+ device_index = self.alsa_devices.index(self.dualsense_audio_device['name'])
170
+ sd.play(audio, samplerate=fs, device=device_index)
171
+ sd.wait()
172
+ except Exception as e:
173
+ print("Failed to play tone:", e)
174
+
175
+ def list_audio_devices(self):
176
+ print("ALSA Devices:")
177
+ for card in self.alsa_devices:
178
+ print(f" - {card}")
179
+ print("\nPulseAudio Devices:")
180
+ for sink in self.pulse_devices:
181
+ print(f" - {sink.name} ({sink.description})")
182
+
183
+ # ---------------------- Cleanup ----------------------
184
+
185
+ def close(self):
186
+ self.ds.close()
187
+
188
+ if __name__ == "__main__":
189
+
190
+ controller = DualSenseController()
191
+
192
+ # Bind buttons to patterns
193
+ controller.bind("cross", lambda: controller.rumble_pattern("heartbeat", 1.5))
194
+ controller.bind("circle", lambda: controller.rumble_pattern("buzz", 0.5))
195
+ controller.bind("triangle", lambda: controller.rumble_pattern("pulse", 2))
196
+ controller.bind("square", lambda: controller.set_led_color(255, 0, 0))
197
+
198
+ # Start listening
199
+ controller.start_input_listener()
@@ -0,0 +1,45 @@
1
+ import pygame
2
+ from pygameControls.controlsbase import ControlsBase
3
+
4
+ class GenericController(ControlsBase):
5
+ def __init__(self, joy):
6
+ self.device = joy
7
+ self.instance_id: int = self.device.get_instance_id()
8
+ self.name = self.device.get_name()
9
+ self.guid = self.device.get_guid()
10
+ self.numaxis: int = self.device.get_numaxes()
11
+ self.axis: list = [self.device.get_axis(a) for a in range(self.numaxis)]
12
+ self.numhats: int = self.device.get_numhats()
13
+ self.hats: list = [self.device.get_hat(h) for h in range(self.numhats)]
14
+ self.numbuttons: int = self.device.get_numbuttons()
15
+ self.buttons: list = [self.device.get_button(b) for b in range(self.numbuttons)]
16
+
17
+ def handle_input(self, event):
18
+ pass
19
+
20
+ def left(self):
21
+ pass
22
+
23
+ def right(self):
24
+ pass
25
+
26
+ def up(self):
27
+ pass
28
+
29
+ def down(self):
30
+ pass
31
+
32
+ def pause(self):
33
+ pass
34
+
35
+ def rumble(self):
36
+ pass
37
+
38
+ @property
39
+ def name(self) -> str:
40
+ return self._name
41
+
42
+ @name.setter
43
+ def name(self, name: str) -> None:
44
+ self._name = name
45
+
@@ -0,0 +1,74 @@
1
+ """
2
+ Logitech F310 Controller class.
3
+ This controller is a usb controller, with the following features.
4
+ (XInput mode)
5
+ 6 axis
6
+ 11 buttons
7
+ 1 hat
8
+
9
+ (DirectInput mode)
10
+ 4 axis
11
+ 12 buttons
12
+ 1 hat
13
+ """
14
+
15
+ import pygame
16
+ from pygameControls.controlsbase import ControlsBase
17
+ from enum import Enum
18
+
19
+ class InputMode(Enum):
20
+ DirectInput = 1
21
+ XInput = 2
22
+
23
+ class LogitechDualActionController(ControlsBase):
24
+ def __init__(self, joy):
25
+ self.device = joy
26
+ self.instance_id: int = self.device.get_instance_id()
27
+ self.name = self.device.get_name()
28
+ self.guid = self.device.get_guid()
29
+ self.powerlevel = self.device.get_power_level()
30
+ self.numaxis: int = self.device.get_numaxes()
31
+ self.axis: list = [self.device.get_axis(a) for a in range(self.numaxis)]
32
+ self.numhats: int = self.device.get_numhats()
33
+ self.hats: list = [self.device.get_hat(h) for h in range(self.numhats)]
34
+ self.numbuttons: int = self.device.get_numbuttons()
35
+ self.buttons: list = [self.device.get_button(b) for b in range(self.numbuttons)]
36
+ self.input_mode = InputMode.DirectInput
37
+
38
+ def handle_input(self, event):
39
+ pass
40
+
41
+ def left(self):
42
+ pass
43
+
44
+ def right(self):
45
+ pass
46
+
47
+ def up(self):
48
+ pass
49
+
50
+ def down(self):
51
+ pass
52
+
53
+ def pause(self):
54
+ pass
55
+
56
+ def rumble(self):
57
+ pass
58
+
59
+ @property
60
+ def name(self) -> str:
61
+ return self._name
62
+
63
+ @name.setter
64
+ def name(self, name: str) -> None:
65
+ self._name = name
66
+
67
+ @property
68
+ def input_mode(self) -> int:
69
+ return self._inputmode
70
+
71
+ @input_mode.setter
72
+ def input_mode(self, mode: int) -> None:
73
+ self._inputmode = mode
74
+
@@ -0,0 +1,74 @@
1
+ """
2
+ Logitech F310 Controller class.
3
+ This controller is a usb controller, with the following features.
4
+ (XInput mode)
5
+ 6 axis
6
+ 11 buttons
7
+ 1 hat
8
+
9
+ (DirectInput mode)
10
+ 4 axis
11
+ 12 buttons
12
+ 1 hat
13
+ """
14
+
15
+ import pygame
16
+ from pygameControls.controlsbase import ControlsBase
17
+ from enum import Enum
18
+
19
+ class InputMode(Enum):
20
+ DirectInput = 1
21
+ XInput = 2
22
+
23
+ class LogitechF310Controller(ControlsBase):
24
+ def __init__(self, joy):
25
+ self.device = joy
26
+ self.instance_id: int = self.device.get_instance_id()
27
+ self.name = self.device.get_name()
28
+ self.guid = self.device.get_guid()
29
+ self.powerlevel = self.device.get_power_level()
30
+ self.numaxis: int = self.device.get_numaxes()
31
+ self.axis: list = [self.device.get_axis(a) for a in range(self.numaxis)]
32
+ self.numhats: int = self.device.get_numhats()
33
+ self.hats: list = [self.device.get_hat(h) for h in range(self.numhats)]
34
+ self.numbuttons: int = self.device.get_numbuttons()
35
+ self.buttons: list = [self.device.get_button(b) for b in range(self.numbuttons)]
36
+ self.input_mode = InputMode.XInput
37
+
38
+ def handle_input(self, event):
39
+ pass
40
+
41
+ def left(self):
42
+ pass
43
+
44
+ def right(self):
45
+ pass
46
+
47
+ def up(self):
48
+ pass
49
+
50
+ def down(self):
51
+ pass
52
+
53
+ def pause(self):
54
+ pass
55
+
56
+ def rumble(self):
57
+ pass
58
+
59
+ @property
60
+ def name(self) -> str:
61
+ return self._name
62
+
63
+ @name.setter
64
+ def name(self, name: str) -> None:
65
+ self._name = name
66
+
67
+ @property
68
+ def input_mode(self) -> int:
69
+ return self._inputmode
70
+
71
+ @input_mode.setter
72
+ def input_mode(self, mode: int) -> None:
73
+ self._inputmode = mode
74
+
@@ -0,0 +1,108 @@
1
+ """
2
+ Logitech F310 Controller class.
3
+ This controller is a usb controller, with the following features.
4
+ (XInput mode)
5
+ 6 axis
6
+ 11 buttons
7
+ 1 hat
8
+
9
+ (DirectInput mode)
10
+ 4 axis
11
+ 12 buttons
12
+ 1 hat
13
+ """
14
+
15
+ import pygame
16
+ from pygameControls.controlsbase import ControlsBase
17
+ from enum import Enum
18
+
19
+ class InputMode(Enum):
20
+ DirectInput = 1
21
+ XInput = 2
22
+
23
+ class ConnectionType(Enum):
24
+ WIRED = 1
25
+ WIRELESS = 2
26
+
27
+ class LogitechF510Controller(ControlsBase):
28
+ def __init__(self, joy):
29
+ self.device = joy
30
+ self.instance_id: int = self.device.get_instance_id()
31
+ self.name = self.device.get_name()
32
+ self.numaxis: int = self.device.get_numaxis()
33
+ self.axis: list = []
34
+ self.numhats: int = self.device.get_numhats()
35
+ self.hats: list = []
36
+ self.numbuttons: int = self.device.get_numbuttons()
37
+ self.buttons: list = []
38
+ self.input_mode: InputMode.DirectInput
39
+ self.input_connection: ConnectionType.WIRED
40
+
41
+ def handle_input(self, event):
42
+ pass
43
+
44
+ def left(self):
45
+ pass
46
+
47
+ def right(self):
48
+ pass
49
+
50
+ def up(self):
51
+ pass
52
+
53
+ def down(self):
54
+ pass
55
+
56
+ def pause(self):
57
+ pass
58
+
59
+ def rumble(self):
60
+ pass
61
+
62
+ @property
63
+ def name(self) -> str:
64
+ return self._name
65
+
66
+ @name.setter
67
+ def name(self, name: str) -> None:
68
+ self._name = name
69
+
70
+ @property
71
+ def axis(self) -> list:
72
+ return self._axis
73
+
74
+ @axis.setter
75
+ def axis(self) -> None:
76
+ self._axis = [self.device.get_axis(a) for a in range(self.numaxis)]
77
+
78
+ @property
79
+ def hats(self) -> list:
80
+ return self._hats
81
+
82
+ @hats.setter
83
+ def hats(self) -> None:
84
+ self.hats = [self.device.get_hats(h) for h in range(self.numhats)]
85
+
86
+ @property
87
+ def buttons(self) -> list:
88
+ return self._buttons
89
+
90
+ @buttons.setter
91
+ def buttons(self) -> None:
92
+ self._buttons = [self.device.get_buttons(b) for b in range(self.numbuttons)]
93
+
94
+ @property
95
+ def input_mode(self) -> int:
96
+ return self._inputmode
97
+
98
+ @input_mode.setter
99
+ def input_mode(self, mode: int) -> None:
100
+ self._inputmode = mode
101
+
102
+ @property
103
+ def input_connection(self) -> int:
104
+ return self._input_connection
105
+
106
+ @input_connection.setter
107
+ def input_connection(self, conn: int) -> None:
108
+ self._input_connection = conn
@@ -0,0 +1,108 @@
1
+ """
2
+ Logitech F310 Controller class.
3
+ This controller is a usb controller, with the following features.
4
+ (XInput mode)
5
+ 6 axis
6
+ 11 buttons
7
+ 1 hat
8
+
9
+ (DirectInput mode)
10
+ 4 axis
11
+ 12 buttons
12
+ 1 hat
13
+ """
14
+
15
+ import pygame
16
+ from pygameControls.controlsbase import ControlsBase
17
+ from enum import Enum
18
+
19
+ class InputMode(Enum):
20
+ DirectInput = 1
21
+ XInput = 2
22
+
23
+ class ConnectionType(Enum):
24
+ WIRED = 1
25
+ WIRELESS = 2
26
+
27
+ class LogitechF710Controller(ControlsBase):
28
+ def __init__(self, joy):
29
+ self.device = joy
30
+ self.instance_id: int = self.device.get_instance_id()
31
+ self.name = self.device.get_name()
32
+ self.numaxis: int = self.device.get_numaxis()
33
+ self.axis: list = []
34
+ self.numhats: int = self.device.get_numhats()
35
+ self.hats: list = []
36
+ self.numbuttons: int = self.device.get_numbuttons()
37
+ self.buttons: list = []
38
+ self.input_mode: InputMode.DirectInput
39
+ self.input_connection: ConnectionType.WIRED
40
+
41
+ def handle_input(self, event):
42
+ pass
43
+
44
+ def left(self):
45
+ pass
46
+
47
+ def right(self):
48
+ pass
49
+
50
+ def up(self):
51
+ pass
52
+
53
+ def down(self):
54
+ pass
55
+
56
+ def pause(self):
57
+ pass
58
+
59
+ def rumble(self):
60
+ pass
61
+
62
+ @property
63
+ def name(self) -> str:
64
+ return self._name
65
+
66
+ @name.setter
67
+ def name(self, name: str) -> None:
68
+ self._name = name
69
+
70
+ @property
71
+ def axis(self) -> list:
72
+ return self._axis
73
+
74
+ @axis.setter
75
+ def axis(self) -> None:
76
+ self._axis = [self.device.get_axis(a) for a in range(self.numaxis)]
77
+
78
+ @property
79
+ def hats(self) -> list:
80
+ return self._hats
81
+
82
+ @hats.setter
83
+ def hats(self) -> None:
84
+ self.hats = [self.device.get_hats(h) for h in range(self.numhats)]
85
+
86
+ @property
87
+ def buttons(self) -> list:
88
+ return self._buttons
89
+
90
+ @buttons.setter
91
+ def buttons(self) -> None:
92
+ self._buttons = [self.device.get_buttons(b) for b in range(self.numbuttons)]
93
+
94
+ @property
95
+ def input_mode(self) -> int:
96
+ return self._inputmode
97
+
98
+ @input_mode.setter
99
+ def input_mode(self, mode: int) -> None:
100
+ self._inputmode = mode
101
+
102
+ @property
103
+ def input_connection(self) -> int:
104
+ return self._input_connection
105
+
106
+ @input_connection.setter
107
+ def input_connection(self, conn: int) -> None:
108
+ self._input_connection = conn
@@ -0,0 +1,45 @@
1
+ import time
2
+ import threading
3
+
4
+ class XboxSeriesXController:
5
+ def __init__(self, joy):
6
+ self.device = joy
7
+ self.instance_id: int = self.device.get_instance_id()
8
+ self.name = self.device.get_name()
9
+ self.guid = self.device.get_guid()
10
+ self.numaxis: int = self.device.get_numaxes()
11
+ self.axis: list = [self.device.get_axis(a) for a in range(self.numaxis)]
12
+ self.numhats: int = self.device.get_numhats()
13
+ self.hats: list = [self.device.get_hat(h) for h in range(self.numhats)]
14
+ self.numbuttons: int = self.device.get_numbuttons()
15
+ self.buttons: list = [self.device.get_button(b) for b in range(self.numbuttons)]
16
+
17
+ def handle_input(self, event):
18
+ pass
19
+
20
+ def left(self):
21
+ pass
22
+
23
+ def right(self):
24
+ pass
25
+
26
+ def up(self):
27
+ pass
28
+
29
+ def down(self):
30
+ pass
31
+
32
+ def pause(self):
33
+ pass
34
+
35
+ def rumble(self):
36
+ pass
37
+
38
+ @property
39
+ def name(self) -> str:
40
+ return self._name
41
+
42
+ @name.setter
43
+ def name(self, name: str) -> None:
44
+ self._name = name
45
+
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: pygameControls
3
+ Version: 0.0.4
4
+ Summary: A simple controller class for pygame.
5
+ Home-page:
6
+ Author: Jan Lerking
7
+ Author-email:
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.12
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Dynamic: author
15
+ Dynamic: classifier
16
+ Dynamic: description
17
+ Dynamic: description-content-type
18
+ Dynamic: license-file
19
+ Dynamic: requires-python
20
+ Dynamic: summary
21
+
22
+ # PyGame-Controller
23
+
24
+ Small module to make it easy to add controller support.
@@ -0,0 +1,19 @@
1
+ LICENSE
2
+ README.md
3
+ setup.py
4
+ pygameControls/__init__.py
5
+ pygameControls/controller.py
6
+ pygameControls/controlsbase.py
7
+ pygameControls/dualsense_audio.py
8
+ pygameControls/dualsense_controller.py
9
+ pygameControls/dualsense_edge_controller.py
10
+ pygameControls/generic_controller.py
11
+ pygameControls/logitech_dual_action_controller.py
12
+ pygameControls/logitech_f310_controller.py
13
+ pygameControls/logitech_f510_controller.py
14
+ pygameControls/logitech_f710_controller.py
15
+ pygameControls/xbox_series_x_controller.py
16
+ pygameControls.egg-info/PKG-INFO
17
+ pygameControls.egg-info/SOURCES.txt
18
+ pygameControls.egg-info/dependency_links.txt
19
+ pygameControls.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ pygameControls
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,21 @@
1
+ if __name__ == "__main__":
2
+ from setuptools import setup, find_packages
3
+
4
+ setup(
5
+ name='pygameControls',
6
+ version='0.0.4',
7
+ packages=find_packages(),
8
+ install_requires=[],
9
+ author='Jan Lerking',
10
+ author_email='',
11
+ description='A simple controller class for pygame.',
12
+ long_description=open('README.md').read(),
13
+ long_description_content_type='text/markdown',
14
+ url='',
15
+ classifiers=[
16
+ 'Programming Language :: Python :: 3',
17
+ 'License :: OSI Approved :: MIT License',
18
+ 'Operating System :: OS Independent',
19
+ ],
20
+ python_requires='>=3.12',
21
+ )