Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
flow3r firmware
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
dos
flow3r firmware
Commits
0754bffd
Commit
0754bffd
authored
1 year ago
by
q3k
Browse files
Options
Downloads
Patches
Plain Diff
sim: add three-way buttons, refactor
parent
fdd4ef6f
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
sim/README.md
+0
-2
0 additions, 2 deletions
sim/README.md
sim/fakes/hardware.py
+112
-65
112 additions, 65 deletions
sim/fakes/hardware.py
with
112 additions
and
67 deletions
sim/README.md
+
0
−
2
View file @
0754bffd
...
...
@@ -34,8 +34,6 @@ Known Issues
Captouch petal input order is wrong.
No support for three-way buttons yet.
No support for audio yet.
Hacking
...
...
This diff is collapsed.
Click to expand it.
sim/fakes/hardware.py
+
112
−
65
View file @
0754bffd
...
...
@@ -14,19 +14,96 @@ bgpath = os.path.join(simpath, 'background.png')
background
=
pygame
.
image
.
load
(
bgpath
)
class
Simulation
:
class
Input
:
"""
Simulation
implements
the state and logic of the on-host pygame-based badg
e
simulator
.
Input
implements
an input overlay (for petals or buttons) that can b
e
mouse-picked by the user, and in the future also keyboard-controlled
.
"""
# Pixels positions of each marker.
POSITIONS
=
[]
# Pixel size (diameter) of each marker.
MARKER_SIZE
=
100
# Colors for various states (RGBA).
COLOR_HELD
=
(
0x5b
,
0x5b
,
0x5b
,
0xa0
)
COLOR_HOVER
=
(
0x6b
,
0x6b
,
0x6b
,
0xa0
)
COLOR_IDLE
=
(
0x8b
,
0x8b
,
0x8b
,
0x80
)
def
__init__
(
self
):
self
.
_state
=
[
False
for
_
in
self
.
POSITIONS
]
self
.
_mouse_hover
=
None
self
.
_mouse_held
=
None
def
state
(
self
):
s
=
[
ss
for
ss
in
self
.
_state
]
if
self
.
_mouse_held
is
not
None
:
s
[
self
.
_mouse_held
]
=
True
return
s
def
_mouse_coords_to_id
(
self
,
mouse_x
,
mouse_y
):
for
i
,
(
x
,
y
)
in
enumerate
(
self
.
POSITIONS
):
x
+=
self
.
MARKER_SIZE
//
2
y
+=
self
.
MARKER_SIZE
//
2
dx
=
mouse_x
-
x
dy
=
mouse_y
-
y
if
math
.
sqrt
(
dx
**
2
+
dy
**
2
)
<
self
.
MARKER_SIZE
//
2
:
return
i
return
None
# Pixel coordinates of each petal 'marker'.
def
process_event
(
self
,
ev
):
prev_hover
=
self
.
_mouse_hover
prev_state
=
self
.
state
()
if
ev
.
type
==
pygame
.
MOUSEMOTION
:
x
,
y
=
ev
.
pos
self
.
_mouse_hover
=
self
.
_mouse_coords_to_id
(
x
,
y
)
if
ev
.
type
==
pygame
.
MOUSEBUTTONDOWN
:
self
.
_mouse_held
=
self
.
_mouse_hover
if
ev
.
type
==
pygame
.
MOUSEBUTTONUP
:
self
.
_mouse_held
=
None
if
prev_hover
!=
self
.
_mouse_hover
:
return
True
if
prev_state
!=
self
.
state
():
return
True
return
False
def
render
(
self
,
surface
):
s
=
self
.
state
()
for
i
,
(
x
,
y
)
in
enumerate
(
self
.
POSITIONS
):
x
+=
self
.
MARKER_SIZE
//
2
y
+=
self
.
MARKER_SIZE
//
2
if
s
[
i
]:
pygame
.
draw
.
circle
(
surface
,
self
.
COLOR_HELD
,
(
x
,
y
),
self
.
MARKER_SIZE
//
2
)
elif
i
==
self
.
_mouse_hover
:
pygame
.
draw
.
circle
(
surface
,
self
.
COLOR_HOVER
,
(
x
,
y
),
self
.
MARKER_SIZE
//
2
)
else
:
pygame
.
draw
.
circle
(
surface
,
self
.
COLOR_IDLE
,
(
x
,
y
),
self
.
MARKER_SIZE
//
2
)
class
PetalsInput
(
Input
):
# TODO(q3k): document order
PETAL_
POSITIONS
=
[
POSITIONS
=
[
(
114
,
302
),
(
163
,
112
),
(
204
,
587
),
(
49
,
477
),
(
504
,
587
),
(
352
,
696
),
(
602
,
298
),
(
660
,
477
),
(
356
,
122
),
(
547
,
117
),
]
# Size of each petal 'marker' rendered in overlay.
PETAL_MARKER_SIZE
=
50
class
ButtonsInput
(
Input
):
POSITIONS
=
[
(
14
,
230
),
(
46
,
230
),
(
78
,
230
),
(
714
,
230
),
(
746
,
230
),
(
778
,
230
),
]
MARKER_SIZE
=
20
COLOR_HELD
=
(
0x80
,
0x80
,
0x80
,
0xff
)
COLOR_HOVER
=
(
0x40
,
0x40
,
0x40
,
0xff
)
COLOR_IDLE
=
(
0x20
,
0x20
,
0x20
,
0xff
)
class
Simulation
:
"""
Simulation implements the state and logic of the on-host pygame-based badge
simulator.
"""
# Pixel coordinates of each LED. The order is the same as the hardware
# WS2812 chain, not the order as expected by the micropython API!
...
...
@@ -44,13 +121,8 @@ class Simulation:
self
.
led_state_buf
=
[(
0
,
0
,
0
)
for
_
in
self
.
LED_POSITIONS
]
# Actual LED state as rendered.
self
.
led_state
=
[(
0
,
0
,
0
)
for
_
in
self
.
LED_POSITIONS
]
# Position of the simulation cursor in window pixel coordinates.
self
.
mouse_x
,
self
.
mouse_y
=
(
0
,
0
)
# ID of petal being held (clicked), or None if no petal is being held.
self
.
petal_held
=
None
# ID of petal being hovered over, or None if no petal is being hovered
# over.
self
.
petal_hover
=
None
self
.
petals
=
PetalsInput
()
self
.
buttons
=
ButtonsInput
()
# Timestamp of last GUI render. Used by the lazy render GUI
# functionality.
self
.
last_gui_render
=
None
...
...
@@ -95,61 +167,19 @@ class Simulation:
def
process_events
(
self
):
"""
Process pygame events and update mouse_{x,y}, petal_held and
petal_hover.
Process pygame events and update mouse_{x,y},
{
petal
,button}
_held and
{
petal
,button}
_hover.
"""
prev_petal_hover
=
self
.
petal_hover
evs
=
pygame
.
event
.
get
()
for
ev
in
evs
:
if
ev
.
type
==
pygame
.
MOUSEMOTION
:
self
.
mouse_x
,
self
.
mouse_y
=
ev
.
pos
self
.
petal_hover
=
self
.
_mouse_coords_to_petal_id
()
if
ev
.
type
==
pygame
.
MOUSEBUTTONDOWN
:
self
.
_process_mouse_down
()
if
ev
.
type
==
pygame
.
MOUSEBUTTONUP
:
self
.
_process_mouse_up
()
if
prev_petal_hover
!=
self
.
petal_hover
:
self
.
_petal_surface_dirty
=
True
def
_mouse_coords_to_petal_id
(
self
):
if
self
.
mouse_x
is
None
or
self
.
mouse_y
is
None
:
return
None
for
i
,
pos
in
enumerate
(
self
.
PETAL_POSITIONS
):
(
px
,
py
)
=
pos
# TODO(q3k): pre-apply to PETAL_POSITIONS.
px
+=
50
py
+=
50
dx
=
self
.
mouse_x
-
px
dy
=
self
.
mouse_y
-
py
if
math
.
sqrt
(
dx
**
2
+
dy
**
2
)
<
self
.
PETAL_MARKER_SIZE
:
return
i
return
None
def
_process_mouse_up
(
self
):
if
self
.
petal_held
is
not
None
:
self
.
petal_held
=
None
self
.
_petal_surface_dirty
=
True
def
_process_mouse_down
(
self
):
if
self
.
petal_held
!=
self
.
petal_hover
:
self
.
petal_held
=
self
.
petal_hover
self
.
_petal_surface_dirty
=
True
if
self
.
petals
.
process_event
(
ev
):
self
.
_petal_surface_dirty
=
True
if
self
.
buttons
.
process_event
(
ev
):
self
.
_petal_surface_dirty
=
True
def
_render_petal_markers
(
self
,
surface
):
for
i
,
pos
in
enumerate
(
self
.
PETAL_POSITIONS
):
x
,
y
=
pos
# TODO(q3k): pre-apply to PETAL_POSITIONS
x
+=
50
y
+=
50
if
i
==
self
.
petal_held
:
pygame
.
draw
.
circle
(
surface
,
(
0x8b
,
0x8b
,
0x8b
,
0x80
),
(
x
,
y
),
50
)
elif
i
==
self
.
petal_hover
:
pygame
.
draw
.
circle
(
surface
,
(
0x6b
,
0x6b
,
0x6b
,
0xa0
),
(
x
,
y
),
50
)
else
:
pygame
.
draw
.
circle
(
surface
,
(
0x5b
,
0x5b
,
0x5b
,
0xa0
),
(
x
,
y
),
50
)
self
.
petals
.
render
(
surface
)
self
.
buttons
.
render
(
surface
)
def
_render_leds
(
self
,
surface
):
for
pos
,
state
in
zip
(
self
.
LED_POSITIONS
,
self
.
led_state
):
...
...
@@ -342,10 +372,27 @@ def set_global_volume_dB(a):
def
get_button
(
a
):
_sim
.
process_events
()
_sim
.
render_gui_lazy
()
state
=
_sim
.
buttons
.
state
()
if
a
==
1
:
sub
=
state
[:
3
]
elif
a
==
0
:
sub
=
state
[
3
:
6
]
else
:
return
0
if
sub
[
0
]:
return
-
1
elif
sub
[
1
]:
return
2
elif
sub
[
2
]:
return
+
1
return
0
def
get_captouch
(
a
):
_sim
.
process_events
()
_sim
.
render_gui_lazy
()
return
_sim
.
petal
_held
==
a
return
_sim
.
petal
s
.
state
()[
a
]
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment