回路図 |
説明 | 通常 | オーバークロック |
---|---|---|
VGA・サウンド・パッド・パッドIDの結線確認用アプリ(test_libvga.uf2) オーバークロック時、テキストとスプライトの重ね合わせやシャドーを1行を使用可能。 |
||
タイル面・スプライト面・テキスト面を使用したテストアプリ0( test_game0.uf2) オーバークロック時は、タイル面を2面使用した星多重スクロールやボスちらつき軽減、スコアなどのテキスト面とスプライトの重ね合わせ、スプライト数増加などのチラつきなど通常と見た目がだいぶ変わる。 |
||
テキスト面を使用したテストアプリ1( test_game1.uf2) | ||
ビットマップ面を使用したテストアプリ2( test_game2.uf2) |
|
|
タイル面・スプライト面・テキスト面を使用したテストアプリ3 |
画像作るの面倒になって放置していた、テストアプリ3の動画を貼り付けました。
非オーバークロック時の動画を60fpsに更新しました。
3D表示の勉強とポリゴン表示の確認のため、テストアプリ2を更新しました。
CPU負荷は思った以上に軽いので、現在計算の精度を荒くしているが、精度を上げる+その他処理をしっかり入れても余裕で動作しそう。
個人的にですが、このマイコン非常に使い勝手が良いと思います。
オーバークロックに対応したアプリの動画を追加。
test_game1にSCC音源で作成したBGMを追加。
古いコンパイラでないとVGAのライブラリが動作しない問題があるため、VGA箇所をライブラリにしていましたが、問題が発生する箇所をインラインアセンブラにしました。
本当は関数全体をインラインアセンブラにすることでまだ処理速度を上げることは可能ですが、管理が面倒になるので必要最小限の変更にしましたが、十分速度は出ていると思います。
コンパイラの問題が回避できたため、以前driverとしていたソースををlibvgaに分けました。
ビルドするには、アプリのソースとは別にlibvgaが必要になります。
libvgaとlibvgaを使用するように変更したソースはDownloadにあります。
各機能の動作確認用のアプリを作成しました(結線の確認用)。
VGA出力用に画像、サウンド用に以前作成したSN76489、SCC、VRC6を順に作成、パッドのID(ディップスイッチ)とパッド状態表示を行います(パッドの確認は、GP0のUARTからも出力しているため、VGAの回路がなくても確認できます)。
また、VGA表示中での最も処理負荷の高い以下の表示を行った時に、処理が間に合わないことが分かりました。
・タイル面(水平垂直反転あり+透過色なし+8の倍数以外への水平スクロール)
・スプライト面(水平垂直反転あり+透過色なし+水平垂直オフセットあり+64個中最後の16個が同じラインに並ぶ)
処理高速化のために色々と試していましたが、全てをアセンブラを使用しないと厳しいかと思いましたが、仕様書を見ているとインターポーレーターと言う面白そうな機能がありました。
この機能は今回の描画に使用できそうだったので試した所、処理速度が上がることより、使用するレジスタ数を極端に減らすことができるため、Cコンパイラの最適化に相性が良いです(もちろん処理速度も速いですが)。
しかも、CPUのコアごとに2つx2レーン持っているため、Cortex-m0にとって非常にうれしい機能で、今回使用した機能以外に飽和演算やブレンド機能にも使用できるみたいです。
ただ、この機能に頼り切ると、ソースを後から見た時に意味が分からなくなるという欠点はあります。
また、今回高速化ができたので、以下の機能を追加しました。
・8bitビット面の解像度256x240
・タイル面にシャドービットを追加
あと、FM TOWNSでDOOMが動いたという記事を見かけ調べると、DOOMは様々なプラットフォームへ移植などされているようです。
DOOMがオープンソースと言うことは知っていましたが、FM TOWNSと言う非常に思い入れのあるキーワードが出てきたため、RaspberryPi Picoでも動作するか確認したくなりました。
簡単に調べてみると、CPU速度はたぶん問題なし、WADファイル?の置き場所は外部にSDカードを取り付ければ問題なし(XInputComかWiiのClassic/SFCミニのコントローラの空きポートへ繋げることが可能)、また読み取り専用のFATなら簡単に作成できるので大丈夫だが、問題はRAMが足りるかだけだけどどうなんだろう?
※軽くソースを覗いたらヒープ用にRAMを6MByte確保していたため、ソースの変更をせずに動作させるのは無理なので、とりあえず今回は諦めました。
4bitのビットマップ面をサポートし、タイル、スプライト、テキストのパターンデータフォーマットをビッグエンディアンからリトルエンディアンへ変更しました。
試しに以前作成した8bitのビットマップ用ポリゴン表示を、4bitでも動作するように修正しました。
4bitでは色数が少なすぎるため、4bitビットマップ時のみ2色のメッシュをサポートし色数が増えたように見えるようにしましたが、ビットのローテート1回増える代わりに塗り潰しの面積が減るため速度が速くなると思っていましたが、逆に速度低下。
どうもポリゴンの塗り潰しに使用しているDMAは余裕があるようで、8bitから4bitにデータ量が半分になりましたが転送完了の待ち時間は変わらず、DMA中に行っている処理の方がDMA完了より遅いらしい。
勘違いしていたのが、2色のメッシュが交互になるよう塗り潰しデータを行ごとに4bitローテートしていますが、Cortex-m0+のローテートに即値が使用できなかったこと(使用できると勝手に思っていた)。
Cortex-m0+はシフト演算は即値が使用できるので他にレジスタが必要になりませんが、ローテートには即値が使用できず他レジスタが必要となるため、使用できるレジスタ数が減り最適化に影響が出ています(表示ポリゴン数が1-2枚程度減る)。
試しにローテートを外すと、4bitと8bitに速度の差は出ませんでした。
そのため、4bitを使用すると処理が軽くなるのではなく、あくまでもRAM使用量が半分になるです。
ただ、RAMの使用量が減るため、前面にスプライト面やテキスト面を重ねて使用できるパターンデータを増やすこともできます。
今回ポリゴンの塗り潰しを少し変更したため、sin/cos * 128で作成した三角形を、以前は50枚程度でしたが、今回の修正で53-55枚程度を1/60で表示できます。
以前作成したソースのパターンデータ変更と、ポリゴン4bit対応したものはDownloadへ置きました。
ビットマップ面を使用したポリゴン表示のアプリを作成し、ソースコードと実行バイナリをDownloadへ置きました、
今回は256色のビットマップ面を使用し、ポリゴン表示を試してみました。
現在は、1/60秒で表示できるポリゴン数は、200x200程度の三角形で40枚程度、動画で表示している絵なら3.5個表示できます。
座標系はOpenGLに合わせているつもり(今の所、透視変換は行わす回転行列による回転のみだが、Coretex-M0+は乗算が早いので使いやすいかも)。
DMAの割り込みをうまく使用すれば、ポリゴン描画をまだまだ早くできると思いますが、DMAの割り込みで処理を行いすぎると音楽に影響がでるため(現在音楽に使用する割り込みは50us周期)とりあえずここまで
(左右のクリップ処理を入れ忘れていたため、-32768 - 32768の横に長いポリゴンを描画するとすご~く処理が重くなると思います)。
また、ポリゴンの表示はメモリ使用量が増えてしまうため、本格的に使用しようとすると表示用のダブルバッファ(153600 = 320x240x2)は少し厳しいかも。
解像度を320x240から320x200へ高さを減らしたり伸ばしたり(HSyncで)など減らす方法はありますが、色数を256色から16色へ落とし、メッシュによる塗り潰しをサポートすれば容量が半分になるので、これならメガドライブのバーチャレーシング位のものを作れるかも(もちろん私には無理ですが処理能力的に)。
動画ではポリゴン表示にチラついている箇所がありますが、Zソートで描画を行っている都合、モデリングデータをきちんと分割する必要がありますが、手打ちなので修正するのが面倒なため諦めました。
テストでPC-8801のシルフィードのようなものを作ろうと思いましたが、データ作成が面倒なので他にするかも
(しかし、以前から思っていましたが、PC-8801のシルフィードってポリゴンに見える画像を2D処理しているように見えるのだが・・・)。
テキスト面のみを使用したテストアプリを作成し、ソースコードと実行バイナリをDownloadへ置きました、
前回はスプライト面+タイル面+一部テキスト面で作成していましたが、今回はあえてテキスト面のみで作成してみました(当たり判定などゲームに必要な処理は入れていません、表示のみです)。
テキスト面+固定フォントのみで作成しているため、人によっては懐かしいと思えると思います。
ただし、1/60秒で動作しているため、動きは綺麗に見えると思います(試して思ったのが反射レーザーがスムーズ)。
今回試して思いましたが、昔のパソコンはテキスト色に制限があることや、RAMが少ないなど色々と制限はありますが、頑張れば綺麗に動かせたかもしれないです。
本当は巨大戦艦を動かそうとしましたが、好きなステージとボスの動きに興味があったので試してみました。
テキストのみで作成すると絵を作成するのが面倒ですが、この手のアプリは作っていると楽しいので、今後1面から作るかもしれません。
ただ、残りビットマップ面のテスト作成がまだなので、とりあえず次はポリゴンを表示しようと思います。
DMAを複数使用してRAM速度がどの程度耐えられるか次第ですが、結構速度が出るのではと思っています。
いくつかの処理追加とソースコードを整理したものと実行バイナリをDownloadへ置きました、
操作にゲーム機のパッドを使用するようにしていましたが、手持ちのパッドが壊れた時に新しいパッドの入手が厳しくなると思います(変換ケーブルを作成するのに延長ケーブルなども入手しないといけないので余計)。
Raspberry Pi Pico 以外でも何かに使用できるかもしてないので、Windows の XInput 入力を COM ポートから出力するツールを作成しました
(XInputを調べたら1つの関数を呼ぶだけと、Microsoftにしてはシンプルな作りになっていたためで、動作確認はWindows10のみ)。
本当は Raspberry Pi PicoをUSBのホストとして動作させ、USBのパッドを使用できるようにすれば良いが、調べなければならないことが多いため、今回は簡単に対応できる方法にしました。
Windows が必要となりますが、このツールを使用れば、マイコン側はUARTのRXとGNDの2ピンだけでパッドが使用できますし、現状は対応していませんがリアルタイムなキー入力などへ簡単に対応できるようになります。
また、XInputCom 用なら以下の回路図のようにピン数が減るため、ブレッドボードで簡単に動かすことができます。
回路図 |
とりあえずゲームらしきものを作成してみました。
実行ファイルはDownloadにありますが、動作させるのは面倒だと思いますので、以下に動画を置きました。
動画は1/30秒となっていますが、実際は1/60秒で動作、CPU負荷も全くない状態で動作しています
(CPU/ROMはまだまだ余裕)。
音はSCCをエミュレート+適当に作成した3bitのDPCMを使用しています(重いOSが乗っていないので、遅延なく音源をエミュレートできるし、複数の音源の追加もできるので良い)。
ソースは整理した後ここへ置きます。
Raspberry Pi PicoはCPUコアが2つあること、ほぼすべてのピンに機能を割り当てられるためピンの割り当てが容易、細かいサポート機能が搭載されていることやシンプルなサンプルもあるので使いやすいかも(ただ、仕様書を日本語化して欲しい...)。
しかも低電力、まったく発熱なし。