メガドラ開発:SGDKメモ

大したことではないけど、メモとして残しておきたいことがたまってきたのでまとめておきます。

リソーステーブル

 ゲームを開発する際には様々なリソースを使用します。SGDKではリソースをresフォルダ以下にまとめ、.resファイルにコンバートの仕方を記述していきます。記述方法についてはbin/rescomp.txtを参考にします。ロムのサイズがそれほど大きくない場合は問題ないのですが、大容量ロムとなるとバンク切り替えを行ってリソースを管理する必要があります。その際には、リソースの入ってるバンクがどこに読み込まれるかによってアドレスも変わってきます。簡単な使用方法としては、以下のようにSYS_getFarDataでアドレスを取得します。
u8* pD = SYS_getFarData( (void*)res_font );
上記の例ではres_fontというリソースがあるバンクをシステムが空きアドレスに読み込み、リソースの正しいアドレスがポインタに代入されます。
 ゲーム開発ではリソースをテーブル化することも多いかと思います。ver1.6.5辺りではconst u8* pResTable[] = { res_font };といった書き方でもコンパイルが通りました。ただ、これだとロム内ではなく、メモリに配置されてしまいます。そしてver2.0以降ではコンパイルも通らなくなり、const u8* const pResTable[] = { res_font };といった書き方が必須となりました。これだとロムの中に入るので、メモリを圧迫することもありません。難しいですねconst。

フリーバッファ

 あらかじめフリーバッファとして大き目の配列を作っておいて、用途に応じて構造体にキャストして使うことがあります。その際にはu8配列ではなくu16配列として定義しておかないと、アライメントの関係でアクセス時にエラーが発生します。

VDP_setPlaneSizeについて

この関数は各プレーンが縦横のセル数割り当てを指定します。頻繁に使うことはないと思いますが、最低でも1回は使うことになります。問題は3番目の引数がbool VramSetupとなっていて、これをtrueにするとスプライトアトリビュートテーブルやスクロールデータテーブルなどのアドレスがリセットされるようです。ver2.0で変更されたようですが(ver1.8辺りかも?)、ドキュメントの説明も不十分なためハマる可能性大なのでメモを残しておきます。

HBlank割り込み用コールバック関数について

これもたぶんver2.0以降の変更だと思いますが、HBlank割り込み用のコールバック関数はHINTERRUPT_CALLBACK func()といった感じで定義しないとダメらしいです。以前はvoidでも問題ありませんでした。

定数名、関数名は変わる。たぶん今後も変わる

 よく変わります。しばらく同じ意味の定数が共存して、突然なくなるので驚きます。なので、置換するのが面倒なら関数名含めてマクロでラッピングしておいた方が良さそうです。

最適化について

 以降はまだ検証が不十分ですが、何度か検証してみて疑惑が残ってる最適化のヒントです。100%信じず自分でも検証していただきたいと考えます。
 まず、シンプルにs8、u8は遅い印象を受けます。容量的に問題なければs16、u16を使用した方が良さそうです。
 ポインタのポインタは頻度を抑えた方が良さそうです。使用頻度が多くなるようであれば、ポインタに入れ直しましょう。
 構造体内の配列へのアクセスはとても重いです。ポインタにアドレスを入れてアクセスした方が良いです。特にfor文で連続アクセスしている場合はポインタに入れておくと劇的に速くなるはずです。
 スプライトアトリビュートテーブルはu16配列(要素数80*4)にするよりも、素直にスプライト構造体(中身はu16が4つ)を80個作った方が高速でした。やり方の問題もあり得るので、ご自身でも試してみてください。推測ですが構造体のサイズが2のべき乗なので最適化が効いてそうな気がします。

この記事が気に入ったらサポートをしてみませんか?