gamepadla-plus 1.1.6__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,27 @@
1
+ name: PyPI Release
2
+
3
+ on:
4
+ release:
5
+ types:
6
+ - published
7
+ workflow_dispatch:
8
+
9
+ jobs:
10
+ pypi-release:
11
+ name: Release Python Package
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ id-token: write
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0
20
+
21
+ - uses: actions/setup-python@v5
22
+ name: Install Python
23
+
24
+ - name: Build SDist
25
+ run: pipx run build --sdist
26
+
27
+ - uses: pypa/gh-action-pypi-publish@v1.10.1
@@ -0,0 +1,7 @@
1
+
2
+ /build
3
+ Gamepadla.spec
4
+ .Gamepadla.spec
5
+ data.txt
6
+ /dist
7
+ /venv
@@ -0,0 +1,260 @@
1
+ ver = "1.1.6"
2
+
3
+ from colorama import Fore, Style
4
+ import time
5
+ import json
6
+ from tqdm import tqdm
7
+ import numpy as np
8
+ import platform
9
+ import requests
10
+ import uuid
11
+ import webbrowser
12
+ import pygame
13
+
14
+ # Print introductory information
15
+ print(f" ")
16
+ print(f" ")
17
+ print(" ██████╗ █████╗ ███╗ ███╗███████╗██████╗ █████╗ ██████╗ " + Fore.CYAN + "██╗ █████╗ " + Fore.RESET)
18
+ print(" ██╔════╝ ██╔══██╗████╗ ████║██╔════╝██╔══██╗██╔══██╗██╔══██╗" + Fore.CYAN + "██║ ██╔══██╗" + Fore.RESET)
19
+ print(" ██║ ███╗███████║██╔████╔██║█████╗ ██████╔╝███████║██║ ██║" + Fore.CYAN + "██║ ███████║" + Fore.RESET)
20
+ print(" ██║ ██║██╔══██║██║╚██╔╝██║██╔══╝ ██╔═══╝ ██╔══██║██║ ██║" + Fore.CYAN + "██║ ██╔══██║" + Fore.RESET)
21
+ print(" ╚██████╔╝██║ ██║██║ ╚═╝ ██║███████╗██║ ██║ ██║██████╔╝" + Fore.CYAN + "███████╗██║ ██║" + Fore.RESET)
22
+ print(" ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═╝╚═════╝ " + Fore.CYAN + "╚══════╝╚═╝ ╚═╝" + Fore.RESET)
23
+ print(Fore.CYAN + " " + "Gamepadla Tester" + Fore.RESET + " " + ver + " https://gamepadla.com")
24
+ print(f" ")
25
+ print(f" ")
26
+ print(f"Credits:")
27
+ print("Based on the method of: https://github.com/chrizonix/XInputTest")
28
+ pygame.init() # Initialize Pygame
29
+
30
+ # Function to filter out outliers in latency data
31
+ def filter_outliers(array):
32
+ lower_quantile = 0.02
33
+ upper_quantile = 0.995
34
+
35
+ sorted_array = sorted(array)
36
+ lower_index = int(len(sorted_array) * lower_quantile)
37
+ upper_index = int(len(sorted_array) * upper_quantile)
38
+
39
+ return sorted_array[lower_index:upper_index + 1]
40
+
41
+ while True:
42
+ pygame.joystick.init() # Initialize joystick
43
+ joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())]
44
+ delay_list = []
45
+
46
+ if not joysticks:
47
+ print("No controller found")
48
+ time.sleep(10)
49
+ exit(1)
50
+ else:
51
+ print(f" ")
52
+ print(f"Found {len(joysticks)} controller(s)")
53
+
54
+ for idx, joystick in enumerate(joysticks):
55
+ print(f"{idx + 1}. {joystick.get_name()}")
56
+
57
+ # Prompt user to select the controller to test
58
+ selected_index = input("Please enter the index of the controller you want to test: ")
59
+ try:
60
+ selected_index = int(selected_index) - 1
61
+ if 0 <= selected_index < len(joysticks):
62
+ joystick = joysticks[selected_index]
63
+ else:
64
+ print("Invalid index. Defaulting to the first controller.")
65
+ joystick = joysticks[0]
66
+ except ValueError:
67
+ print("Invalid input. Defaulting to the first controller.")
68
+ joystick = joysticks[0]
69
+
70
+ joystick.init() # Initialize the selected joystick
71
+ joystick_name = joystick.get_name()
72
+
73
+ print("")
74
+ print(f"Gamepad mode: {joystick_name}")
75
+ os_name = platform.system()
76
+ uname = platform.uname()
77
+ os_version = uname.version
78
+ print(f"Operating System: {os_name}")
79
+
80
+ # Prompt user to select number of tests or set a custom number
81
+ repeat = 1988
82
+ repeatq = input("Please select number of tests (1. 2000, 2. 4000, 3. 6000), or enter your own number: ")
83
+ if repeatq == "1":
84
+ repeat = 2000
85
+ elif repeatq == "2":
86
+ repeat = 4000
87
+ elif repeatq == "3":
88
+ repeat = 6000
89
+ else:
90
+ try:
91
+ repeat = int(repeatq)
92
+ except ValueError:
93
+ print("Invalid input. Please enter a valid number.")
94
+
95
+ # Prompt user to select the stick to test (left or right)
96
+ print("")
97
+ print("Please select the stick you want to test:")
98
+ print("1. Left stick")
99
+ print("2. Right stick")
100
+ stick_choice = input("Enter the number (1 or 2): ")
101
+
102
+ print("")
103
+ if stick_choice == "1":
104
+ axis_x = 0 # Axis for the left stick
105
+ axis_y = 1
106
+ print("Testing left stick.")
107
+ elif stick_choice == "2":
108
+ axis_x = 2 # Axis for the right stick
109
+ axis_y = 3
110
+ print("Testing right stick.")
111
+ else:
112
+ print("Invalid choice. Defaulting to left stick.")
113
+ axis_x = 0
114
+ axis_y = 1
115
+
116
+ if not joystick.get_init():
117
+ print("Controller not connected")
118
+ exit(1)
119
+
120
+ times = []
121
+ start_time = time.time()
122
+ prev_x, prev_y = None, None
123
+
124
+ # Main loop to gather latency data from joystick movements
125
+ with tqdm(total=repeat, ncols=76, bar_format='{l_bar}{bar} | {postfix[0]}', postfix=[0]) as pbar:
126
+ while True:
127
+ pygame.event.pump()
128
+ x = joystick.get_axis(axis_x)
129
+ y = joystick.get_axis(axis_y)
130
+ pygame.event.clear()
131
+
132
+ # Ensure the stick has moved significantly (anti-drift)
133
+ if not ("0.0" in str(x) and "0.0" in str(y)):
134
+ if prev_x is None and prev_y is None:
135
+ prev_x, prev_y = x, y
136
+ elif x != prev_x or y != prev_y:
137
+ end_time = time.time()
138
+ duration = round((end_time - start_time) * 1000, 2)
139
+ start_time = end_time
140
+ prev_x, prev_y = x, y
141
+
142
+ while True:
143
+ pygame.event.pump()
144
+ new_x = joystick.get_axis(axis_x)
145
+ new_y = joystick.get_axis(axis_y)
146
+ pygame.event.clear()
147
+
148
+ # If stick moved again, calculate delay
149
+ if new_x != x or new_y != y:
150
+ end = time.time()
151
+ delay = round((end - start_time) * 1000, 2)
152
+ if delay != 0.0 and delay > 0.2 and delay < 150:
153
+ times.append(delay * 1.057) # Adjust for a 5% offset
154
+ pbar.update(1)
155
+ pbar.postfix[0] = "{:05.2f} ms".format(delay)
156
+ delay_list.append(delay)
157
+
158
+ break
159
+
160
+ if len(times) >= repeat:
161
+ break
162
+
163
+ # Filter outliers from delay list
164
+ delay_clear = delay_list
165
+ delay_list = filter_outliers(delay_list)
166
+
167
+ # Calculate statistical data
168
+ filteredMin = min(delay_list)
169
+ filteredMax = max(delay_list)
170
+ filteredAverage = np.mean(delay_list)
171
+ filteredAverage_rounded = round(filteredAverage, 2)
172
+
173
+ polling_rate = round(1000 / filteredAverage, 2)
174
+ jitter = round(np.std(delay_list), 2)
175
+
176
+ # Function to determine max polling rate based on actual polling rate
177
+ def get_polling_rate_max(actual_rate):
178
+ max_rate = 125
179
+ if actual_rate > 150:
180
+ max_rate = 250
181
+ if actual_rate > 320:
182
+ max_rate = 500
183
+ if actual_rate > 600:
184
+ max_rate = 1000
185
+ return max_rate
186
+
187
+ # Display results
188
+ print("")
189
+ max_polling_rate = get_polling_rate_max(polling_rate)
190
+ print(f"Polling Rate Max.: {max_polling_rate} Hz")
191
+ print(f"Polling Rate Avg.: {polling_rate} Hz")
192
+ stablility = round((polling_rate/max_polling_rate)*100, 2)
193
+ print(f"Stability: {stablility}%")
194
+
195
+ print(f" ")
196
+ print(f"=== Synthetic tests ===")
197
+ print(f"Minimal latency: {filteredMin} ms")
198
+ print(f"Average latency: {filteredAverage_rounded} ms")
199
+ print(f"Maximum latency: {filteredMax} ms")
200
+ print(f"Jitter: {jitter} ms")
201
+
202
+ # Generate a unique test key
203
+ test_key = uuid.uuid4()
204
+
205
+ # Prepare data for JSON output
206
+ data = {
207
+ 'test_key': str(test_key),
208
+ 'version': ver,
209
+ 'url': 'https://gamepadla.com',
210
+ 'date': time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()),
211
+ 'driver': joystick_name,
212
+ 'os_name': os_name,
213
+ 'os_version': os_version,
214
+ 'min_latency': filteredMin,
215
+ 'avg_latency': filteredAverage_rounded,
216
+ 'max_latency': filteredMax,
217
+ 'polling_rate': polling_rate,
218
+ 'jitter': jitter,
219
+ 'mathod': 'GP',
220
+ 'delay_list': ', '.join(map(str, delay_clear))
221
+ }
222
+
223
+ # Write data to file
224
+ with open('data.txt', 'w') as outfile:
225
+ json.dump(data, outfile, indent=4)
226
+
227
+ # Ask if user wants to open the results in a browser
228
+ if input("Open in browser? (Y/N): ").lower() == "y":
229
+ gamepad_name = input("Please enter the name of your gamepad: ")
230
+ connection = input("Please select connection type (1. Cable, 2. Bluetooth, 3. Dongle): ")
231
+ if connection == "1":
232
+ connection = "Cable"
233
+ elif connection == "2":
234
+ connection = "Bluetooth"
235
+ elif connection == "3":
236
+ connection = "Dongle"
237
+ else:
238
+ print("Invalid choice. Defaulting to Cable.")
239
+ connection = "Unset"
240
+
241
+ # Add connection and gamepad name to the data
242
+ data['connection'] = connection
243
+ data['name'] = gamepad_name
244
+
245
+ # Send test results to the server
246
+ response = requests.post('https://gamepadla.com/scripts/poster.php', data=data)
247
+ if response.status_code == 200:
248
+ print("Test results successfully sent to the server.")
249
+ webbrowser.open(f'https://gamepadla.com/result/{test_key}/')
250
+ else:
251
+ print("Failed to send test results to the server.")
252
+
253
+ # Clean up unused data
254
+ del data['test_key']
255
+ del data['os_version']
256
+ del data['url']
257
+
258
+ # Ask if the user wants to run the test again
259
+ if input("Run again? (Y/N): ").lower() != "y":
260
+ break
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022-2024 John Punch
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,55 @@
1
+ Metadata-Version: 2.3
2
+ Name: gamepadla-plus
3
+ Version: 1.1.6
4
+ Summary: Gamepads latency and polling rate tester
5
+ Project-URL: Repository, https://github.com/WyvernIXTL/gamepadla-plus
6
+ Project-URL: Issues, https://github.com/WyvernIXTL/gamepadla-plus/issues
7
+ Author: John Punch
8
+ Maintainer: Adam McKellar <dev@mckellar.eu>
9
+ License: MIT License
10
+ License-File: LICENSE
11
+ Keywords: gamepad,latency,test
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ Classifier: Programming Language :: Python :: 3
15
+ Requires-Python: >=3.8
16
+ Requires-Dist: colorama
17
+ Requires-Dist: numpy
18
+ Requires-Dist: pygame
19
+ Requires-Dist: requests
20
+ Requires-Dist: tqdm
21
+ Description-Content-Type: text/markdown
22
+
23
+ # Gamepadla
24
+ Gamepads polling rate and synthetic latency tester
25
+ Based on the method of Christian P.: https://github.com/chrizonix/XInputTest
26
+ Pyhon code written by [John Punch](https://www.reddit.com/user/JohnnyPunch/)
27
+
28
+ ![image](https://github.com/cakama3a/Gamepadla/assets/15096106/5ea9dfba-e31a-4911-960b-0cc9d2f66bc4)
29
+
30
+ A website with a catalog of tested gamepads: https://gamepadla.com
31
+
32
+ ABOUT GAMEPADLA
33
+ Gamepadla is an easy way to check the polling rate of your gamepad. This tool will help you get accurate data about your controller's performance, which can be useful for gamers, game developers, and enthusiasts.
34
+ Gamepadla works with most popular gamepads and supports DInput and XInput protocols, making it a versatile solution for testing different types of controllers.
35
+
36
+ ![image](https://github.com/cakama3a/Gamepadla/assets/15096106/1152f147-2db9-4301-962e-2ac97555a0fa)
37
+
38
+ DISCLAMER
39
+ Gamepadla measures the delay between successive changes in the position of the analog stick on the gamepad, rather than the traditional input latency, which measures the time between pressing a button on the gamepad and a response in a program or game.
40
+ This method of measurement can be affected by various factors, including the quality of the gamepad, the speed of the computer's processor, the speed of event processing in the Pygame library, and so on.
41
+ Therefore, although Gamepadla can give a general idea of the "response" of a gamepad, it cannot accurately measure input latency in the traditional sense. The results obtained from Gamepadla should be used as a guide, not as an exact measurement of input latency.
42
+
43
+ Here's how to use Gamepadla:
44
+ 1. Connect your gamepad to your PC.
45
+ You can connect your gamepad via Bluetooth, with a cable, or with the included receiver. Make sure your operating system recognizes the gamepad.
46
+ 2. Launch Gamepadla.
47
+ Just double-click on the fileGamepadla.exe filefile to launch the program.
48
+ 3. Check the connection of your gamepad.
49
+ Gamepadla will automatically detect connected gamepads. If your gamepad is not detected, make sure it is connected correctly and try again.
50
+ 4. Run the test.
51
+ After the gamepad is detected, the program will ask you to move the left stick in a circle without stopping. This will allow the program to collect data about the gamepad's latency.
52
+ 5. View the results.
53
+ When the test is complete, the program will redirect you to the site with the results. You will see the minimum, average, and maximum latency, as well as the polling rate and jitter.
54
+ 6. Compare the results.
55
+ If you want to compare the results of different tests, simply repeat the test. The results will be added to your test page.
@@ -0,0 +1,33 @@
1
+ # Gamepadla
2
+ Gamepads polling rate and synthetic latency tester
3
+ Based on the method of Christian P.: https://github.com/chrizonix/XInputTest
4
+ Pyhon code written by [John Punch](https://www.reddit.com/user/JohnnyPunch/)
5
+
6
+ ![image](https://github.com/cakama3a/Gamepadla/assets/15096106/5ea9dfba-e31a-4911-960b-0cc9d2f66bc4)
7
+
8
+ A website with a catalog of tested gamepads: https://gamepadla.com
9
+
10
+ ABOUT GAMEPADLA
11
+ Gamepadla is an easy way to check the polling rate of your gamepad. This tool will help you get accurate data about your controller's performance, which can be useful for gamers, game developers, and enthusiasts.
12
+ Gamepadla works with most popular gamepads and supports DInput and XInput protocols, making it a versatile solution for testing different types of controllers.
13
+
14
+ ![image](https://github.com/cakama3a/Gamepadla/assets/15096106/1152f147-2db9-4301-962e-2ac97555a0fa)
15
+
16
+ DISCLAMER
17
+ Gamepadla measures the delay between successive changes in the position of the analog stick on the gamepad, rather than the traditional input latency, which measures the time between pressing a button on the gamepad and a response in a program or game.
18
+ This method of measurement can be affected by various factors, including the quality of the gamepad, the speed of the computer's processor, the speed of event processing in the Pygame library, and so on.
19
+ Therefore, although Gamepadla can give a general idea of the "response" of a gamepad, it cannot accurately measure input latency in the traditional sense. The results obtained from Gamepadla should be used as a guide, not as an exact measurement of input latency.
20
+
21
+ Here's how to use Gamepadla:
22
+ 1. Connect your gamepad to your PC.
23
+ You can connect your gamepad via Bluetooth, with a cable, or with the included receiver. Make sure your operating system recognizes the gamepad.
24
+ 2. Launch Gamepadla.
25
+ Just double-click on the fileGamepadla.exe filefile to launch the program.
26
+ 3. Check the connection of your gamepad.
27
+ Gamepadla will automatically detect connected gamepads. If your gamepad is not detected, make sure it is connected correctly and try again.
28
+ 4. Run the test.
29
+ After the gamepad is detected, the program will ask you to move the left stick in a circle without stopping. This will allow the program to collect data about the gamepad's latency.
30
+ 5. View the results.
31
+ When the test is complete, the program will redirect you to the site with the results. You will see the minimum, average, and maximum latency, as well as the polling rate and jitter.
32
+ 6. Compare the results.
33
+ If you want to compare the results of different tests, simply repeat the test. The results will be added to your test page.
@@ -0,0 +1,49 @@
1
+ [build-system]
2
+ requires = [
3
+ "hatchling",
4
+ "versioningit",
5
+ ]
6
+ build-backend = "hatchling.build"
7
+
8
+ [tool.hatch.version]
9
+ source = "versioningit"
10
+
11
+
12
+ [project]
13
+ name = "gamepadla-plus"
14
+ description = "Gamepads latency and polling rate tester "
15
+ authors = [
16
+ { name="John Punch" },
17
+ ]
18
+ maintainers = [
19
+ { name="Adam McKellar <dev@mckellar.eu>" },
20
+ ]
21
+ readme = "README.md"
22
+ license = {text = "MIT License"}
23
+ keywords = ["gamepad", "test", "latency"]
24
+ requires-python = ">=3.8"
25
+ classifiers = [
26
+ "Programming Language :: Python :: 3",
27
+ "License :: OSI Approved :: MIT License",
28
+ "Operating System :: Microsoft :: Windows",
29
+ ]
30
+
31
+ dynamic = ["version"]
32
+
33
+ dependencies = [
34
+ "colorama",
35
+ "tqdm",
36
+ "numpy",
37
+ "requests",
38
+ "pygame",
39
+ ]
40
+
41
+
42
+ [project.urls]
43
+ Repository = "https://github.com/WyvernIXTL/gamepadla-plus"
44
+ Issues = "https://github.com/WyvernIXTL/gamepadla-plus/issues"
45
+
46
+
47
+ [project.scripts]
48
+ gamepadla = "gamepadla:main"
49
+