Skip to content

Commit 05a3028

Browse files
authored
Merge pull request #3138 from FoamyGuy/fruit_jam_logicgates
fruit jam logic gates simulator
2 parents 413e195 + b1ed7fb commit 05a3028

File tree

7 files changed

+2033
-0
lines changed

7 files changed

+2033
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
"""
5+
Fruit Jam Logic Gates Simulator
6+
"""
7+
import sys
8+
import time
9+
10+
import board
11+
from digitalio import DigitalInOut, Pull, Direction
12+
from displayio import Group
13+
14+
import supervisor
15+
from neopixel import NeoPixel
16+
from adafruit_usb_host_mouse import find_and_init_boot_mouse
17+
from adafruit_fruitjam.peripherals import request_display_config
18+
from workspace import Workspace
19+
20+
# cooldown time to ignore double clicks
21+
CLICK_COOLDOWN = 0.15
22+
last_click_time = None
23+
24+
# set the display size to 320,240
25+
request_display_config(320, 240)
26+
display = supervisor.runtime.display
27+
28+
# setup the mouse
29+
mouse = find_and_init_boot_mouse()
30+
mouse.sensitivity = 1.5
31+
if mouse is None:
32+
raise RuntimeError(
33+
"No mouse found connected to USB Host. A mouse is required for this app."
34+
)
35+
36+
# setup displayio Group for visuals
37+
main_group = Group()
38+
display.root_group = main_group
39+
40+
# setup physical hardware buttons
41+
btn_1 = DigitalInOut(board.BUTTON1)
42+
btn_1.direction = Direction.INPUT
43+
btn_1.pull = Pull.UP
44+
btn_2 = DigitalInOut(board.BUTTON2)
45+
btn_2.direction = Direction.INPUT
46+
btn_2.pull = Pull.UP
47+
btn_3 = DigitalInOut(board.BUTTON3)
48+
btn_3.direction = Direction.INPUT
49+
btn_3.pull = Pull.UP
50+
51+
# setup neopixels
52+
neopixels = NeoPixel(board.NEOPIXEL, 5, brightness=0.2, auto_write=True)
53+
54+
# setup Workspace object, giving it the neopixels, and hardware button objects
55+
workspace = Workspace(neopixels, (btn_1, btn_2, btn_3))
56+
57+
# add workspace elements to the Group to be shown on display
58+
main_group.append(workspace.group)
59+
main_group.append(workspace.mouse_moving_tg)
60+
61+
# add the mouse to the Group to be shown on top of everything else
62+
main_group.append(mouse.tilegrid)
63+
64+
# hardware button state variables
65+
old_button_values = [True, True, True]
66+
button_values_changed = False
67+
68+
while True:
69+
# update mouse, and get any mouse buttons that are pressed
70+
pressed_btns = mouse.update()
71+
72+
# enforce click cooldown to ignore double clicks
73+
now = time.monotonic()
74+
if last_click_time is None or now > last_click_time + CLICK_COOLDOWN:
75+
# if any buttons are pressed
76+
if pressed_btns is not None and len(pressed_btns) > 0:
77+
last_click_time = now
78+
# let workspace handle the click event
79+
workspace.handle_mouse_click(mouse.x, mouse.y, pressed_btns)
80+
81+
# if there is an entity on the mouse being moved
82+
if not workspace.mouse_moving_tg.hidden:
83+
# update its TileGrid's location to follow the mouse
84+
workspace.mouse_moving_tg.x = mouse.x - 12
85+
workspace.mouse_moving_tg.y = mouse.y - 24 - 12
86+
87+
# check how many bytes are available from keyboard
88+
available = supervisor.runtime.serial_bytes_available
89+
90+
# if there are some bytes available
91+
if available:
92+
# read data from the keyboard input
93+
c = sys.stdin.read(available)
94+
key_bytes = c.encode("utf-8")
95+
# let workspace handle the key press event
96+
workspace.handle_key_press(key_bytes, mouse.x, mouse.y)
97+
98+
# get hardware button states
99+
btn_1_current = btn_1.value
100+
btn_2_current = btn_2.value
101+
btn_3_current = btn_3.value
102+
button_values_changed = False
103+
104+
# check if any hardware button states have changed
105+
if btn_1_current != old_button_values[0]:
106+
button_values_changed = True
107+
if btn_2_current != old_button_values[1]:
108+
button_values_changed = True
109+
if btn_3_current != old_button_values[2]:
110+
button_values_changed = True
111+
112+
# update the old button states to compare with next iteration
113+
old_button_values[0] = btn_1_current
114+
old_button_values[1] = btn_2_current
115+
old_button_values[2] = btn_3_current
116+
117+
# if any button state changed, update workspace to run simulation
118+
if button_values_changed:
119+
workspace.update()

0 commit comments

Comments
 (0)