Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@inachi

Wio Terminal の CircuitPython に Stage ライブラリを追加する

はじめに

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()

スクリーンショット 2020-09-20 11.58.00.png

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
inachi

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?