pimoroni / picosystem

PicoSystem libraries and examples.
MIT License
145 stars 33 forks source link

PicoSystem SDK port for MicroPython. #12

Closed Gadgetoid closed 3 years ago

Gadgetoid commented 3 years ago

Requires PIMORONI_PICOSYSTEM board type with a custom root pointer. Available here: https://github.com/pimoroni/micropython/tree/board/rp2/pimoroni_picosystem

TODO:

Testing

CI Builds

You can grab beta builds from the CI artifacts. Eg: :arrow_right: :arrow_right: :arrow_right: https://github.com/pimoroni/picosystem/suites/4086239197/artifacts/104054214 :arrow_left: :arrow_left: :arrow_left:

Tips:

Build from source

These instructions may be a bit patchy, YMMV!

git clone https://github.com/pimoroni/picosystem
git clone https://github.com/pimoroni/micropython -b board/rp2/pimoroni_picosystem
cd micropython
git submodule update --init
cd lib/pico-sdk
git submodule update --init
cd ../../micropython/mpy_cross
make
cd ../ports/rp2
cp ../../../picosystem/micropython/modules_py/boot.py modules/
make USER_C_MODULES=../../../picosystem/micropython/modules/micropython.cmake BOARD=PIMORONI_PICOSYSTEM
cp build-PIMORONI_PICOSYSTEM/firmware.uf2 /path/to/RPI-RP2/

Find firmware.uf2 in build-PIMORONI_PICOSYSTEM

Gadgetoid commented 3 years ago

Code for cycling through spritesheets:

from picosystem import *

spritesheets = [
    "s4m_ur4i-dingbads.16bpp",
    "s4m_ur4i-pirate-characters.16bpp",
    "s4m_ur4i-pirate-tilemap.16bpp",
    "s4m_ur4i-platformer.16bpp",
    "s4m_ur4i-space-shooter-backdrop.16bpp",
    "s4m_ur4i-space-shooter-ships.16bpp",
    "s4m_ur4i-top-down-shooter.16bpp"
]

buffer = Buffer(128, 128)
spritesheet(buffer)
last_update = 0
current_sheet = 0

def update(ticks):
    global last_update, current_sheet
    if ticks - last_update > 100:
        last_update = ticks
        open(spritesheets[current_sheet], "rb").readinto(buffer)
        current_sheet += 1
        if current_sheet >= len(spritesheets):
            current_sheet = 0

def draw():
    for x in range(int(120 / 8)):
        for y in range(int(120 / 8)):
            sprite(x + y * int(120 / 8), x * 8, y * 8)

while True: tick()
Gadgetoid commented 3 years ago

Some SFX:

Voice().play("A7", bend=1500) # Coin 1
Voice().play("A7", bend=1000) # Coin 2

Voice(noise=100).play("A7", bend=100) # Sonic WHOOSH

Voice(noise=0, attack=10).play("A1", bend=20, bend_ms=20, hold=1000) # Go to red alert
Voice(noise=100, distort=100).play("D4", bend=1, bend_ms=1, hold=1000)

Voice(noise=0, attack=10).play("A3", bend=200, bend_ms=50, hold=200) # Power up

Voice(noise=100, distort=100).play("D3", bend=-10, bend_ms=10) # Floorboard

Voice(noise=100, distort=100).play("D4", bend=-10, bend_ms=10) # Crunch
Gadgetoid commented 3 years ago

Sound has been re-worked. See examples!

voice = Voice(attack, decay, sustain, release, bend, bend_ms, reverb, noise, distort)
voice.play(frequency, duration, volume)
voice.bend(amount, speed)
voice.effects(reverb, noise, distort)
voice.envelope(attack, decay, sustain, release)

Attack, decay, release, duration and reverb are all given in milliseconds. Volume, Sustain, Noise and Distort are given in % (0-100). Frequency and Bend are given in Hz. "bend_ms" is also given in milliseconds, indicating the interval at which the bend frequency is added to the base frequency.