トランジションを使う!

 yaneSDK2nd α6 から、トランジションBlt 機能がつきました。トランジションとは、0から256までの各段階(フェイズと言います)で画像を変形させる機能の総称です。0で画像は表示されておらず、256で普通に Blt したのと同じ状態になります。当然、0から256にカウントアップするだけでなく、カウントダウンしても、好みのフェイズで止める事も可能です。
 実は yaneSDK2nd でトランジションが使いたくて、α4の時に個人的に移植していました。でもあっと言う間に移植されちゃって、まったくもって無駄な努力でした(泣)。
 でも 1st にあって、2nd にないトランジションが実はあります。それに私が作成したトランジションもありますので、とりあえずそれだけでもまとめようと言うことで、作ってみました。
 ところで CPlaneBase も実は結構痛いクラスです。これが無いときは、CDIB32 と CPlane の2つに別々にルーチンを書いていたので、とっても大変でした。うーん、もっと早く付いてくれてればねぇ…。

サンプルプログラム[2000/09/30 Up!] DiagonalDiffusionBlt がバグっていたのを修正!
ソース

 サンプルにはWAFFLEブランドの「Revolution」より、画像をお借りしました。やねうらおさんの許可は取ってありますが、このサンプル用に特別に許可を頂いただけですので、これ以外の用途に使うのは厳禁です。
 ソースのほうは自由に改変、使用してもらって構いません。

 私の作ったトランジションを使うには、PlaneTransBlt2.h, PlaneTransBlt2a.cpp, PlaneTransBlt2b.cpp の3つを自分のプロジェクトにコピーして、ファイルをプロジェクトに追加してください。
 次に PlaneTransBlt2.h の頭にある、yaneSDK.h へのパスを直してください。デフォルトだと私の環境になってますので。
 あとはコンパイルして使ってください。使い方は基本的に CPlaneTransBlt といっしょです(関数名とかはヘッダを読んでね!)。もし、「/GR- オプションがどーのこーの」っていうようなエラーが出たら、プロジェクト->設定->C/C++タグ->カテゴリをC++言語に->ランタイムタイプ情報(RTTI)を有効にする、にチェックをつけてください。dynamic_cast<> を使っているので、RTTI が必要なだけです。

[言い訳・懺悔]

 自分で作ったトランジション以外、すべて 1st のころのソースのパクリです(爆)。コピペして動くようにちょこっと調整しただけの、まったくもって盗人みたいな事してます。ですので、私のトランジション以外はやねうらおさんの著作と致します。
 ただし、動かないという問い合わせは Tear へお願いします。やねさんへ問い合わせたりしないでね!

[注意!]

 サンプルは良いのですが、ご自分でトランジションを使おうとしたとき、CPlane での TensileBlt1,2 類が上手く動かない場合があります(yaneSDK2nd α6で確認)。これは拡縮転送メンバ関数である、BltR 系が「Y軸方向への拡大(等倍含む)に対応していない」事によります。
 実際にやってみると分かるのですが、TensileBlt1 だと、画像の左上1ドットの色で引き伸ばし表示されてしまいます。これは拡大縮小(等倍含む)時に、Y軸方向へ Source 画像を走査しないためです。

(2000/09/30 追加)

 スミマセン。間違いました。正確に表現しますと、Source から Destination へ Plane を転送する際、(Destination の高さ) <= (Source の高さ)の場合に上手く転送できない、というものです。
 転送先(Destination)の領域が小さい場合、転送元(Source)は当然間引いて転送しなければサイズが合いません。その間引きを計算しているのが、yanePlane.cpp 内のマクロ DRAW_CLIPPER_R です。このマクロでは、ブレゼンハムを利用して小数点以下と整数部を分けて計算しています。
 しかし転送系(BltR, BltFastR など)ではこのマクロで計算した整数部を利用していません。ですから縮小の場合に Y 軸方向を走査しないのです。拡大して転送する場合は整数部が 0 で小数点以下にのみ値が入るので、整数部を使用しなくても正しく動作するのです。
 しかし縮小転送の場合は整数部にも値が入ってしまいます( Destination に1回転送するたびに Source をそれだけたくさん先へ進めないと間引けないわけです)。特に等倍だと小数点以下=0、つまり整数部のみとなるわけです。
 ちなみに Y 軸方向の整数部と少数以下は、マクロ DRAW_CLIPPER_R では nStepsY と nStepY として定義されています。BltR,BltFastR 内をサーチすれば分かりますが、nStepsY が使われていません。使われているのは、BlendBltFastR 内の BPP=24 の場合だけのようです。

(2000/09/30 以上)

 やねさんにお願いしたところ、修正してもらう方向でお返事を頂きました!(サンクス、やねさん!)ですので、次バージョンで直っていると思います。

 「今すぐ直したいよ〜」って人は、とりあえず 16BPPの BltR と BltFastR だけですが以下の方法を試してみてください。

 CPlane.cpp の、1550 行付近と 1980 行付近にある、以下の if 文を探してください。

    if ( nEyCnt >= 0 )
    {
     lpSrc = (WORD*)((BYTE*)lpSrcBack + lPitchSrc);  // クリッピングで飛ばす分を足して、次のラインにする
     nEyCnt -= EY2;          // Yの補正値
    }
    else
    {
     lpSrc = lpSrcBack;  // Xループで進んだ分戻す
    }

 見つかりました?そうしたら、この IF 文の最後に以下を付け足してください。

    lpSrc = (WORD*)((BYTE*)lpSrc + lPitchSrc * nStepsY); // TearDrop_Stone Added.

 こうすればOKです。ただし、動作を確認しているのは 16BPP のルーチンだけです。他の BPP や、BlendBltR などは分からない(調べてないです(爆))ので、これで行けるかどうかわかりません。たぶん大丈夫じゃないかな〜?(<-無責任!)