2020年10月12日月曜日

PS2の直線並びでない4bitイメージを見られるカタチにする

PS2アンジェリーク トロワの中身を漁っていて見つけたこのイメージ(TIM2ヘッダなし)↓は、幅0x40*高さ0x20、使用色6色。一体どこのパーツなのだろう。どうせ見ても面白いもんでもなさそうだし10年以上スルーしていたが、とことん知り尽くすというポリシーに反していたので改めて向き合うことにした。

自作の直線並びでない8bitイメージ用のコンバータで変換してみるとグチャグチャになる。4bitイメージは8bitとは違うコードを書く必要がありそうだ。それには変換後のデータが必要だ…といっても、何のパーツかわからないことには…。

変換後のデータをカンで探す

ゲームをやり込んでいるとカンが働くもので、攻略本のカラー写真なども参考にしていくつか候補を絞った。コレだと思ったイメージを、PCSX2 1.4とTexModという神ツールで抽出する(これが私のエミュの使い方なのです!)。以前はプロセスメモリエディタを使って、目を皿にしてバイナリデータを探してダンプしていたからホント楽になりました。ありがとうございます。

+キーを何回か押して候補が見つかったら(緑色に置き換わり、画面左上にイメージが薄ぼんやり表示される)Log withで割り当てたキーを押す。すると、Output Formatで割り当てたイメージ形式で抽出される。私はBMPにしている。このあと色々弄るのでBMPが都合良いのだ。

抽出したイメージを色々修正する

抽出したイメージをXnViewで見てみる。幅64*高さ32。

PS2のイメージは赤と青が逆なので画像(I)→色交換(S)→RGB>BGRで本来の色に戻す。なんて痒い所に手が届く機能がついているんだろう。素晴らしい。

画像(I)→色総数を見ると、6色。どうやらこれが探していた変換後のイメージっぽい。

このあと冒頭の変換前のイメージと変換後のイメージを見比べて、ドットの位置を確認していきたいのだが、地味な配色すぎてわかりづらいからパレットを修正する。その為に、変換後のイメージをファイル(F)→エクスポート(E)→カラー16色(最適化)で4bitイメージBMPに保存する。TexModで抽出したイメージは全て32bitイメージなのだ。

これ以降、変換前のイメージをBefore、変換後のイメージをAfterと呼ぶことにする。

Afterのパレットの並び替えをして色も変える

パレットを並べ替えるツールでAfterを開く。これはTIMの時にお世話になったツール。TM2は非対応だが、BMPには対応している。Windows7では保存後ウィンドウクローズで異常終了する(保存はちゃんとされている)のでよほど古い環境の人以外にはお勧めしない。

最適化した時に使用色が左寄せになってしまったのだろう。Beforeのパレットの並びと合わせないと!

パレットを並べ替えて保存したら、次は画像編集ソフトでBeforeとAfterをオープンしてパレットの使用している色、すなわち6色分だけをカラフルに変える。両方とも同じにする。

使用していない所も色を変えてしまったので、使用している所にレ点をつけた。これでBeforeとAfterはかなり鮮やかになった。どのドットがどこに対応しているのか調べやすくなるだろう。

私は使い慣れた画像編集ソフトを使っているが、XnViewでもパレットの色を変えられる。素晴らしい!
画像(I)→カラーマップ編集。

〔 Before 〕
〔 After 〕

4bitイメージは面倒だからBeforeを8bitイメージにする

8bitイメージの時のコードを手直ししている時、ふと4bitイメージは1バイトで2ドットを表すことを思い出した。ドットを動かす度にいちいち上位4ビット下位4ビットを切ったり貼ったりしないといけないのか…そのうえ、上下が逆転しているときた。考えるのも面倒くさ過ぎる。もう1バイト1ドットでいいじゃないか。というわけで、今更だがBeforeを8bitイメージに変換した。これによって使用パレット番号が変わることはないし、見た目も変わらない。

8bitイメージにしたものの、直線並びでない8bitイメージ用のコンバータではAfterのカタチに変換できなかった。惜しいカタチにもならなかった。やっぱり4bit用のものを作らなくては。

ドットを並べ替えるコードを書いて試行錯誤を重ねる

イメージの左上のドットから順に一行挟んで逆N字(小文字のnと言われた方が私は腑に落ちるのだが…)に並べていく。これを全部で三回繰り返す。何回か回してみて三回がしっくりくると思った。カンです。

〔 Before_1 〕

幅8高さ4でグリッドを設定してみた。白い枠で囲った部分をブロックとみなす。左上の赤い太枠内のドットの並びは↓のようになっている(16進)。ドット1,3,5,7はイメージの右半分、黄色い太枠の右側に飛んでいった。

Before_1の黄色い太枠内のドットを横一列に展開すると、Afterの0x11行目に一致した。やったね!

しかし、Before_1の青い太枠内は同じようにはいかなかった。前後4ドットを交換してから展開すると一致する箇所が見つかる。

他にも交換しなければならない箇所はたくさん見つかった。交換しなくていいブロックを表、交換すべきブロックを裏とすると左上のブロックは必ず表、イメージの半分から右のブロックは必ず裏で始まるっぽい。そのようにして交換したのが↓。緑とオレンジで塗り潰したブロックが交換した箇所。

〔 Before_2 〕

何ブロック毎に交換したらいいかは、イメージの高さによる。(高さ ¥ 2 ^ 4) * 2。色々なサイズのイメージで試してわかったことだ。

あとは各ブロックをしかるべき場所に展開していけば完成だが、どれをどこに配置したらいいか。ブロックに番号を振ってみた。

0は0行目、10は0x10行目へ、といった具合に展開していく。20以降はイメージの右半分の0行目から。全体図を把握しやすいように、ブロックを整理してみる。Before_2の並びよりBefore_3の方がスッキリしてわかりやすい。

最終的にドットはどう並んだ?

この並び方を何と呼ぶのか私は知らない。swizzleとかtwiddleとかいうらしいがどのタイプにはまるのか?とにかくlinearでない8bitイメージ(例えばアンジェリークトロワでいうところの256色の背景など)を変換した時の結果とも違う。そっちの方はこんなに複雑じゃなかった。

これをPS2の4bitイメージデータにする時は(需要がなさそうだが…)、2ドットを1バイトにパックする。パレットはせいぜい16色(0~F)しかないので、桁が溢れることはない。その際上位4bitと下位4bitを入れ替えなければならない。

0 件のコメント:

コメントを投稿