Skip to content

Commit 7c5f4f8

Browse files
authored
Merge pull request #3164 from RetiredWizard/fruitmatch3
Fruitjam Match3: Improve mouse compatibility
2 parents 59524df + da3cb8c commit 7c5f4f8

File tree

1 file changed

+57
-31
lines changed
  • Metro/Metro_RP2350_Match3/match3_game

1 file changed

+57
-31
lines changed

Metro/Metro_RP2350_Match3/match3_game/code.py

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,22 @@
2626
import adafruit_sdcard
2727
import msgpack
2828
import storage
29-
from match3_game_helpers import (
30-
Match3Game,
31-
STATE_GAMEOVER,
32-
STATE_PLAYING_SETCALLED,
33-
GameOverException,
34-
)
29+
try:
30+
from match3_game_helpers import (
31+
Match3Game,
32+
STATE_GAMEOVER,
33+
STATE_PLAYING_SETCALLED,
34+
GameOverException,
35+
)
36+
except ImportError:
37+
# Needed for Fruit Jam OS if "Play again" is selected at end of game
38+
os.chdir('/apps/Metro_RP2350_Match3')
39+
from match3_game_helpers import (
40+
Match3Game,
41+
STATE_GAMEOVER,
42+
STATE_PLAYING_SETCALLED,
43+
GameOverException,
44+
)
3545

3646
original_autoreload_val = supervisor.runtime.autoreload
3747
supervisor.runtime.autoreload = False
@@ -244,34 +254,40 @@
244254
mouse_bufs = []
245255
# debouncers list for debouncing mouse left clicks
246256
mouse_debouncers = []
257+
mouse_sync = []
247258

248259
# scan for connected USB devices
249260
for device in usb.core.find(find_all=True):
250261
# check if current device is has a boot mouse endpoint
251-
mouse_interface_index, mouse_endpoint_address = (
252-
adafruit_usb_host_descriptors.find_boot_mouse_endpoint(device)
253-
)
254-
if mouse_interface_index is not None and mouse_endpoint_address is not None:
255-
# if it does have a boot mouse endpoint then add information to the
256-
# usb info lists
257-
mouse_interface_indexes.append(mouse_interface_index)
258-
mouse_endpoint_addresses.append(mouse_endpoint_address)
259-
260-
# add the mouse device instance to list
261-
mice.append(device)
262-
print(
263-
f"mouse interface: {mouse_interface_index} "
264-
+ f"endpoint_address: {hex(mouse_endpoint_address)}"
262+
try:
263+
mouse_interface_index, mouse_endpoint_address = (
264+
adafruit_usb_host_descriptors.find_boot_mouse_endpoint(device)
265265
)
266+
if mouse_interface_index is not None and mouse_endpoint_address is not None:
267+
# if it does have a boot mouse endpoint then add information to the
268+
# usb info lists
269+
mouse_interface_indexes.append(mouse_interface_index)
270+
mouse_endpoint_addresses.append(mouse_endpoint_address)
271+
272+
# add the mouse device instance to list
273+
mice.append(device)
274+
print(
275+
f"mouse interface: {mouse_interface_index} "
276+
+ f"endpoint_address: {hex(mouse_endpoint_address)}"
277+
)
278+
mouse_sync.append(0)
266279

267-
# detach kernel driver if needed
268-
kernel_driver_active_flags.append(device.is_kernel_driver_active(0))
269-
if device.is_kernel_driver_active(0):
270-
device.detach_kernel_driver(0)
280+
# detach kernel driver if needed
281+
kernel_driver_active_flags.append(device.is_kernel_driver_active(0))
282+
if device.is_kernel_driver_active(0):
283+
device.detach_kernel_driver(0)
271284

272-
# set the mouse configuration so it can be used
273-
device.set_configuration()
285+
# set the mouse configuration so it can be used
286+
device.set_configuration()
274287

288+
except usb.core.USBError as e:
289+
# The mouse might have glitched and may not be detected but at least we don't crash
290+
print(e)
275291

276292
def is_mouse1_left_clicked():
277293
"""
@@ -332,23 +348,27 @@ def is_right_mouse_clicked(buf):
332348
winner = None
333349

334350

335-
def get_mouse_deltas(buffer, read_count):
351+
def get_mouse_deltas(buffer, read_count, sync):
336352
"""
337353
Given a mouse packet buffer and a read count of number of bytes read,
338354
return the delta x and y values of the mouse.
339355
:param buffer: the buffer containing the packet data
340356
:param read_count: the number of bytes read from the mouse
341357
:return: tuple containing x and y delta values
342358
"""
343-
if read_count == 4:
359+
if read_count == 4 or (read_count == 8 and sync > 50):
344360
delta_x = buffer[1]
345361
delta_y = buffer[2]
346362
elif read_count == 8:
347363
delta_x = buffer[2]
348364
delta_y = buffer[4]
365+
if delta_y != 0:
366+
sync = -999
367+
elif delta_y == 0 and sync > -1:
368+
sync += 1
349369
else:
350370
raise ValueError(f"Unsupported mouse packet size: {read_count}, must be 4 or 8")
351-
return delta_x, delta_y
371+
return delta_x, delta_y, sync
352372

353373

354374
def atexit_callback():
@@ -381,10 +401,12 @@ def atexit_callback():
381401
try:
382402
# read data from the mouse, small timeout so we move on
383403
# quickly if there is no data
404+
data_len = 0
384405
data_len = mouse.read(
385-
mouse_endpoint_addresses[i], mouse_bufs[i], timeout=10
406+
mouse_endpoint_addresses[i], mouse_bufs[i], timeout=20
386407
)
387-
mouse_deltas = get_mouse_deltas(mouse_bufs[i], data_len)
408+
mouse_deltas = get_mouse_deltas(mouse_bufs[i], data_len, mouse_sync[i])
409+
mouse_sync[i] = mouse_deltas[2]
388410
# if we got data, then update the mouse cursor on the display
389411
# using min and max to keep it within the bounds of the display
390412
mouse_tg.x = max(
@@ -405,6 +427,10 @@ def atexit_callback():
405427
except usb.core.USBTimeoutError:
406428
pass
407429

430+
# common non-fatal error
431+
except usb.core.USBError:
432+
pass
433+
408434
# update the mouse debouncers
409435
mouse_debouncers[i].update()
410436

0 commit comments

Comments
 (0)