MicroPython is a great way for beginners to get a feel for PicoSystem.
Play with audio beeps and boops via the REPL, and get a simple game running with minimal boilerplate.
Go to the GitHub releases page to find the latest release of PicoSystem MicroPython.
- Scroll down and download the .uf2 file. eg: "picosystem-v0.1.0-micropython-v1.17.uf2"
- Connect your PicoSystem to your computer.
- Hold X while powering on your PicoSystem to enter bootloader mode.
- Copy the .uf2 file (linked below) onto the "RPI-RP2" directory that appears.
Every PicoSystem MicroPython application must have the following basic form:
def update(tick):
pass
def draw(tick):
pass
start()
The update
function is where your game logic goes. draw
is responsible for drawing your game world to the screen. Call start()
to signal to PicoSystem
that it should start cranking the game engine.
In your update
function you can optionally call quit()
to break out of the game loop.
If you're just exploring on the REPL, call flip()
to display your changes and update input.
Try it:
>>> pen(0, 0, 0)
>>> clear()
>>> pen(15, 15, 15)
>>> text("Hello World")
>>> flip()
If you find things not working as expected on the REPL, reset your pen, cursor, camera, clip, and alpha like so:
>>> pen();cursor();camera();clip();alpha()
pen(number)
,pen(r, g, b)
orpen(r, g, b, a)
- set the drawing colourpen()
- reset the drawing colour to white (15, 15, 15, 15)clip(x, y, w, h)
- set the clipping region (drawing outside this region is ignored)clip()
- reset the clipping region to the drawing target size (0, 0, 120, 120 if SCREEN)blend(COPY / ALPHA / MASK)
- set the blend modeblend()
- reset the blend mode (ALPHA
)target(Buffer)
- set a Buffer to draw intotarget()
- reset the draw target toSCREEN
camera(x, y)
- set the camera locationcamera()
- reset the camera location (0, 0)cursor(x, y)
- set the text cursorcursor()
- reset the text cursor (0, 0)spritesheet(Buffer)
- set the spritesheetspritesheet()
- reset the spritesheet to the builtin default
clear()
- clear to penpixel(x, y)
- single pixelrect(x, y, w, h)
- rectanglefrect(x, y, w, h)
- filled rectanglecircle(x, y, r)
- circlefcircle(x, y, r)
- fcircleellipse(x, y, rx, ry)
- ellipsefellipse(x, y, rx, ry)
- fellipseline(x1, y1, x2, y2)
- line from xy1 to xy2hline(x, y, length)
- horizontal line starting from xy, length in pixelsvline(x, y, length)
- vertical line starting from xy, length in pixelspoly((x, y), (x, y), (x, y))
- polygon (supply points as tuples)fpoly((x, y), (x, y), (x, y))
- filled polygon (supply points as tuples)text(message)
- message at cursor positiontext(message, wrap)
- message at cursor position, text will be wrapped on word boundaries if it exceeds wrap width in pixelstext(message, x, y)
- message at xytext(message, x, y, wrap)
- message at xy, text will be wrapped on word boundaries if it exceeds wrap width in pixelssprite(i, x, y)
- draws sprite from current spritesheet at xysprite(i, x, y, cx, cy)
- draws a rectangle of sprites from current spritesheet at xy, cx sprites across and cy sprites downsprite(i, x, y, cx, cy, dw, dh)
- draws a rectangle of sprites from current spritesheet at xy, cx sprites across and cy sprites down, scaled to a rectangle dw by dh pixelssprite(i, x, y, cx, cy, dw, dh, flags)
- draws a rectangle of sprites from current spritesheet at xy, cx sprites across and cy sprites down, scaled to a rectangle dw by dh pixels, flags can be any combination of HFLIP and VFLIPblit(Buffer, x, y, w, h, dx, dy)
- blit a portion of a Buffer to dx,dyblit(Buffer, x, y, w, h, dx, dy, dw, dh)
- blit a portion of a Buffer to dx,dy stretching to dw,dh
pressed(A / B / X / Y / UP / DOWN / LEFT / RIGHT)
-True
if the button has been pressed since the last frame.button(A / B / X / Y / UP / DOWN / LEFT / RIGHT)
-True
if the button is pressed
A Buffer contains an image or spritesheet in the screen pixel format (16bit AAAARRRRGGGGBBBB).
You can draw to a Buffer using all the regular drawing operations, or draw a Buffer to the screen with blit()
.
my_buffer = Buffer(width, height)
- create a new Bufferopen(filename, "rb").readinto(my_buffer)
- read an image into a Buffertarget(my_buffer)
- set your Buffer as the draw targettarget()
- set the screen as the draw target
When target()
is set to a Buffer, calling clip()
will reset the clipping region
to the size of the targeted Buffer.
PicoSystem's text()
function has some special escape sequences:
\\penRGBA
- set the text colour to RGBA, eg red is:\\penF00F
\\spr000
- draw a sprite in-line with text, eg a leaf:\\spr007
rgb(r, g, b)
orrgb(r, g, b, a)
- return a new colour (16bit number)hsv(hue, sat, value)
- convert from HSV to RGB and return a colour (16bit number)intersects(x, y, w, h, cx, cy, cw, ch)
- check if two rectangles intersectix, iy, iw, ih = intersection(x, y, w, h, cx, cy, cw, ch)
- return the intersection between two rectanglescontains(x, y, cx, cy, cw, ch)
- check if a rectangle cxywh contains point xy
You can use open(filename, "rb").readinto(Buffer)
to load one of the supplied .16bpp spritesheet files, like so:
my_sprites = Buffer(128, 128)
open("spritesheet.16bpp", "rb").readinto(my_sprites)
spritesheet(my_sprites)
These steps mirror those in the GitHub actions workflow: https://github.com/pimoroni/picosystem/blob/main/.github/workflows/micropython.yml
A customised version of MicroPython is required, since PicoSystem uses some hacks that have not yet been tidied and submitted upstream.
Clone PicoSystem (if you have not already done so):
git clone https://github.com/pimoroni/picosystem
Clone MicroPython and fetch the submodules (note you must use the experimental/picosystem
branch for now, this is subject to change):
git clone https://github.com/micropython/micropython
cd micropython
git submodule update --init
cd ../../mpy-cross
make
cd ../ports/rp2
You must build against the PicoSystem set of USER_C_MODULES
and use the PIMORONI_PICOSYSTEM
board directory. These can be specified when configuring MicroPython, like so:
cmake -S . -B build-picosystem -DPICO_BUILD_DOCS=0 -DUSER_C_MODULES=../../../picosystem/micropython/modules/micropython.cmake -DMICROPY_BOARD_DIR=../../../picosystem/micropython/PIMORONI_PICOSYSTEM
cmake --build build-picosystem
If you see an error about pio
headers, don't dispair, just build again. There's some kind of race condition here.
cp build-picosystem/firmware.uf2 /path/to/RPI-RP2/