はじめに
Adafruit の PyBadge に関するこの記事を読んでいて、Wio Terminalでも動かしてみたいなと思ったところ、現状の Wio Terminal の CircuitPython には ugame や stage といったモジュールが組み込まれていませんでした。
ということで、Wio Terminal の CircuitPython 用に Stage ライブラリを組み込んでみました。
ビルド手順
※ CircuitPython のビルド環境構築については省略します。 BUILDING.mdを参考に構築してください。
ソース中の Stage ライブラリのあるディレクトリに移動して、Wio Terminal 用のディレクトリを作成します。
$ cd circuitpython/frozen/circuitpython-stage/
$ mkdir seeeduino_wio_terminal
$ cd seeeduino_wio_terminal
作成した Wio Terminal 用のディレクトリにファイル ugame.py
を以下の内容で作成します。
import board
import digitalio
import analogio
import gamepad
import stage
K_X = 0x01
K_DOWN = 0x02
K_LEFT = 0x04
K_RIGHT = 0x08
K_UP = 0x10
K_O = 0x20
K_START = 0x40
K_SELECT = 0x80
display = board.DISPLAY
buttons = gamepad.GamePad(
digitalio.DigitalInOut(board.SWITCH_PRESS),
digitalio.DigitalInOut(board.SWITCH_DOWN),
digitalio.DigitalInOut(board.SWITCH_LEFT),
digitalio.DigitalInOut(board.SWITCH_RIGHT),
digitalio.DigitalInOut(board.SWITCH_UP),
digitalio.DigitalInOut(board.BUTTON_1),
digitalio.DigitalInOut(board.BUTTON_2),
digitalio.DigitalInOut(board.BUTTON_3)
)
class DummyAudio:
def play(self, f, loop=False):
pass
def stop(self):
pass
def mute(self, mute):
pass
audio = DummyAudio()
stage.py
のシンボリックリンクを作成します。
$ ln -s ../stage.py .
※ ここまでの修正は GitHub のここにも置いておきました。
CircuitPython の Wio Terminal 用ボード定義ディレクトリに移動します。
$ cd ../../../ports/atmel-samd/boards/seeeduino_wio_terminal/
board.c
を以下の内容で修正します。
@@ -47,7 +47,7 @@
0xc1, 0x01, 0x10, // Power control SAP[2:0];BT[3:0]
0xc5, 0x02, 0x3e, 0x28, // VCM control
0xc7, 0x01, 0x86, // VCM control2
- 0x36, 0x01, 0x38, // Memory Access Control
+ 0x36, 0x01, 0xe8, // Memory Access Control
0x37, 0x01, 0x00, // Vertical scroll zero
0x3a, 0x01, 0x55, // COLMOD: Pixel Format Set
0xb1, 0x02, 0x00, 0x18, // Frame Rate Control (In Normal Mode/Full Colors)
@@ -84,7 +84,7 @@
240, // Height
0, // column start
0, // row start
- 180, // rotation
+ 0, // rotation
16, // Color depth
false, // Grayscale
false, // pixels in a byte share a row. Only valid for depths < 8
これ、displayio モジュールがソフトウェアで 180° 回転させて表示しているのを、元からハードウェア設定的に 180° 回転させる修正です。なぜ、わざわざこんなことするかというと、Stage ライブラリが displayio の画面回転のことなんて無視しているので、180° 回転して(上下さかさまになったように)表示されてしまうためです。
mpconfigboard.mk
を以下の内容で修正して Stage ライブラリの組込みを有効化します。
@@ -12,3 +12,8 @@
LONGINT_IMPL = MPZ
CIRCUITPY_VECTORIO = 1
+
+CIRCUITPY_GAMEPAD = 1
+CIRCUITPY_STAGE = 1
+
+FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/seeeduino_wio_terminal
CircuitPython をビルドします。
$ cd ../../../..
$ make -C mpy-cross
$ cd ports/atmel-samd
$ make BOARD=seeeduino_wio_terminal
ビルドが終わると、CircuitPython ファームウェアが build-seeeduino_wio_terminal/firmware.uf2
にできるので、これを Wio Terminal のブートローダでインストールします。
以上でモジュール stage と ugame が使えるようになっています。
おわりに
きっかけとなった記事のデモスクリプトを Wio Terminal の画面の大きさに合わせて修正したものを以下に載せておきます。
import ugame
import stage
class Ball(stage.Sprite):
def __init__(self, x, y):
super().__init__(bank, 1, x, y)
self.dx = 2
self.dy = 1
def update(self):
super().update()
self.set_frame(self.frame % 4 + 1)
self.move(self.x + self.dx, self.y + self.dy)
if not 0 < self.x < 303:
self.dx = -self.dx
if not 0 < self.y < 224:
self.dy = -self.dy
bank = stage.Bank.from_bmp16("ball.bmp")
background = stage.Grid(bank, 20, 15)
text = stage.Text(12, 1)
text.move(110, 110)
text.text("Hello world!")
ball1 = Ball(128, 0)
ball2 = Ball(0, 152)
ball3 = Ball(222, 128)
game = stage.Stage(ugame.display, 24)
sprites = [ball1, ball2, ball3]
game.layers = [text, ball1, ball2, ball3, background]
game.render_block()
while True:
for sprite in sprites:
sprite.update()
game.render_sprites(sprites)
game.tick()