Tang-Nano FPGAボードで動作するテトリスゲームを実装してみました。SNESコントローラを接続してプレイすることができます。ソースコードは大変散らかっており、至るところにバグが潜んでいると思われますのでご注意ください(?)
Tang-NanoにSNESコントローラと音声出力用のLPFを接続します。
超雑で申し訳ありません。肝心のtetris.vはソースコードを見たほうが早いです。
(よくわからんが、まぁ動いている(稀にテトリミノが壁に刺さるバグあり)からヨシ!)
フィールドサイズは外枠を含めて、横12 x 縦22ブロックとしました。Wikipediaに記載のある図が由来です。
Tetris - Wikipedia https://en.wikipedia.org/wiki/Tetris
ブロックのサイズは、10x10pixelとしました。内部処理では、ブロックに4bitのcodeを割り当てて管理しています。codeとテトリミノの種類、色の対応関係は次のとおりです。 | code(dec) | 割当 | 色 |
---|---|---|---|
0 | 背景 | 黒 | |
1 | 外枠ブロック | 灰 | |
2 | テトリミノ(I) | 水 | |
3 | テトリミノ(O) | 黄 | |
4 | テトリミノ(S) | 緑 | |
5 | テトリミノ(Z) | 赤 | |
6 | テトリミノ(J) | 青 | |
7 | テトリミノ(L) | 橙 | |
8 | テトリミノ(T) | 桃 | |
その他 | 未使用 | - |
ブロックをLCDに描画する際には、ブロックの境界をクッキリさせ、立体感を出すために明暗を付けています。例えばテトリミノ(O)は黄色ですが、実際には以下の図のような配色で描画されています。
tetris.vで定義されています。基準となるXY座標(r_block_pos_x, r_block_pos_y)からのオフセットとして定義しています。LCDのスキャン位置信号(i_pos_x, i_pos_y)とオフセットが一致している場合にブロックが描画されます。
フィールドの情報(外枠や固定されたブロック)はDPRAMに格納しています。データ幅はブロックのコードを格納するために4bit確保しており、深さは12 x 22 = 264必要となります。
以下、ポートの割当です。
ポートA:
ポートB:
BGMとテトリミノ固定時の効果音を再生する機能を実装しました。
BGMは2音(Chあたり1音 x 2ch)同時発音に対応しています。bgm_ROM.vにズラッと並んだデータがSMF(Standard MIDI File)から生成した譜面データです。最大で1024個のイベントを登録可能です。
効果音は、32bitの線形帰還シフトレジスタで生成される信号を出力します。「ザッ、ザッ」というノイズ音です。
BGMと効果音は加算され、最終的に8bit幅のデータとなります。これをΔΣ型のDACに入力し、1bitのPDM変調信号を得ます。外付けのLPFでアナログ信号に再生されます。
Resource | Usage | Utilization |
---|---|---|
Logics | 932/1152 | 80% |
--LUTs,ALUs,ROM16s | 932(806 LUTs, 126 ALUs, 0 ROM16s) | - |
--SSRAMs(RAM16s) | 0 | - |
Registers | 474/945 | 50% |
--logic Registers | 460/864 | 53% |
--I/O Registers | 14/81 | 17% |
BSRAMs | 4/4 | 100% |