(裏)ゲームセンター荒らしforMSX2開発記
ゲームレジェンド30で展示した1chipMSXのミニゲーム作成の顛末ですMSXのプログラムをまともに組むものは初めて、
開発環境も厳しい、
MSXはとにかくスピードが遅い、
果たして無事完成するのだろうか
純粋なz88dkは第三章から
リリース後の高速化は第四章の予定です
お好きな表題を(クリックorタップ)して中身を読んでみてください
一章 思い立ち〜準備
ゲームレジェンドでは展示のみの参加もOK、それならいろいろ見せびらかしたい
三月ごろに新刊が完成。次の作業は…スペースを目立たせたいと考えたて
卓上ゲーム機は押し入れから引っ張り出して確認して完了
タブレットは、趣味のwebページのありもの素材をつなげて完成
ゲーム機は、当初はMSXに手持ちのゲームROMと緩く考えてしましたのですが
三月ごろに早々と本も完成して余裕があり
さらに家の者が「もう一冊本を作ろう」とけしかけてきたのです
が、「ネタもないし新刊のネタでゲームを作る」と言い放つことになりました
(プログラムは本業だしね)
「電源無し」なので、小型でバッテリーで動きそうなマシン
ゲームレジェンドはイベントの申し込み時に電源の使用の有り無し、を申請しますここで電源無しを選んでいたため、会場で電源コンセントの使用は期待できません
バッテリーで動きそうな手持ちのゲーム機から選択したのが1chipMSX
過去のゲーム機に比べれば最近に作られたものですしきっと消費電力も少ないでしょう
当時購入して、ほとんど使わずにお蔵入りしていた機器の出番です
1chipMSXには5VのACDCアダプターが付属しています。
これの代わりにスマホバッテリーに接続できるケーブルを作成します
早速秋葉原にいって同型のプラグのパーツを秋葉原で買ってきます。
(USBの方の端子は使っていないケーブル等を切断して安く済ますつもり)
自宅に戻ってUSBのケーブルをあさっていると……
なんとUSB卓上扇風機の電源ケーブルが作ろうとしているケーブルと同じです。
USBの電源に接続するとそのまま動作してしまいました。…プラグは買わなくても良かった。
ジャンクで買って放置していたUSB電源のモニター
1chipMSXだけではモニターディスプレイがありません。こちらはちょっと当てがありました。
以前に秋葉原で購入していたOn-Lap 1303Hのジャンク品
USBの電源で動作するフルHD解像度のLCDモニタです。
HDMI入力コネクタの接触が悪いのです、自分で直そうとしていたのですが、うまくいかず
修理を放り出してmicroHDMIのコネクタを引きはがしたまま放置していた物件がありました。
これのアナログRGB入力が使えるのではないかと思い調べてみます
アマゾンで対応アナログRGBケーブルを発注して、無事動作を確認。モニタを組み立てなおします。
残念ながらアスペクト比の変更ができないのですがそこは我慢します。
これでモニタも用意できました。
甘い目論見
さて本体とモニタが用意できたので、展示の中身です。画面を見て目を引いてくれればいい程度に思っていました
印刷所から本が届くと、家の者が「まだ時間があるからもう一冊作らないの?」と
(おたく同人作家はこういう思考をするのか)
そんなにネタはありません、それに俺プログラマーだし、やるならプログラムでしょ
MSXはスプライトマシン。少ないキャラならBASICでも簡単なゲームが作れるんじゃないかな
と思ってしまったのです。
二章 開発〜準備から
MSXのプログラムは殆ど未経験
MSX2との出会いは学生の頃のFS-A1、安い値段に惹かれてPC-98を持っていたにもかかわらず購入プログラムを組むつもりで
多色スプライトやVDPの転送コマンドにはものすごく期待したものでした。
VDPのコマンドはスプライトと肩を並べるほど速くもなく(当時はVSYNC至上主義者でもあったので)
重ね多色スプライトは使いづらく
それ以上MSX2プログラミングに興味を持つこともなくROMカートリッジでゲームするのみで
それ以上プログラムを組むことはありませんでした
Z80を本でかじっただけで8086に移行してしまった私にMSXのプログラムは組めるのだろうか
やりたい事を実現できそうな仕様を絞り込む
大体のMSX2の仕様はZ80CPU
ハードウエア仕様からの見積もり
ゲームの基本ルール
脳内で想定のゲームをプレイしている想像をしてみます。
的確に追ってくる敵は狭いフィールド敵にすぐに追いつかれそうな気がします。
(昔のBASICの投稿ゲームではよくある光景です)
フィールドを迷路のように複雑にするべきだろうか、敵の行動にルールを設けるべきだろうか
などともうすこし詰める必要がありそうです。
blue MSX
さすがに実機での開発は御免こうむりたいです(慣れたエディタを使いたいね)。MSXのエミュレータで開発できればと思いますgoogle検索でMSXのエミュレータを検索します。blue MSXというのがなかなかよさそうです
FDイメージのマウントのほかに、WindowsのフォルダをMSXのFDDとしてマウントすることが出来るそうです
クロス開発に打って付けです
解説サイトを見ながら設定すると。無事おなじみのMSX-BASICの画面が出てきました
早速簡単なプログラムを動かしてみたのですが、右側のSHITキーやCtrlキーが使えません。
記号の入力の時などうっかり右のSHIFTキーを押してしまいます。注意が必要です
スプライトエディタSST
ゲームプログラムの要、画面を出力するところから始めますまずはMSX2の二面重ね3色スプライトのデータを作成します
Windows上で動作するスプライトエディタが無いかといろいろ調べたのですがちょっと見つかりませんでした
MSX2上で動作するSSTというスプライトエディタがありました
このツールはBASICで出来ているそうです。こちらを使わせて頂きます。
改造して機能追加したり、プログラムの参考にもさせて頂こうと思います
blueMSX上でSSTを動かしてみます。カーソルキーで編集するようです
マウスで大まかに当たりを取りたいので、マウスでも動作するように改造してみます
すると機能追加の分、速度が遅くなったのでblueMSXでエミュレーションの速度を上げてもたつきを解消します
すると今度は、キー入力が速くなりすぎます
キー入力判定を
マウスでドットを打ち、保存してみます

するとなぜかファイルが保存されていません。
blueMSXでのフォルダのマウント機能では安全のためファイルの書き込みは出来ないようになっているようです
解決するためにAドライブにはデータ保存用のDSKイメージをマウント
BドライブにはアスキーセーブしたSSTのベーシックファイル等をマウントします
これでデータはAドライブに保存されます
DSKイメージからファイルの取り出しはDisk-Managerを使用します
BITMAPデータコンバータ BMP to MSX
ゲームの背景は手抜きをして一枚絵の画像データをファイルから一度に読み込んで完了とします
背景のタイルや筐体等を個別に描画すればデータ容量も少なくスピードも上がりそうです
全画面分の画像データを簡単に作成できる今の時代ならではの手抜きかもしれません
windowsのBMPファイルからMSXで読み込める桁式に変換して減色処理も行ってくれる優れものです
画像を綺麗に見せるにはSCREEN8の256色モードです
しかしこのモードはカラーパレット機能が無く、スプライトも固定16色表示になってしまいます
これではスプライトに好きな色が選べずに制限が出てしまいます
なのでSCREN5のパレット付き16色モードでコンバートします。
ここでも注意が必要です、MSX2のパレットは一組で背景とスプライトで共用しています。
なので(先にスプライトで必要な色を決めている場合)スプライトで使っている色を使って背景データを作らなければなりません
BMP to MSXの設定画面で、すべてのパレットを固定してコンバートします。
(パレットデータはスプライトエディタのパレットデータを開きながら手動で設定していきました)
スプライトが思ったように表示されない
まずスクリーンモードを256×212×16色に切り替えます(SCREEN 5)
キャラも合わせて三体しかいませんし
BASICで読み込んでみる
bloadでコンバートした背景CGを読み込みます。パレットも反映させます
SST付属のサンプルを参考にスプライトを読み込みます
z88dkを導入する。コマンドラインでコンパイル。
MSXで使えるフリーのCコンパイラを探します
MSXで使えるCコンパイラは結構あるようで比較解説しているサイトもあります。
そのなかでz88dkを選びました。
windows上でMSXの実行ファイルを作成できる開発環境です
ANSI Cに対応していることと、インラインアセンブラが使えるところが決め手です
詳しく解説されているサイトを参考に導入します。
最近の開発環境は、統合環境が当たり前ですが、
z88dkは別途用意したテキストエディタでソースを記述して保存
コマンドラインからコンパイルする、という昔ながらの開発です
MS-DOSの頃はMS-C + MIFESで同じように開発していたのを、思い出します。
z88dkを導入する。MSXで実行できるファイルを作る方法
z88dkはコマンドラインからzccとタイプして実行しますが、いくつかのコマンドラインオプションを指定する必要があります。+msx | MSXをターゲットとする指定らしい |
-create-app | アプリケーションを作成する指定らしい |
-subtype=msxdos | MSX-DOS上で動作する指定 |
-startup=2 | 起動時の処理の指定 |
-o<flename> | 出力ファイル名の指定 |
-x<flename> | ライブラリ作成の指定 |
MSX上でMSX-DOSを起動できるようにしておきます
DISKにMSXDOS.SYSとCOMMAND.COMが必要です(1chipMSXにはおまけでついてきます)
エミュレータしかない場合はMSX MAGAZINE永久保存版等から入手できるそうです(現在プレミアがついていますが)
無事実行ファイルが出来たら実行ファイルのあるフォルダをblueMSXのドライブとしてマウントします
ファイルの内容はまうんとの時
コンパイル等でファイルが更新されてもにblueMSXの方では内容は元のままで更新されません。
再度マウント(ディスクトライブに対してディレクトリの挿入)が必要です、注意。
三章 開発〜いろいろ問題発生
まずはサンプルプログラムをコンパイルしてみる
インストールしたz88dkにはexamplesフォルダがありサンプルソースがいくつか用意されています。
その中からmsx用のサンプルをコンパイル実行してみます
なぜかうまくコンパイルできないものもありますが、いくつかのサンプルはコンパイル、実行できました。
これを参考にプログラムを組んでみます
自分でソースを組んでみる
テキストエディタでソースを作成して、コマンドラインでコンパイルします
最近の開発環境はソース編集+コンパイル+デバッグが一つでできる統合環境が当たり前です
なので、コードを書いていても、関数や構造体メンバの候補が出てこないので不安です
(VSでソースを書いてz88dkのコンパイラを呼び出すことは可能かな?)
(そういえば最近はコンパイルなんて言わずに実行ファイルを作成することをビルドって言いますね)
まずは画面モードを切り替えてみます。
動作しています。
z88dkで、コンパイルとリンクを別々に行う方法がよくわかりません
とりあえずライブラリ化して分割することにします
VSYNC待ち出来るのか確認してみる
スプライトマシンとはいえ、画面更新は垂直帰線期間行わないとティアリングが発生してしまいます。ゲームの速度も垂直同期で調整するつもりなので必須です
エミュレーターではどのように動作するのか確認の意味も含めてテストしてみます
垂直帰線信号をポーリングして、タイミングを取ります
まだ画面を描き変える処理を作っていません
そこで音を使ってタイミングをチェックします
インラインアセンブラの練習として I/Oポートの入出力関数を作ってみます
ネットでz88dkで検索するとインラインアセンブラで関数を記述する方法を解説してくださっているサイトが見つかります
これを参考に作ります
関数の引数は先頭から順にスタックに積まれる様です。
1bit音声出力ポートのアクセス関数も作ります(無作法に直接ポートをアクセスしてます)
実行するとなんとなく60Hzのブーという音が聞こえてきます。
正しく動いてるのではと思います
背景画像を読み込んでVRAMに転送する
BASICではBLOAD命令でVRAMに転送することが出来ました。
MSXのVRAMはCPUから直接扱えるメモリでありません。fread関数でVRAMに読み込むことは出来ません
ファイルを一旦メインメモリに読み込んでからVDP経由でVRAMに転送します
VPOKEは使えない?
MSXのサンプルにvpoke関数がありました。BASICのVPOKE命令と同様の働きのようですvpokeを使ってファイルの背景データをVRAMに転送することにします

スクリーンの中ほどから内容が書き換わっていますが、どう見ても背景データではありません
スクリーンモードが切り替わっていないのかとも思いますが、そうでもないようです
なにが悪いのか全く分かりません。
msx.hを見るとmsx_vpoke, msx_vpoke_calleeとちょっと違う関数の定義があります、こちらに変えて実行してみます
やはり結果は同じで、画像ば出てきません。中身の処理は同じようです
…と、msx.hを調べていると、msx_vwriteなる関数の定義があります。連続したメモリをVRAMに転送する関数のようです
こちらを使用してみると

あっさりファイルの中身が出てきました(パレットを反映していないので色合いが異なっています)
推測ですがz88dkのMSXサポートはMSX1に対応しているとのことです
vpoke関数もMSX1の場合しかうまく動作しないのかもしれません(MSX2未対応のBIOSを使っているとか)
スプライトエディタ
SSTはスプライトの同時エディット数が15個です(実際のスプライト面から来る制限がある様です)もう少し定義する必要があるので、ほかのスプライトエディタを探しました
SEPTというMSX-DOS上で動作するエディタが見つかりました。こちらを使わせていただくことにします
こちらはマウス主体のエディタです。キーボードでの操作はカーソルキーでマウスカソールを移動させるタイプです

スプライトの表示は更新するデータが少なくて済む…はず
一般にスプライトというのは、一度表示パターンを定義すれば
あとは表示位置情報の更新のみで画面を高速に動き回る
というイメージを持っていました
MSXの場合X,Y座標にそれぞれ1バイト, 定義パターン指定に1バイト、未使用1パイト
4バイトの更新でスプライトを制御できるはず…と思っていました。
意外と多い書き換え情報
今回はキャラサイズを16×32ドットのパターンとして二面重ねの多色スプライトなので 2×2の4面のスプライトを使います
なので表示位置情報は16バイト
最大画面上には3キャラ+1アイテムで56バイトの転送。
まぁこんなものでしょうか
アトリビュートテーブルから派生したカラーテーブル(ジェネレーターの拡張ではない)
MSX2のスプライト(V-9938)は大きく三つのVRAM領域を使用しています
カラーテーブルはMSX1の
大雑把には今までスプライト一面単位だった指定部分をスプライトの水平1ラインことにできるように細分化したものです
スプライトがちょっと画面の左に隠れるたびにカラーテーブルを16バイト書き換え無ければなりません。
今回は 1キャラ4スプライトですが64バイトにもなります
例えば移動、攻撃等で表示パターンが変更になります。パターン定義のNo.を変えます。(これは1バイト)
この時に凝った色使いをしているとラインごとの色指定が変わります
※今作だとプレイヤーキャラが振り向いたり、椅子に座ったりすると色使いが変わっています
すると
さらに表示順が入れ替わる場合もカラーテーブルの更新が必要になります
今回の画面は斜め見下ろしです。画面上側が遠く、画面下側が近くなります。
遠くのキャラは近くのキャラに隠れるように表示しなければいません。
キャラの前後の位置関係が変わるたびに表示するスプライト面も変更になります
そしてカラーテーブルも書き換えることになるのです
せめてパレットテーブル的にカラーテーブルのテーブルNo.を指定する仕様にしてくれればよかったのに……
ゲーム内容を進めて行きます
裏ページを使ってパタパタアニメ―ョン
画面がさみしいのでフィールド上のテーブル筐体の画面にゲーム画面を描こうと思いますせっかくなのでMSX2の自動ページ切り替え機能で2コマのアニメーションをさせようと思います
VRAM128Kの場合SCREEN5は4枚のページを持てます
ゲーム起動時に0,1ページに二枚のフィールドの画像を読み込むようにします
なぜか自動ページ切り替えができない
VDPのレジスタに設定することで偶数奇数ページを自動で切り替える機能があります
なぜかページが切り替わりません。まさかblueMSXは堂々切り替えに対応していないのでしょうか?
時間もないので、プログラムから手動で切り替えることにします。
VDPレジスタの設定で行いますが、こちらは問題なく切り替わりました
次のページも使う
「すべてのテーブル筐体にクレジットを入れる」がゲームの目的ですすでにクレジットを入れた筐体の区別がわかりやすいようにします
クレジットが入った、専用の画面を表示することにします
アクションでクレジットが入ると、画面が変わってプレイヤーに判るようにします
クレジットが入った筐体の画像を作成して、未使用のVRAMの画面ページに読み込みます。これを筐体の位置に転送し書き換えます
VDPのVRAM間転送コマンド
クレジットが入った画面は個別の筐体毎なのでページ切り替えでは不可能です
VDPの転送コマンドを使用します、CPUと並列で動作するので高速化できます
テクニカルハンドブックのアセンブラのサンプルを参考にインラインアランブラで記述してみます
コンパイルすると、インラインアランブラの途中でエラーが発生します
一見誤りが無いように見えるのですが、なぜかエラーが発生するのです
何が悪いのか全く分からないので(開発環境が悪いんじゃないの?)
仕様がないのでインラインアセンブラはあきらめてoutp関数で記述します
全部のページを使ってしまおう
あとページが一枚残っています。このページにタイトル画面を読み込んで切り替えて使うことにしますクレジット画面の空きに筐体画面を賦存しておきます(一面クリア後にゲーム画面を復帰させるため)
簡易デバッグにも便利
ミニゲームとはいえスコア表示は付けたいです。画面が引き締まる効果もあります
当初は背景画面に書き込もうかと考えていたのですが、
背景との重ね合わせ処理やキャラの奥に隠れる等、懸念点もあります
そこで
現在、一キャラにつき4面、最大3キャラ + アイテムで2面、合計14面使用しています。
MSXのスプライト面は32面なので18面の余裕があります。定義にも余裕があります
スプライトモード2は最大8面のスプライトを水平に並べられます。
拡大モードのスプライトなら画面の横幅一杯に並べることが可能です
8×8ドットの文字を想定しているのでスプライト 一定義に四文字含まれます
一文字単位で自由に表示するために定義を直接書き換えることにします
プログラム内にフォントデータを持ってCPUからVRAMに1文字単位で転送して表示します
転送処理の負荷が気になりますが、毎回更新しなければ大丈夫でしょう、と軽い気持ち
最初に左上にスプライトを3面並べて、表示したい文字をジェネレーターテーブルに転送します
無事スコア表示が組み込まれました。

スプライトは正方形の16×16ドットのパターンです、8×8ドットの文字だと縦横2文字の配置です
ちなみにライン毎のずらし指定bitで上8ラインと下8ラインを32ドットずらすようにしてみました
8文字限界まで文字を表示すればよかった…
構造体の処理にバグがある?
さて自キャラ、敵キャラの動きを作ります。
また、コーディングも処理速度が速くなるようにしたつもり
こんな感じで組んでいると、思ったように動きません
調べていくと、おかしい原因が絞れてきました
構造体のメンバの値を構造体の別のメンバに代入している式があります
この結果が、期待した値になっていないようなのです

コンパイラにバグがあるのでしょうか
仕様がないので変数を介して値を代入することにします
時間もないので対処療法で先に進みます
作曲しよう
この時点で当日まで一週間を切っていました
曲作成一日、サウンドドライバ一日の目安で作業します
私は鼻歌でオリジナルのメロディが思いつく程度の素人なので簡単にはいきません
此処は奥の手「歌詞を作ってそれでメロディ作る」を実行します
作詞:さらだかきもちゲームの主人公のテーマです:-) なんか適当ですが、これでメロディが浮かんでくればしめたものです
俺はゲームに金は(金は)払わねぇ
払う金などありゃしねぇ
だけどゲームが俺のゆりかご
地獄の底まで添い遂げる
……なんかガチャガチャした曲になりました、時間もないのでこれを使います
PSGのハードウエアエンベロープで音階出力にチャレンジ
MSXのPSGでぜひやってみたいことがありました。AY-3-8910は音量のハードウエアエンベロープを一つ持っています。時間とともに音量を変化させる機能です
エンベロープの時間の指定は16bitで範囲が結構広いのです
繰り返すタイプのエンベロープを可聴周波数で発生させることが出来ます
※PSGのミキサーでチャンネルのトーンとノイズをOFFにすると純粋な波形が出力されます
ドライバの仕様として
BYTEのポインタの示す値でswitchで分岐して"V"なら次の音量値を取得して更新、"CDE"なら現在のオクターブと長さでドレミを演奏、という感じのエンジンを作成します
これを3チャンネル分繰り返して三重和音の再生です
音階に対応するのPSG用のデータ等はネットで検索して用意しておきます
三角波、ノコギリ波、鳴りました。通常の音階データを与えると数オクターブ低い音階でなっているようです
なので高いオクターブは厳しくなります
とりあえず鳴らすことは達成しました :-)
波形を確認してみる
blueMSXのアナログ出力の波形を見てみる
オシロスコープを使って波形を確認してみます
左から、通常の矩形波,三角波,鋸波
一応それっぽい波形になっているようです
PSGの音量出力が対数になっていることもあってか波形も曲線を描いて、本来の三角波、鋸はとは少し異なります
ちなみに1chipMSXの出力はこんな感じです
櫛の歯の様な波形が出ています(耳で聞く分には違いは感じられないんですけどね)
1chipMAXはPWMでオーディオ出力を生成しているとどこかで見た記憶があります
高周波成分がある為かオシロスコープもなかなか波形を読み取ってくれませんでした
サウンド再生は処理落ちに敏感
実際にゲーム中に鳴らすと、頻繁に処理落ちが発生して、テンポがつまづきます。
たまの処理落ちも耳で感じ取れてしまいます、これは良くない
とりあえずゲーム中はリズムトラックのみ鳴らすことにします
8bitCPUのZ80は遅い、ということで細かく高速化してきました
一番、高速化の実感がわいたのが
構造体を辞めてバラの変数とする
するとなんと、敵キャラ2体動作時でも処理落ちが無くなりました
と書かれていていまいち実感がわきませんでした
今思えば8086でのBPによるスタック上の引数や自動変数のアクセスの利便性や、1命令でのbyte→wordの符号拡張
Z80の機械語にやらせたらどれだけコストが掛かるのか、出力コードは怖く未だ見ていません:-)
あれ、敵一体でも遅い
もう時間もないので30fpsを基準に調整しなおすかと考えます・・・
ぎりぎりまで細かく調査してみると、数回アクションする頃に処理落ちが始まる事を発見します
しかも敵が一体でも
原因はchar型の変数
原因は、スコア用のスプライト定義の転送ルーチンが毎フレーム呼ばれてしまうことでした直線のスコアと今回のスコアを比較して異なっている場合に書き換えるという処理
でしたが、直前のスコアの変数がchar型だったためスコアがある程度増えると、毎回書き換えることになっていたのでした
高速化の足しになればと、変数をintからcharに書き換えてしまったのが原因です
前日、ようやくリリース
なんとか間に合いました四章 高速化と今後
たくさんの人たちにプレイして頂けました
「これ普通のMSXでも動作するのですか?」と質問を受け
はたと気が付きました『1chipMSXの高速化スイッチをONにしたままだった』と
案の定、うちに帰って通常のスピードでプレイしてみると結構処理落ちします
これはなんとかしなければ
これを高速化することにします
カラーテーブルのVRAM間転送
現在は、1キャラに大してスプライト4面、カーテーブルCPUから64バイト程の転送です余っているVRAMにカラーテーブルを置いてVDPコマンドで転送すると速い
とネットの記事にありました。これをやってみます
スプライト定義64個分のカラーテーブルの定義をVRAMの空き領域に転送します
VRAM領域を眺めると0x7000からが空いているのでここに配置します
そしてもう一つ用意が必要です
X座標がマイナスになった時には、ずらしビット(0x80)をONにする必要があります
そこで中身が同じでずらしビットをONにしただけのカラーテーブルを用意して、別の空き領域に配置します
スプライト面がX座マイナスがどうかで、転送するカラーテーブルを切り替えるようにします
これだけのためにちょっともったいない気もしますが、高速化のためには必要です
幸いVRAMも余っていますし
VRAMを大きな一枚の画面とみなしてX,Yの座標で指定するのです
そういえば、VDPコマンドの説明に、ビットマップ画面以外のモードでもコマンドが使用できるように思わせる指定があります
これってMSX1のPCGな画面モード時に画面転送コマンドが使用できるという事なのでしょうかね。スクロールとか早くなるかも。ちょっと興味があります
スプライト面のプライオリティ入れ替え時や等の引っ掛かりも気にならなくなりました
ですが、主人公のアクション時にまだ引っ掛かります。
どうやらスコア表示のパターン転送(CPU→VRAM)が足を引っ張っているようです
6桁の数値のパターンを一度に転送していたのがよくないようです
これを1フレームに1桁ごと転送をばらしてみます
スコア表示を凝視していると、文字の書き換わりが波打つのが見えますが、さほど問題ないでしょう
(書き換え中にスクリーンショットを撮るとちょっとおかしなスコア表示になりますが…)
(一度パターンをクリアするとか、書き換え中はスコアを非表示するとか対策が考えられます)
SEが鳴っているときに処理落ちしやすいようです
サウンドルーチンの高速化、MMLをコンバート済みにする等を考えましたが、 その前に一つ試してみたいことを思いつきました
オート変数をスタティック変数に変更してみる
読んで字のごとく、あらかじめ決まったアドレスに変数が確保されます対して、関数内に普通にに変数を宣言するとオート変数になります
オート変数はスタック領域に動的に確保されます
変数へのアクセスはSPからの相対アドレスになってしまいアドレスの計算利用が増えてしまいます
(あらためて8086のBPやSPの相対アドレシングやRET命令でのスタックの解放は高級言語用と納得します)
int count = 0;となっているところを
static int count; count = 0;とするわけです。
このプログラムはマルチスレッドも割り込みも使用していません
なので関数が二重に呼び出されることもありません。特に気にすることはありません
毎回値が初期化されるように、値の代入を宣言の後に書いておくことくらいでしょうか
目に見えて効果が出た
メインループ内の変数を静的変数にしてみました。するとどうしたことでしょう、フレーム落ちがほぼなくなりました。
予定していたMMLを事前展開は見送ることにしました :-)
アドレス固定の変数……、なんだかハンドアセンブルの機械語のプログラム見たいです。
アーケードゲーム並みの60fpsを目指そうとすると、BASICはおろかCコンパイラ(z88dk)でも厳しいものでした
これ以上処理を複雑にしたい場合は素直にアセンブラで記述する必要がありそうです
VDPの仕様も面倒でした、過去のMSX2のゲームであまり多色スプライトを使用したものがなかったのにもうなずけます
