ライン

ワンチップマイコンによる回転スクロールシューティングゲーム VELUDDA

ライン

2014年11月15日

最終更新日 2023年7月8日(Raspberry Pi Pico版追加

 電子機器に内蔵されている基板を見ていると、何やら構造物の建ち並ぶ街並みを上空から眺めているような気持ちになることがあります。この基板上空を空飛ぶ円盤に乗って飛行していると、突如前方から攻撃を仕掛けられ、また地上からは砲弾が狙って飛んでくる・・・しまった、ここは敵の要塞上空だったのか!生きて帰るには敵機を全滅させるしかない!
 そんな空想に耽りながら、PIC32MXマイコンによるオリジナルの本格的シューティングタイプのテレビゲームを作りました。タイトルは「VELUDDA」(ベルーダ)。マイコンチップだけでカラービデオ信号生成とサウンド出力、そして画面の回転とスクロールの処理をしながらシューティングゲームを実行するという無茶をしていますが、実に動きは滑らかです。PIC32MXの性能の高さを実感することができる作品に仕上がりました。


ハードウェア

 以前行った、拡大縮小回転機能付きビデオ出力実験の回路に、操作用のボタン6個と、モノラルの音声出力を追加しただけの、シンプルなハードウェア構成です。使用したマイコンはPIC32MX370F512Hで、動作システムクロックが最大100MHz、搭載メモリはプログラム用フラッシュが512KB+ブート用12KB、SRAMが128KBとこれまでのPICマイコンとは比べものにならないくらい高性能なチップです。それでいてチップ自体は6ドル程度と、非常にコストパフォーマンスに優れています。パッケージが0.5ミリピッチの64ピンTQFPというのが難点ですが、市販の変換基板を使うなどすれば扱いやすくなります。また、試したわけではありませんが、USB機能搭載のPIC32MX470F512Hでも動作すると思います。
 電源は3.3Vですが、アルカリ乾電池2本でも動作します。私は5VのACアダプタと3端子レギュレータで3.3Vを作っています。6個のボタンは、タクトスイッチでよいです。カバーをつけると操作しやすくなるのでお勧めです。
 発振子には必ず14.31818MHzの水晶を使ってください。セラミックのレゾネータでは精度が低く、カラーが出せません。
 システムの詳細は解説は、拡大縮小回転機能付きビデオ出力実験を参照してください。

 右の写真はpupさんが起こしてくれたプリント基板で製作したものです。チップ部品を使用して、とてもコンパクトに仕上げてくれました。

回路図

完成写真

プリント基板

遊び方

 ビデオ出力と音声出力をテレビにつなぎ、電源を入れるとタイトル画面が出ます。ここでSTARTボタンを押すと、音楽とともにゲームが始まります。
 自機は画面下のほうにある白くて丸い円盤です。敵要塞の上空を円盤で飛んで敵部隊を全滅させるという想定です。ゲームが始まると地上の要塞画像が下にスクロールしていきます。円盤は停止することができません。その代わり、左右のボタンで旋回することができます。旋回すると要塞画像が回転します。また、上ボタンを押している間は、通常の1.5倍にスピードアップします。マップの上下端、左右端はつながっているので、飛んでいるとやがて一周します。
 ゲーム開始するとすぐに、敵が編隊を組んで現れます。FIREボタンでミサイルを発射して、やっつけてください。敵機に衝突すると自機が1機減ります。敵機を全滅させるとステージクリアです。
 ステージ2からは地上から砲弾が撃たれます。砲弾は狙って飛んできますので、必ず避けてください。砲台はミサイルで破壊することができません。ただ、落下した砲弾が当たったときだけ破壊されます。
 自機は最初5機あります。ステージが5の倍数ごとにサービスで1機増えます。残りがなくなるとゲーム終了です。
 タイトル画面で上下ボタンにより、BGMの有無を選択できます。BGMにはエリック・サティの「グノシエンヌ」という少し風変わりな曲を採用したのですが、音源が単純な方形波のため、長時間プレイしていると、だんだん耳障りになってくるかもしれません。そのときはMUSIC OFFを選択してください。また、ゲーム中にSTARTボタンを押すと、一時停止することができます。

タイトル画面

プレイ画面

キャラクター一覧


画面回転スクロールの原理

 ゲーム全体マップは横1024ドット×縦512ドットのフィールドになっています。このフィールドの画像をスクロールと回転をさせながら画面に切り取って表示させるのが、本ゲームプログラムの一番の課題ですので、ここを解説します。
 前述の通り、拡大縮小回転機能付きビデオ出力実験のシステムを使いました。ただし、画面最上部は得点などを表示させたいので、改造して8行分だけ固定領域を設けました。この領域を除くと、表示領域は横256ドット×縦216ドットとなります。ビデオメモリは256ドット×256ドット、8ビット色分あり、ここから実際に表示させたい部分を切り取って出力するように設定を行うのですが、そのままの大きさで画面を回転させるとビデオメモリ領域からはみ出してしまいますので、1周してもはみ出さないように表示領域を縮小する必要があります(表示自体は拡大される)。
 計算すると約1.31倍するとよいことがわかるので、表示領域はその逆数をとって、ちょうど4分の3、横192×縦162ドット相当としました。

解説図1


 回転だけであればこれだけでよいのですが、スクロールさせるとなると、地上背景のマップ情報から一部を切り取って描画し続ける必要があります。
 スクロールするたびに表示領域全体を描画していると処理がとても間に合わないので、変更点だけを追加で描画し、画面表示開始位置を変更する方法を使いました。単純な縦スクロールのゲームでは普通に使われる手法ですが、回転を伴うと話は簡単ではありません。
 まず最初に表示領域全体の描画を行うのですが、このとき傾いている場合は図のように、その表示領域を含む矩形の描画窓領域分をビデオメモリ上に描画します。
 そして、スクロールや回転をすると、同様に新たな描画窓の矩形範囲を計算し、上下左右それぞれの増分だけ描画を行います(図の斜線領域)。

解説図2


 ビデオメモリは256ドット×256ドットの有限な範囲しかありませんが、表示は上下端、左右端がそれぞれ環状につながっていて繰り返されるようになっています。描画する際も、例えば上にはみ出した場合は、一番下に描画を行います。あとは表示開始位置と表示角度の設定を変更すると、回転スクロールが実現されます。
 このようにして、移動するたびに追加描画をしていくのですが、ビデオメモリが環状になっているため、追加描画した反対側は自然に消滅(新たに反対側の表示に消費される)していきます。最初に計算したように、描画窓がビデオメモリのサイズを超えることはないので、描画が反対側の表示部分を侵食することもありません。
 このように巧妙な仕組みで、回転スクロールを実現することができました。

解説図3


プログラムの使い方とダウンロード

 ソースファイルは6個に分かれています。またヘッダファイルが3個あります。
    bmpdata.s    地上画像データ
    graphlib2.c    グラフィック描画関連ライブラリ、フォントデータ含む
    musicdata.c   音楽関連データ
    rotatevideo2.c  拡大縮小回転機能付きビデオ出力システム(改造版)
    veludda.c     ゲーム本体(main関数、コンフィグ設定など含む)
    veludda_chars.c キャラクタービットマップデータ
    graphlib2.h    グラフィック描画関連ライブラリのヘッダー
    rotatevideo2.h  拡大縮小回転機能付きビデオ出力システム(改造版)のヘッダー
    veludda.h     ゲーム関連ヘッダー。各種ゲームパラメータ設定もここ

 MPLAB Xで全てをプロジェクトに追加して、コンパイルしてください。コンパイルに 際しては、オプションで最適化の設定が必要です。「xc32-g++」のoptimizationの項目でoptimization-levelをLevel1以上にしてください。Level1まではフリー版でも利用可能です。コンパイル済みのHEXファイルも公開しておきます。
 また、CコンパイラはXC32 v1.32以下に対応しています。v1.33から仕様が変更となり、ライブラリとしてplib.hを使用すると警告が出るようになりました。マイクロチップ社としては、今後xc.hの利用を推奨しているようですが、これまで作成したビデオ出力関連システムはplib.h用となっていて、xc.hには対応していません。ただ、v1.33でplib.hを使用した場合も、警告は出ますがコンパイルは正常にできているようです。

ソースプログラムおよびHEXファイルのダウンロード


最後に

 拡大縮小回転機能付きビデオ出力実験に成功してから、応用作品を早く作りたいと思ってきましたが、ようやく完成しました。ゲームとしてもなかなか楽しめるものになったので、満足しています。今回のゲームを応用すれば、同様の回転スクロール型のビデオゲームが簡単に作れます。
 PIC32MX370F512HおよびUSB機能搭載版のPIC32MX470F512Hは、今のところ国内の販売店では販売されていないようで、マイクロチップのDirectショップや、その他海外通販サイトから購入する必要があるのが残念ですが、PICマイコンとしては、PIC32MZシリーズに次ぐ性能で、チップ自体のコストパフォーマンスは非常に高く、入手して損はないと思います。入手しましたらぜひこのゲームで遊んでみてください。
 ご意見、ご質問、メッセージなどありましたらこちらの掲示板にお願いします。




おまけ



小型カラーグラフィック液晶対応版

2017.6.11 追加

 小型のカラーグラフィック液晶の価格が下がり、入手しやすくなったので、本ゲームを液晶用に改造してみました。

LCD版VELUDDA

 使用した液晶は2.6型で解像度240×320ドットのTFT1N3204-Eとキャリー基板のセット品です。本来は縦長の液晶ですが、今回は横にして使います。TFT1N3204-Eに搭載の液晶コントローラICはルネサスのR61505Wです。同じ解像度でコマンド互換性のあるコントローラ(ILI9325など)を搭載した液晶であれば、初期化部分の修正で簡単に移植することも可能でしょう。
 マイコンはビデオ出力版と同じPIC32MX370F512Hを使用します。システムクロックには水晶は使わず、内蔵FRCをPLL回路経由で96MHzとして動作させています。RAMを128Kバイト搭載で、96MHzに対応していれば、他のPIC32MXシリーズでも動作すると思います。
 液晶との接続は8ビットパラレルとしました。PORTBの下位8ビットをデータ用とし、上位ビットでコントロールします。パラレル接続のため接続本数は多いですが、部品点数は非常に少ないシンプルな構成でできました。音声出力は安直に圧電ブザーを使いましたが、アンプを通して小型スピーカーを付けるのもよいと思います。
 電源は液晶バックライト用に5V、その他は3.3Vとしています。この液晶モジュールは本来2.8V用ですが、3.3Vでも問題なく動作するようです。

 プログラムについては、VRAM構造などはビデオ出力版そのままとし、いったんマイコン上のVRAMに全て描画してから、全画面分を一気に液晶に転送しています。こうすることで、従来のビデオ出力部分を液晶出力にプログラムを書き換えるだけで、大部分はそのままで動作させられます。低価格の液晶でどこまで転送スピードが出せるのか不安がありましたが、ビデオ出力同様にインラインアセンブラを使うことで、ビデオ出力版と同じ毎秒60フレームの書き換えができることが分かりました。ソフトウェアでのビデオ信号(NTSC)の生成と違い、液晶への出力は特にタイミングを要求されないので、1ラインの出力は普通に1ドット出力を256回ループさせています。

ソースプログラムおよびHEXファイルのダウンロード

 ビデオ出力の代わりに小型液晶搭載としたことで、携帯型のゲームを作成することも可能となりました。電源を電池やスマートフォン用のモバイルバッテリ等にし、オリジナルのプリント基板を作って、外に持ち歩いて遊んでみてはどうでしょうか?

LCD版VELUDDA

実験風景
(別実験の基板を流用したので関係ない部品が多数写っています)

液晶版VELUDDA回路図
回路図 (クリックで拡大)


TFT1N3204-Eキャリー基板ピン配置
TFT1N3204-Eキャリー基板ピン配置 (クリックで拡大)





Raspberry Pi Pico+小型液晶版

2023.7.8 追加

 Raspberry Pi Picoに小型液晶を接続したバージョンも製作しました。

Raspberry Pi Pico版VELUDDA

 使用した液晶はコントローラにILI9341を搭載し、SPIで接続するタイプのものです。SDカードスロットを搭載し、液晶下側に14ピン、上側にSDカード用4ピンのインターフェイスを搭載したものが一般的で、2.4型や2.8型、3.2型など種類が豊富で、入手も容易なので最近はよく利用されているようです。
 回路図は右図のようになります。電源はRaspberry Pi PicoのUSBコネクタから+5Vを供給するか、VSYS端子(39ピン)に+1.8V〜+5.5Vを供給します。液晶用電源は3V3OUT端子(36番ピン)から供給可能です。
 また、BASICマイコンMachiKania type Pと互換性がありますので、MachiKania type Pでもそのまま走らせることができます。
 液晶は横置きで14ピン側を右側となるように配置しますが、回路図にあるSDカード用の配線を行い、SDカード内に「MACHIKAP.INI」というテキストファイルを作成し、「LCD180TURN」と記載した行を作成することで、ゲーム機同時に読み込みを行い14ピン側を左側にすることも可能です。(MachiKania type P用設定ファイルがそのまま利用可能。)

【注意】
 今回使用した液晶はSPI接続のため、パラレル接続に比べ転送速度が劣ります。ILI9341は規格上はSPIクロック10MHzまでと規定されていますが、実際にははるかに高速転送が可能なようです。またRaspberry Pi Picoも通常、システムクロック125MHzで動作しており、RP2040チップは最大133MHzとされていますが、オーバークロック耐性が非常に高いと言われています。
 今回はプログラム設定によりRaspberry Pi Picoを倍速の250MHzで走らせ、液晶用SPIの転送クロックは62.5MHzとしました。これにより、なんとかオリジナルのPIC32MX370F512Hビデオ出力版と同様の毎秒60フレーム描画を実現することができました。
 動作確認はしておりますが、Raspberry Pi Picoや液晶に負担となる可能性がありますことをご認識の上、ご利用ください。

Raspberry Pi Pico版VELUDDA回路図

回路図 (クリックで拡大)


VELUDDA Pico全体
MachiKania type Pを使用


UF2実行ファイルはこちら


 Raspberry Pi PicoのBOOTSELボタンを押しながらUSBケーブルをPCに接続し、veludda_pico.uf2ファイルをRaspberry Pi Picoに書き込んでください。また、veludda.hexファイルはMachiKania type PのSDカードにコピーし、ファイル選択画面で選択して実行できます。ソースプログラムはこちらからダウンロードできます。

Copyright (C) KenKen All Rights Reserved.