ASKS?::SesameSaltBlog

SesameSaltBlog | Calendar | All Tags

JavaScriptでGBエミュレータもどき

Tags: jsgb
久しぶりに更新!もう5月ですが、あけましておめでとうございます!

Something like GameBoy Emulator
URL: http://yomogimochi.com/jsgb/



いまJavaScriptでゲームボーイのエミュレータもどきを作っている。ハリボテながらも、スプライトなどの画像を表示することができて、こんな感じかーっていうのが掴めてきたところだ。

何だかパッと見では、ちゃんとアニメーションしてるように見えるかもしれないけど、今はまだクロック数をうまい具合に調整することでそれっぽく見せてる偽物の実装。割り込み周りの仕組みをきちんと作り込めば、もっと実機の動作に近づきそうな感じがするんだけど、そこはまだどうやって再現しようか考えてる段階。

さて、何年か前からコンピュータの動きを真似るプログラムについては試行錯誤していた。その始まりは、プログラムカウンタなどレジスタを用意し、メモリのような何かから数値を読み取って、それに対応する動作をさせるというものを作ってみたら、意外と気持ちよく動いたところからだったと思う。

それから幾つか試作品を作ってみたんだけど、どうにも「指定した時間内で指定した回数処理を実行する」っていう部分が作りきれなくて、そこで止めてしばらく置いていた。

最初に思いついた実装は、指定した時間内に何回処理が実行できるかっていうのを数えて平均の実行回数を求めておいて、必要な待ち時間を予測して変化させていくというものだった。処理の間に調整するための待ち時間が入るイメージ。処理目線。でも、このやり方だとプログラムが複雑になりすぎるし、待ち時間の変化が微妙にずれたりして、結果的にはこの部分から設計が捻じれていって、よく分からなくなっていった。

しばらく経って、何かゲームを作っていた時に、単位時間あたりのフレーム数を調整する処理が必要になった。それで、どこかのウェブサイトでその解説を眺めていたら、時間内に何回実行するか分かっていれば1つの処理あたりの時間が分かるということに気が付いた。このおかげで処理にどのくらい時間が掛かったか、というところから待ち時間を求められるようになった。このやり方だと一定間隔で処理を実行させることも出来て良い感じだった。

良い感じだったんだけど、処理と処理の間に待ち時間を挟まないといけない、という思い込みが結構大きな壁になって後で殴りかかってきた。どうもCPUみたいな大量の処理を行う場合に間に合わない。

結局、さらに俯瞰して、画面を更新させるタイミングで時間を区切り、その間に必要な量の処理をまとめてバッと実行させて、時間が余ったら次の更新タイミングまで待たせるという所に落ち着いた。このやり方なら、一定間隔を保ちながら大量に実行できるし、画面上の動作も不自然にならない。

……字にしてみるとさらっとしてるなぁと思うんだけども、実際はそこにたどり着くまでに結構時間が掛かっていた。特に「画面を更新させるタイミングで時間を区切る」という部分。ゲームボーイだと画面を更新する間隔は16ミリ秒。後で知ったけどゲームボーイに限らず色んなところで割とよく使われている一般的な間隔だと思う。でも、そのときは何も知らなかったのでこれでは画面がカクカクするのではないかと勘違いしていた。知らなかったとしても一度実験してしまえば意外と間に合うことに気が付けたんだけど、それをせずに考え込んでしまったのでだいぶ時間を食ってしまった。あと、16ミリ秒では処理の実行回数が間に合わないんじゃないかという心配もあったけど、こっちはそこまで苦労せずに大丈夫なことに気が付いた。

このやり方は、何かPICで7セグメントのディスプレイに数字を表示するときと似てるなぁと思った。高校の授業で初めて7セグを扱ったときは、最初に電気を送り込めば、どの部分を表示するかっていうのを記憶してくれて、そのまま数字を表示できるハイテクなものだと思っていた。

実際はそこまでハイテクな代物じゃなくて、毎度どの部分を表示するかっていうのを指定する必要がある。しかもずっと連続して送り続けると、PICの方が熱でダメになってしまうので(ダメにしてしまった)、適度にウェイトとなる処理を入れないといけない。ウェイトがあるから、スローモーションで見ると7セグは点滅しているはずだけど、すごく短い間隔で変化するから人間の目には自然に見える。これと同じような現象が最後のやり方では起きている。

ざっとこんな感じ。さぁ、次は割り込み周りをしっかりさせるぞ!
コメントを読む | コメントを書く