Skip to content
Snippets Groups Projects
Verified Commit 99c07b00 authored by dos's avatar dos
Browse files

Reorganize

parent cc42740e
No related branches found
No related tags found
No related merge requests found
import sys import media, math
import media, math, random
from st3m.ui.colours import * from st3m.ui.colours import *
from st3m.input import InputController from st3m.input import InputController
from st3m.ui.view import BaseView, ViewManager, ViewTransitionSwipeLeft from st3m.ui.view import 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 from st3m.application import Application, ApplicationContext
import st3m.run import st3m.run
import leds import leds
import time
import bl00mbox
# TODO: FIXME
import sys
sys.path.append('/flash/apps/PetalHero')
class Flower: import song
def __init__(self, x: float, y: float, z: float) -> None: import flower
self.x = x import utils
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: class PetalHero(Application):
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: def __init__(self, app_ctx: ApplicationContext) -> None:
super().__init__(app_ctx) super().__init__(app_ctx)
self.input = InputController() self.input = InputController()
self.path = getattr(app_ctx, 'bundle_path', '/flash/apps/PetalHero') self.path = getattr(app_ctx, 'bundle_path', '/flash/apps/PetalHero')
if not self.path: if not self.path:
self.path = '/flash/apps/PetalHero' 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.flower = flower.Flower(0, 0, 0.01)
self.time = 0 self.time = 0
self.repeats = 0 self.repeats = 0
def draw(self, ctx: Context): self.blm = bl00mbox.Channel("Petal Hero")
ctx.rgb(*GO_GREEN)
ctx.rgb(*PUSH_RED) self.in_sound = self.blm.new(bl00mbox.patches.sampler, self.path + "/in.wav")
self.in_sound.signals.output = self.blm.mixer
self.out_sound = self.blm.new(bl00mbox.patches.sampler, self.path + "/out.wav")
self.out_sound.signals.output = self.blm.mixer
self.crunch_sound = []
for i in range(3):
self.crunch_sound.append(self.blm.new(bl00mbox.patches.sampler, self.path + "/crunch" + str(i+1) + ".wav"))
self.crunch_sound[i].signals.output = self.blm.mixer
def draw(self, ctx: Context):
ctx.linear_gradient(-120, -120, 120, 120) ctx.linear_gradient(-120, -120, 120, 120)
ctx.add_stop(0.0, [94, 0, 0], 1.0) ctx.add_stop(0.0, [94, 0, 0], 1.0)
...@@ -263,6 +84,7 @@ class App(Application): ...@@ -263,6 +84,7 @@ class App(Application):
def think(self, ins: InputState, delta_ms: int) -> None: def think(self, ins: InputState, delta_ms: int) -> None:
self.input.think(ins, delta_ms) self.input.think(ins, delta_ms)
media.think(delta_ms) media.think(delta_ms)
for c in [self.flower]: for c in [self.flower]:
c.rot += float(delta_ms) * c.rot_speed c.rot += float(delta_ms) * c.rot_speed
self.time += delta_ms / 1000 self.time += delta_ms / 1000
...@@ -272,7 +94,11 @@ class App(Application): ...@@ -272,7 +94,11 @@ class App(Application):
self.repeats += 1 self.repeats += 1
if self.input.buttons.app.middle.pressed: if self.input.buttons.app.middle.pressed:
self.vm.push(SecondScreen(), ViewTransitionSwipeLeft()) self.in_sound.signals.trigger.start()
self.vm.push(song.SongView(self), ViewTransitionSwipeLeft())
if self.input.buttons.os.middle.pressed:
self.out_sound.signals.trigger.start()
if self.exiting: if self.exiting:
return return
...@@ -282,14 +108,14 @@ class App(Application): ...@@ -282,14 +108,14 @@ class App(Application):
led = -3 led = -3
for col in [RED, (1.0, 1.0, 0.0), BLUE, PUSH_RED, GO_GREEN]: for col in [RED, (1.0, 1.0, 0.0), BLUE, PUSH_RED, GO_GREEN]:
for i in range(7): for i in range(7):
leds.set_rgb(led if led >= 0 else led + 40, *dim(col, -math.cos(self.time) / 2 + 0.5)) leds.set_rgb(led if led >= 0 else led + 40, *utils.dim(col, -math.cos(self.time) / 2 + 0.5))
led += 1 led += 1
leds.set_rgb(led, 0, 0, 0) leds.set_rgb(led, 0, 0, 0)
led += 1 led += 1
leds.update() leds.update()
def on_enter(self, vm: Optional[ViewManager]) -> None: def on_enter(self, vm) -> None:
super().on_enter(vm) super().on_enter(vm)
#self._vm = vm #self._vm = vm
# Ignore the button which brought us here until it is released # Ignore the button which brought us here until it is released
...@@ -308,6 +134,5 @@ class App(Application): ...@@ -308,6 +134,5 @@ class App(Application):
leds.set_brightness(69) leds.set_brightness(69)
leds.update() leds.update()
if __name__ == '__main__': if __name__ == '__main__':
st3m.run.run_view(App(ApplicationContext())) st3m.run.run_app(PetalHero)
File added
File added
File added
...@@ -3,7 +3,7 @@ name = "Petal Hero" ...@@ -3,7 +3,7 @@ name = "Petal Hero"
menu = "Music" menu = "Music"
[entry] [entry]
class = "App" class = "PetalHero"
[metadata] [metadata]
author = "dos" author = "dos"
......
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()
in.wav 0 → 100644
File added
import midi
AMAZING_DIFFICULTY = 0
MEDIUM_DIFFICULTY = 1
EASY_DIFFICULTY = 2
SUPAEASY_DIFFICULTY = 3
baseNotes = {
0x60: AMAZING_DIFFICULTY,
0x54: MEDIUM_DIFFICULTY,
0x48: EASY_DIFFICULTY,
0x3c: SUPAEASY_DIFFICULTY
}
noteMap = {}
for basenote, diff in baseNotes.items():
for note in range(5):
noteMap[basenote + note] = (diff, note)
reverseNoteMap = dict([(v, k) for k, v in list(noteMap.items())])
class Event:
def __init__(self, length):
self.length = length
class Note(Event):
def __init__(self, number, length, special = False, tappable = False):
super().__init__(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()))
out.wav 0 → 100644
File added
song.py 0 → 100644
from st3m.input import InputController
from st3m.ui.view import BaseView, ViewManager, ViewTransitionSwipeLeft
from st3m.application import Application, ApplicationContext
import media
import midi
import midireader
class SongView(BaseView):
def __init__(self, app):
super().__init__()
self.app = app
midiIn = midi.MidiInFile(midireader.MidiReader(None), self.app.path + '/notes.mid')
midiIn.read()
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')
def on_exit(self):
super().on_exit()
self.app.out_sound.signals.trigger.start()
start.mp3 0 → 100644
File added
dim = lambda x, y: tuple(map(lambda x: x * y, x))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment