レトロでハードな物語

レトロなゲーム機・マイコン・中古デバイスなどをArduinoやAVRで再活用する方法を模索しています。

Arduinoでスタートレックゲーム

2018年09月07日 | 自作ゲーム

1970年代、TK-80BSというワンボード・マイコンではTiny BASICで書かれたスタートレックゲームを動作させるのが流行っていたとのこと。現在、それよりはるかに高性能なマイコンのArduinoでスタートレックゲームが動かせないはずがありません。

そこで、軽い気持ちでTiny BASICで書かれたスタートレックゲームの移植を始めました。色々なバージョンがあるようですが、元となるソースはこちらから入手しました。
TinyなBASICならCへの移植は簡単だろうと思ったのが大間違い。構造化プログラミングとは程遠いBASICプログラムの流れを追うのは結構大変です。でも、もっと大変なのはArduinoのSRAMが2Kしかないことです。

Arduinoでゲームをするには何らかの入出力装置を接続しなければなりませんが、今回は簡単に済ませるためシリアル入出力を利用することにしました。これが問題で、フラッシュメモリに書き込まれているはずの文字列が実行時にSRAMにコピーされメモリを食いつぶしてしまうのです。
最終的に出来上がったスケッチをコンパイルすると、SRAMの空き容量が200バイトほどになってしまい警告が表示されました。ここでスケッチを手直しすればよかったのですが、ボードに書き込んだところ先日投稿したようにArduino Pro Microのブートローダーを壊してしまいました。

Pro Micro復旧後、メモリの節約のために変数のサイズを小さくしたり、グローバル変数を減らしたりしてみたのですが思ったほど節約できません。しばらく悩んだ後、メモリ節約について調べてみたところ簡単に使用メモリを減らす方法が見つかりました。
表示したい文字列をF()マクロで囲うと、文字列を表示するときにSRAMにコピーするのではなくフラッシュメモリから読み出して表示してくれるそうです。
もっと早く調べていれば苦労しなくてすんだのに...。という訳でメモリ問題はあっけなく解決。

完成したスケッチはこちらです。

startrek.ino

メモリ節約やBASIC寄りの記述でわかりにくいプログラムになってしまいましたので、まだバグがあるかもしれません。
遊び方はBASICソースを入手したサイトにあるSTARTREK_JP.TXTの説明と同じですが、幾つか相違点があります。


ゲームはArduino IDEのシリアルモニタや他のシリアルコンソールアプリから利用できます。キーボードからの入力には改行コードをつける必要があります。Arduino IDEのシリアルモニタではLFやCR、CRLFのどれかを改行コードとして送るようにしてください。スケッチstartrek.inoの先頭に #define EOL '\n' という記述がありますが、ここにシリアルモニタなどで指定した改行コードを定義する必要があります。

LFの場合 #define EOL '\n'
CRの場合 #define EOL '\r'
CRLFの場合 #define EOL '\n'

次の行にある #define ECHO は使用するシリアルコンソールが入力した文字をエコーバックするときにコメントアウトします。Arduino IDEのシリアルモニタではこのままにしておきます。

ゲームはゲーム書き込み済みのArduinoを接続した後に、シリアルモニタを立ち上げリターンキーを押せば(改行コードを送れば)開始します。
Ubuntuの場合だけかもしれませんが、LeonardoやPro Microは一番最初の接続時(Pro Microはリセット後毎回?こちらも参照)にATコマンドらしきものが送られてきているようなので、うまくゲームを開始できないときはボードのリセットかUSBの抜き差しで開始できるようになると思います。

ゲーム開始直後に難易度を聞いてきますので、難しくしたけれは'Y'をそうでなけれは他の文字を入力してください。'Y'のかわりに数字の'1'を使うことが出来ます。ゲームはテンキーのみで遊べるようになっていますので、コマンドも1〜7の数字で入力します。数字の'0'か数字以外の文字を入力するとコマンド一覧が表示されます。

入力出来る数値は整数値のみで、小数点を含む数値やマイナスの値は入力出来ません。数字以外の文字を入力すると'0'とみなします。

ゲーム中、光子魚雷で星を撃ったときの処理がオリジナルのBASICプログラムでは意図したとおりに動いていない(勝手にそう解釈しました。)ようなのでちょっとだけ修正しています。


Arduino IDEのシリアルモニタ以外のシリアルコンソールを使用するときの参考に、UbuntuのGTKTermを使用する際の設定例を以下に示します。

スケッチの#define行を以下のように修正してボードに書き込みます。

#define EOL '\r'
//#define ECHO

GTKTermを起動したらConfigurationメニューのPortを選択しPort:の設定を/dev/ttyACM0にし、Local echoとCRLF autoにチェックをつけます。


Arduino接続後、リターンキーを押せばゲームを開始できます。

Arduino IDEのシリアルモニタには必要ありませんが、それ以外のシリアルコンソールで入力した数値を修正できるように、BSキーで入力された数値を削除できるようにしました。画面上では入力文字は消えませんが、内部の文字列のバッファからは削除されています。

なお、このソフトウェアを使用するに当たって生じた如何なる損害やトラブルに関して、作者は一切の責任を負いませんのでご理解の程よろしくお願いします。


今回ゲームの移植とデバッグに、AUTODESKのTinkercad電子回路シミュレーターを使用しました。プラウザからオンラインで利用できるのでインストール不要で簡単に使えます。色々な電子部品で回路が組めますが、その中の部品としてArduino UNOが使えます。当然、作成したスケッチもきちんと動作します。
シミュレーターなので、スケッチを書いたらボードに書き込まずにそのまま実行できるのが手軽でいいですね。デバッグモードもあり、ブレークポイントが設定できるので実行しながら変数の内容確認が出来き便利です。

これを利用すればArduinoを所有していなくてもゲームで遊ぶことが出来ます。


シミュレーターについての詳細はまた後で投稿します。



最新の画像もっと見る

コメントを投稿