これが
こうなって
こうなる
10年ほど前にflipこそプレゼンテーション(演出効果みたいな)の 基本であろうとか勝手に思いこんでPC-9801UV11相手にいろいろ 遊んでいたのを思い出してまたやってみました。
↑の昔話の頃は、表VRAMと裏VRAMの内容を入れ替えるということで swapと呼んでいましたが要するに現在見えている絵を、別の絵に 切り替えることをここではflipと呼んでいます。
単に切り替えるだけではなく、その過程に何らかの演出効果を 出してゆこうというもんです。
ソース + Windows版バイナリ + Windows版DLLが入ってます。
あそぶにはこのファイルの他に、320x240のbmpファイル2枚が必要です。
まだまだ変わりそうなのでアーカイブファイル内のREADMEを見てやってください
flip処理本体をドライバと呼ぶことにします。ドライバは独立した ソースファイルで構成され、現在のところ 最低限要求されている仕様は以下の通りです。
その他の事項として
新しいドライバを作るときはtemplate.cを参考にしてやってください。
以後の説明では、ドライバを呼び出す前の画面を 「前画像」、入れ替えた後の画像を「後画像」と呼ぶことにします。
ゲーム名の後の機種名は私がやったことのあるマシンの名前です。
クロスフェードです。後画像や前画像を単色にすると、フェードアウト、 フェードインになります。
前にある画像のアルファ値を0.0⇔1.0の間で変化させるだけなので アルファ使えると楽だねえとつくづく思ったりします。
あいかわらずうまい説明がみつからないのですが.... 後画像が右端から じわじわと出現するようなものです。
(α値について) 0 0 0 0 0→1 1 1 1 1 (ほかの色) 後画像 中間 後画像 (中間 = 後画像と黒のグラデーション)最後に、前画像をglBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA) で いちばん前に貼り付けます。このブレンド方法だと、 前画像はα = 1に近いところ(右)は見えず、α = 0に近いところ(左)のほうだけが 表示されます。で、0→1の部分をだんだん左に走らせてゆくと、最後は 後画像だけが表示されることになり、flipが完了します。
後画像のランダムな位置の、一定の大きさの矩形領域を前画像と 交換してゆくことでflipを行います。 設定可能なプロパティはxとyで、それぞれ交換の単位となる 縦横のピクセル数を指定します。
Ambivalenz(Alice Soft, PC98)の、シィアからディアドラが出現するシーン なんかはx=8、y=8くらいで呼び出すと似てるかも。Ambivalenzのオープニングは 今でも思い出すと鳥肌が立ちますなあ。音楽もすばらしかったし。
x=8、y=1にすると夢幻の心臓II(XTAL SOFT, PC88)の水晶玉(マップ表示)のときの 表示に似てるかなあ
全ての位置を漏れなく交換しないとflipは成立しませんので、 ここでは10年前にやったのと同じように 線形合同法による一様乱数を使っています。
X = (A * X + C) % M という式に次々とXを入れてゆくと乱数列っぽくなるわけですが、 Mが2の羃乗、A≡5(mod 8)、C≡1(mod 2) のとき、 この処理をM回繰り返すことで0〜M-1までの数字が1回ずつ現れる 乱数列を作ることができます。
実際には本当に出したい乱数の範囲Mが2の羃乗とは限りませんので、 Mを越えない最小の2の羃乗となる数を捜すceilingという関数を作ってます。 ここでは「最もLSBに近い1が立ってるビットのみを1にする式」を 利用しています。詳しくはfjの教祖様の説明を御覧下さい。
話を無駄に複雑にしていないかという気もしますが、 こういう場合のセオリーであると思われる 「数列を作っておいてそれを乱数でかきまぜる(乱数で 選ばれた2つの位置の数を交換する〜という処理を何回か繰り返す)」 という処理はメモリを食うし、他にいい方法も思いつかなかったので まあいいか〜
んー説明がむずかしい。一定ドット幅のラインごとに軌跡を描きながら 描画してゆきます...で通じます?(通じるか) 設定可能なプロパティはstepとspeedで、 stepドットずつspeed秒間でflipを行います。
step=1、speed=10くらいにするとXAK2(Micro Cabin, PC88/PC98)の オープニングタイトル画面みたいになります。XAK2のオープニングは YsIIと同じくらい好きですがどうでしょう(なんやそれ)
横方向だとRance3(Alice Soft, PC98)のオープニングになりますな。 (まだ実装してませんが...)
TVを消したりつけたりしたときのような、垂直成分が圧縮/伸長されてゆく 様子を意識したeffectです。
それならもっと似せようがあるだろうという気がしますが アルシャーク(right-stuff, PC98)の戦闘シーンを意識してこんな 感じになってます。でもこのシーン、うちのPC-9801UV11じゃ遅くて 何がやりたかったのかさっぱり分かりませんでしたが、 友達のPC-9801DAで見たらとても格好よくて愕然とした記憶が。
天外魔境II (HUDOSON、PC-Engine)のタイトルロゴが出てくるところでも 似たような処理がありました。
スクロールしつつ画像を切り替えます。 設定可能なプロパティはtype、step、step2、speedで、 stepドットずつspee秒間でflipを行います。
typeにはv、h、mが指定可能で、vだと垂直スクロール、hだと水平スクロール、 mだとマーシャルエイジ(天津堂、PC98)風スクロールになります。
step2はtype=mのときのみ有効で、水平シフトスクロール(はみ出た部分が 反対側に出てくるものを便宜上こう呼びます)のシフト量を指定することができます。 マーシャルエイジだとstep=1、speed=10、step2=80くらいかなあ。 最初と最後に加速度がついたような気もするんですが記憶が定かではありません。
PC98だとこの手のスクロールはGDCに表示位置変更のコマンドを送って、 欠けた分だけ補ってやればいいのでとても楽なのですが、 今回は自力でBlitSurfaceを組み合わせて実現させています。 力技でも(320x240なら)それっぽく見えるのが最近のマシンのすごいところ。
type=vまたはh、speed=1、step=16くらいにすると ハイドライドスペシャル(TOSHIBA EMI、family computer)とか ハイドライド3(T&E soft、PC88)とかのマップ切替に近くなるかも。
flip呼ぶ前に前画像のテクスチャを作成し、それをビューポートいっぱいに 貼り出しています。
ふつうにflipを呼び出します。SDL_GL_SwapBuffersはflip側で呼び出します。
flipを別スレッドで呼び出します。ただし、元画像はディスプレイサーフェスではなく、 同じ大きさのソフトウエアサーフェスを渡しています。
メインスレッド側は、ソフトウエアサーフェスのpixelsを、glTexSubImage2Dによって テクスチャに転送します。
flip後に更新がおろそかになっています。
また、ウインドウサイズ変更なども放置...