Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
P
Petal Hero
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
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
dos
Petal Hero
Commits
cc42740e
Verified
Commit
cc42740e
authored
1 year ago
by
dos
Browse files
Options
Downloads
Patches
Plain Diff
Initial import
parent
5504e16f
No related branches found
No related tags found
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
__init__.py
+313
-0
313 additions, 0 deletions
__init__.py
flow3r.toml
+10
-0
10 additions, 0 deletions
flow3r.toml
menu.mp3
+0
-0
0 additions, 0 deletions
menu.mp3
with
323 additions
and
0 deletions
__init__.py
0 → 100644
+
313
−
0
View file @
cc42740e
import
sys
import
media
,
math
,
random
from
st3m.ui.colours
import
*
from
st3m.input
import
InputController
from
st3m.ui.view
import
BaseView
,
ViewManager
,
ViewTransitionSwipeLeft
import
leds
sys
.
path
.
append
(
'
/flash/apps/PetalHero
'
)
import
midi
AMAZING_DIFFICULTY
=
0
MEDIUM_DIFFICULTY
=
1
EASY_DIFFICULTY
=
2
SUPAEASY_DIFFICULTY
=
3
noteMap
=
{
# difficulty, note
0x60
:
(
AMAZING_DIFFICULTY
,
0
),
0x61
:
(
AMAZING_DIFFICULTY
,
1
),
0x62
:
(
AMAZING_DIFFICULTY
,
2
),
0x63
:
(
AMAZING_DIFFICULTY
,
3
),
0x64
:
(
AMAZING_DIFFICULTY
,
4
),
0x54
:
(
MEDIUM_DIFFICULTY
,
0
),
0x55
:
(
MEDIUM_DIFFICULTY
,
1
),
0x56
:
(
MEDIUM_DIFFICULTY
,
2
),
0x57
:
(
MEDIUM_DIFFICULTY
,
3
),
0x58
:
(
MEDIUM_DIFFICULTY
,
4
),
0x48
:
(
EASY_DIFFICULTY
,
0
),
0x49
:
(
EASY_DIFFICULTY
,
1
),
0x4a
:
(
EASY_DIFFICULTY
,
2
),
0x4b
:
(
EASY_DIFFICULTY
,
3
),
0x4c
:
(
EASY_DIFFICULTY
,
4
),
0x3c
:
(
SUPAEASY_DIFFICULTY
,
0
),
0x3d
:
(
SUPAEASY_DIFFICULTY
,
1
),
0x3e
:
(
SUPAEASY_DIFFICULTY
,
2
),
0x3f
:
(
SUPAEASY_DIFFICULTY
,
3
),
0x40
:
(
SUPAEASY_DIFFICULTY
,
4
),
}
reverseNoteMap
=
dict
([(
v
,
k
)
for
k
,
v
in
list
(
noteMap
.
items
())])
dim
=
lambda
x
,
y
:
tuple
(
map
(
lambda
x
:
x
*
y
,
x
))
class
Event
:
def
__init__
(
self
,
length
):
self
.
length
=
length
class
Note
(
Event
):
def
__init__
(
self
,
number
,
length
,
special
=
False
,
tappable
=
False
):
Event
.
__init__
(
self
,
length
)
self
.
number
=
number
self
.
played
=
False
self
.
special
=
special
self
.
tappable
=
tappable
def
__repr__
(
self
):
return
"
Note <#%d> length %d
"
%
(
self
.
number
,
self
.
length
)
class
Tempo
(
Event
):
def
__init__
(
self
,
bpm
):
super
().
__init__
(
0
)
self
.
bpm
=
bpm
def
__repr__
(
self
):
return
"
<%d bpm>
"
%
self
.
bpm
class
MidiReader
(
midi
.
MidiOutStream
.
MidiOutStream
):
def
__init__
(
self
,
song
):
super
().
__init__
()
self
.
song
=
song
self
.
bpm
=
0
self
.
heldNotes
=
{}
self
.
velocity
=
{}
self
.
ticksPerBeat
=
480
self
.
tempoMarkers
=
[]
def
addEvent
(
self
,
track
,
event
,
time
=
None
):
if
time
is
None
:
time
=
self
.
abs_time
()
assert
time
>=
0
#print('addEvent', track, event, time)
#if track is None:
# for t in self.song.tracks:
# t.addEvent(time, event)
#elif track < len(self.song.tracks):
# self.song.tracks[track].addEvent(time, event)
def
abs_time
(
self
):
def
ticksToBeats
(
ticks
,
bpm
):
return
(
60000.0
*
ticks
)
/
(
bpm
*
self
.
ticksPerBeat
)
if
self
.
bpm
:
currentTime
=
midi
.
MidiOutStream
.
MidiOutStream
.
abs_time
(
self
)
# Find out the current scaled time.
# Yeah, this is reeally slow, but fast enough :)
scaledTime
=
0.0
tempoMarkerTime
=
0.0
currentBpm
=
self
.
bpm
for
i
,
marker
in
enumerate
(
self
.
tempoMarkers
):
time
,
bpm
=
marker
if
time
>
currentTime
:
break
scaledTime
+=
ticksToBeats
(
time
-
tempoMarkerTime
,
currentBpm
)
tempoMarkerTime
,
currentBpm
=
time
,
bpm
return
scaledTime
+
ticksToBeats
(
currentTime
-
tempoMarkerTime
,
currentBpm
)
return
0.0
def
header
(
self
,
format
,
nTracks
,
division
):
self
.
ticksPerBeat
=
division
def
tempo
(
self
,
value
):
bpm
=
60.0
*
10.0
**
6
/
value
self
.
tempoMarkers
.
append
((
midi
.
MidiOutStream
.
MidiOutStream
.
abs_time
(
self
),
bpm
))
if
not
self
.
bpm
:
self
.
bpm
=
bpm
#self.song.setBpm(bpm)
#print('bpm', bpm)
self
.
addEvent
(
None
,
Tempo
(
bpm
))
def
note_on
(
self
,
channel
,
note
,
velocity
):
if
self
.
get_current_track
()
>
1
:
return
self
.
velocity
[
note
]
=
velocity
self
.
heldNotes
[(
self
.
get_current_track
(),
channel
,
note
)]
=
self
.
abs_time
()
def
note_off
(
self
,
channel
,
note
,
velocity
):
if
self
.
get_current_track
()
>
1
:
return
try
:
startTime
=
self
.
heldNotes
[(
self
.
get_current_track
(),
channel
,
note
)]
endTime
=
self
.
abs_time
()
del
self
.
heldNotes
[(
self
.
get_current_track
(),
channel
,
note
)]
if
note
in
noteMap
:
track
,
number
=
noteMap
[
note
]
self
.
addEvent
(
track
,
Note
(
number
,
endTime
-
startTime
,
special
=
self
.
velocity
[
note
]
==
127
),
time
=
startTime
)
else
:
print
(
"
MIDI note 0x%x at %d does not map to any game note.
"
%
(
note
,
self
.
abs_time
()))
pass
except
KeyError
:
print
(
"
MIDI note 0x%x on channel %d ending at %d was never started.
"
%
(
note
,
channel
,
self
.
abs_time
()))
from
st3m.application
import
Application
,
ApplicationContext
import
st3m.run
import
leds
class
Flower
:
def
__init__
(
self
,
x
:
float
,
y
:
float
,
z
:
float
)
->
None
:
self
.
x
=
x
self
.
y
=
y
self
.
z
=
z
self
.
rot
=
0.0
self
.
rot_speed
=
1
/
800
#(((random.getrandbits(16) - 32767) / 32767.0) - 0.5) / 800
def
draw
(
self
,
ctx
:
Context
)
->
None
:
ctx
.
save
()
ctx
.
rotate
(
self
.
rot
)
ctx
.
translate
(
-
78
+
self
.
x
,
-
70
+
self
.
y
)
#ctx.translate(50, 40)
#ctx.translate(-50, -40)
#ctx.scale(100 / self.z, 100.0 / self.z)
ctx
.
move_to
(
76.221727
,
3.9788409
).
curve_to
(
94.027758
,
31.627675
,
91.038918
,
37.561293
,
94.653428
,
48.340473
).
rel_curve_to
(
25.783102
,
-
3.90214
,
30.783332
,
-
1.52811
,
47.230192
,
4.252451
).
rel_curve_to
(
-
11.30184
,
19.609496
,
-
21.35729
,
20.701768
,
-
35.31018
,
32.087063
).
rel_curve_to
(
5.56219
,
12.080061
,
12.91196
,
25.953973
,
9.98735
,
45.917643
).
rel_curve_to
(
-
19.768963
,
-
4.59388
,
-
22.879866
,
-
10.12216
,
-
40.896842
,
-
23.93099
).
rel_curve_to
(
-
11.463256
,
10.23025
,
-
17.377386
,
18.2378
,
-
41.515124
,
25.03533
).
rel_curve_to
(
0.05756
,
-
29.49286
,
4.71903
,
-
31.931936
,
10.342734
,
-
46.700913
).
curve_to
(
33.174997
,
77.048676
,
19.482194
,
71.413009
,
8.8631648
,
52.420793
).
curve_to
(
27.471602
,
45.126773
,
38.877997
,
45.9184
,
56.349456
,
48.518302
).
curve_to
(
59.03275
,
31.351935
,
64.893201
,
16.103886
,
76.221727
,
3.9788409
).
close_path
().
fill
()
ctx
.
restore
()
class
SecondScreen
(
BaseView
):
def
draw
(
self
,
ctx
:
Context
)
->
None
:
# Paint the background black
ctx
.
rgb
(
0
,
0
,
0
).
rectangle
(
-
120
,
-
120
,
240
,
240
).
fill
()
# Green square
ctx
.
rgb
(
0
,
255
,
0
).
rectangle
(
-
20
,
-
20
,
40
,
40
).
fill
()
def
think
(
self
,
ins
:
InputState
,
delta_ms
:
int
)
->
None
:
self
.
input
.
think
(
ins
,
delta_ms
)
media
.
think
(
delta_ms
)
def
on_enter
(
self
,
vm
:
Optional
[
ViewManager
])
->
None
:
super
().
on_enter
(
vm
)
#self._vm = vm
# Ignore the button which brought us here until it is released
#self.input._ignore_pressed()
media
.
load
(
'
/sd/song.mp3
'
)
class
App
(
Application
):
def
__init__
(
self
,
app_ctx
:
ApplicationContext
)
->
None
:
super
().
__init__
(
app_ctx
)
self
.
input
=
InputController
()
self
.
path
=
getattr
(
app_ctx
,
'
bundle_path
'
,
'
/flash/apps/PetalHero
'
)
if
not
self
.
path
:
self
.
path
=
'
/flash/apps/PetalHero
'
print
(
self
.
path
)
midiIn
=
midi
.
MidiInFile
(
MidiReader
(
None
),
self
.
path
+
'
/notes.mid
'
)
#midiIn.read()
self
.
flower
=
Flower
(
0
,
0
,
0.01
)
self
.
time
=
0
self
.
repeats
=
0
def
draw
(
self
,
ctx
:
Context
):
ctx
.
rgb
(
*
GO_GREEN
)
ctx
.
rgb
(
*
PUSH_RED
)
ctx
.
linear_gradient
(
-
120
,
-
120
,
120
,
120
)
ctx
.
add_stop
(
0.0
,
[
94
,
0
,
0
],
1.0
)
ctx
.
add_stop
(
1.0
,
[
51
,
0
,
0
],
1.0
)
ctx
.
rectangle
(
-
120
,
-
120
,
240
,
240
)
ctx
.
fill
()
ctx
.
save
()
ctx
.
translate
(
0
,
-
10
)
ctx
.
rgba
(
0.1
,
0.4
,
0.3
,
0.42
)
self
.
flower
.
draw
(
ctx
)
ctx
.
linear_gradient
(
-
50
,
0
,
50
,
0
)
ctx
.
add_stop
(
0.0
,
[
145
,
37
,
0
],
1.0
)
ctx
.
add_stop
(
0.5
,
[
245
,
111
,
0
],
0.75
)
ctx
.
add_stop
(
1.0
,
[
151
,
42
,
0
],
1.0
)
#ctx.rgb(0.1, 0.4, 0.3)
ctx
.
font
=
"
Camp Font 2
"
ctx
.
font_size
=
90
ctx
.
text_align
=
ctx
.
CENTER
ctx
.
text_baseline
=
ctx
.
MIDDLE
ctx
.
move_to
(
0
,
-
30
)
ctx
.
text
(
"
PETAL
"
)
ctx
.
move_to
(
0
,
30
)
ctx
.
text
(
"
HERO
"
)
ctx
.
restore
()
ctx
.
font
=
"
Camp Font 3
"
ctx
.
font_size
=
16
ctx
.
text_align
=
ctx
.
CENTER
ctx
.
text_baseline
=
ctx
.
MIDDLE
ctx
.
gray
(
1.0
)
ctx
.
move_to
(
0
,
70
+
math
.
sin
(
self
.
time
*
4
)
*
4
)
ctx
.
text
(
"
Press the button...
"
)
def
think
(
self
,
ins
:
InputState
,
delta_ms
:
int
)
->
None
:
self
.
input
.
think
(
ins
,
delta_ms
)
media
.
think
(
delta_ms
)
for
c
in
[
self
.
flower
]:
c
.
rot
+=
float
(
delta_ms
)
*
c
.
rot_speed
self
.
time
+=
delta_ms
/
1000
if
self
.
time
//
18
>
self
.
repeats
and
self
.
repeats
>=
0
:
media
.
load
(
self
.
path
+
'
/menu.mp3
'
)
self
.
repeats
+=
1
if
self
.
input
.
buttons
.
app
.
middle
.
pressed
:
self
.
vm
.
push
(
SecondScreen
(),
ViewTransitionSwipeLeft
())
if
self
.
exiting
:
return
#leds.set_brightness(32 - int(math.cos(self.time) * 32))
led
=
-
3
for
col
in
[
RED
,
(
1.0
,
1.0
,
0.0
),
BLUE
,
PUSH_RED
,
GO_GREEN
]:
for
i
in
range
(
7
):
leds
.
set_rgb
(
led
if
led
>=
0
else
led
+
40
,
*
dim
(
col
,
-
math
.
cos
(
self
.
time
)
/
2
+
0.5
))
led
+=
1
leds
.
set_rgb
(
led
,
0
,
0
,
0
)
led
+=
1
leds
.
update
()
def
on_enter
(
self
,
vm
:
Optional
[
ViewManager
])
->
None
:
super
().
on_enter
(
vm
)
#self._vm = vm
# Ignore the button which brought us here until it is released
#self.input._ignore_pressed()
media
.
load
(
self
.
path
+
'
/menu.mp3
'
)
self
.
repeats
=
0
self
.
time
=
0
self
.
exiting
=
False
leds
.
set_brightness
(
69
)
def
on_exit
(
self
):
super
().
on_exit
()
media
.
stop
()
self
.
exiting
=
True
leds
.
set_all_rgb
(
0
,
0
,
0
)
leds
.
set_brightness
(
69
)
leds
.
update
()
if
__name__
==
'
__main__
'
:
st3m
.
run
.
run_view
(
App
(
ApplicationContext
()))
This diff is collapsed.
Click to expand it.
flow3r.toml
0 → 100644
+
10
−
0
View file @
cc42740e
[app]
name
=
"Petal Hero"
menu
=
"Music"
[entry]
class
=
"App"
[metadata]
author
=
"dos"
license
=
"GPL-3.0-or-later"
This diff is collapsed.
Click to expand it.
menu.mp3
0 → 100644
+
0
−
0
View file @
cc42740e
File added
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