メガドライブに絵を出そう!さもなくば死!(SGDKのIMAGEを使ってみる)


買いました。ちょっと前に発表になって、発売日に。冬はこれで暮らします。
…そりではですね(チョビヒゲお調子者教師のイメージで)、実際にRescompを使っていきたいと思います。
個人用リファレンスなので、内容に文句言われましても…のスタンスで。SGDKのバージョンは2.00。
前回の記事から、【IMAGE】【PALETTE】【SPRITE】【XGM2】【TILESET】【MAP】【OBJECT】を
いじっていこうと思いますが、初回は【IMAGE】のいじり加減を書き起こしたいと思います。


まずは、下準備。
VScodeの拡張機能からプロジェクトファイルを作ると、
いろいろある中に「res」というフォルダが生成されています。これが素材置き場。
画像、音声、なんでもここです。
入れたら、その中に拡張子「.res」というテキストファイルを作ります。resources.res、res01.resなど。
これは素材リストで、入れた素材の所在と属性を書き込んでおきます。
…次に、プログラム本体(例えばmain.c)に移って、登録素材を呼び出すためのおまじないを書きます。
res01.resというファイルを作ったなら、呼び出したい「.c」ファイルの冒頭に

#include <res01.h>

と書くのがお作法です。「.h」なんか作ってねーじゃん「.res」じゃんと思いがちですが、
コンパイルするときに同名の「.h」ファイルが自動生成されて、それによって読み出されます。そういうものです。


「res」フォルダに「img」フォルダを作って、「sample_color16.png」を置いてみます。
ちなみにこんな画像です。

ちっさいんで、大きさ2倍にしましょう。

そこはかとなく気持ち悪い。顔については説明しません。名前はアッピーです。
ところで…こういう画像はどうやって用意するのか?
ドット絵特化なイラストツールが世の中にたくさんありますが
結局、インデックスカラーという形式…色数を256色以下に指定してpng保存できればなんでもいいので
ぜひスキなソフトをお試しください。何にもわからんくてWindowsでこれからドット絵始めるなら
たぶんAsepriteがいいっす。利用人口が単に多いだけですけど。
そのほかのドット絵ツールレビューはこちらにまとまってます。ワタシにはゴミでもあなたには合うかも!


インデックスで指定する色には諸説ありますが、これは単にブラウン管時代のテクノロジーで
光3原色の加減を8段階に分けて、それを「色」としており、そんな「R255,G192,B064」みたいな
繊細な設定方法じゃなかったわけなので諸説あって当然だと理解してます。じゃどうするかってんで、
https://gendev.spritesmind.net/forum/viewtopic.php?f=22&t=2188
昔はった記事の再掲。画像壊れちゃってますが、モニタの輝度からRGBの値を測定した方がいて(笑)、
各色「0,52,87,116,144,172,206,255」の8段階だったぞ!って書いてあるので、
ウチは絵描くとき、それにならってます。この値を採用しているところ、結構見かけるし。
でもSGDKやエミュレータがどう判定して出力しているかは別の話。エムツーさんの移植ソフトから
スクリーンショットとっても、この値になってない。
けど、だから何?っていう。元々アナログだし、テレビ側の設定でかなり変わっちゃうよね。


【IMAGE】
ここからは「.res」の書き方例と、「.c」での呼び出し方例をあわせて。レッツ画像表示!
素材登録の書き方はこんなカンジです。

//res01.res
  //「IMAGE」「名前(structure)」「”ファイルパス”」
  //      (compression/圧縮)(map_opt/Tilemap最適化)(map_base/ベースtilemap値)で完成。
IMAGE img00 "img/sample_color16.png" -1

カッコの中はオプションなので、未指定でも通ります。
上の記述例では、compressionのオプションだけつけています。
オプションは順番に反映されるので、map_optオプションだけつけるということはできません。

●compressionオプション…
BEST(-1):いい感じ
NONE(0):圧縮無し 無指定だとこれ
APLIB(1):圧縮率高め
FAST(2):圧縮率低め
これは画像圧縮アルゴリズムみたい。変えてみると、結構ファイル容量に変化がありました。
OHSAT GAMESさんのサンプルではFASTが選ばれていましたが、
いろいろ見るに-1指定なので、BESTでいいんかなあ。とりあえず-1にしといて、困ったら変えようかな。

●map_optオプション…
NONE(0):最適化なし
ALL(1):重複、および反転したら同じになるタイルを探して削る 無指定だとこれ
DUPLICATE(2):重複しているタイルを探して削る

map_opt、画像の最適化ということなんですが意味わからんので実力行使に出ます。さっきの画像を使います。

//res01.res
IMAGE img10 "sample_color16.png" -1 0
IMAGE img11 "sample_color16.png" -1 1
IMAGE img12 "sample_color16.png" -1 2
//main.c
#include <genesis.h>
#include <res01.h>
int main()
{
  //背景A(BG_A)に、イメージ(img10~12)を、座標X、座標Yに出力する、という内容。
  //座標は8x8pixelの「セル」で換算します。ちなみに画面の解像度は320*224pixelです。
    VDP_drawImage(BG_A,&img10,0,0);
    VDP_drawImage(BG_A,&img11,0,8);
    VDP_drawImage(BG_A,&img12,0,16);
    while(1)
    {
        SYS_doVBlankProcess();
    }
    return (0);
}

VDP_drawImageというコマンドが、Rescompを通じて素材を出力する特別なコマンドです。
するとメガドライブの画面はこうなります。

画像表示できました!顔は画面外に行きました。3回書いたので、3つ。3つとも同じように表示されています。
で、画像を一時的にためておく「VRAM」メモリを見ると、

なんか同じ画像なのに読まれ方が違うように見えます。最適化ごとで色分けしてみます。

NONE(0):最適化なし
ALL(1):重複、および反転したら同じになるタイルを探して削る
DUPLICATE(2):重複しているタイルを探して削る

こんなカンジで読まれていることがわかります。
メガドライブは、8px四方の絵を「1CELL(セル)」として、この単位で扱うのですが
このセル単位でかぶっていたらoptmizeされるということですね。
NONEだとバカ正直に画像をまるごとメモリにためてしまう。
ALLは重複・反転をマージしてあるので一番効率いい。
加えて、同じ画像だからといって全体でoptmizeされるわけでもないようなので、
画像を載せるときは結構注意が必要そう。

このあたりはきっと、プログラムのほうでも補完が必要なんだろうな。
デザエモンはそういうの簡単に反転できたけど、
桜井さんのYoutubeでゲームボーイ開発の苦労話見たので、きっとああいうことをするのであろう。


ということで、画像は表示できたので次【PALETTE】をいじってみたいと思います。
ところで、map_baseオプション…。タイルマップのベース タイル インデックス オフセット…なんそれ?
静的(static)に値を割り当てれば、VDP_setTileMapxxx(..)コマンドで使うときに速くなるぞ!ですって。ふーん。
シカトしよ。いまは。いまはね。

タイトルとURLをコピーしました