/*	
 *	clipvqtd.h
 *
 *	VQ圧縮テクスチャ描画
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2016-2017 Naoyuki Sawa
 *
 *	* Wed Dec 21 21:39:53 JST 2016 Naoyuki Sawa
 *	- 1st リリース。
 *	  まだ仮実装で、速度は度外視で、PDW_Draw_VQTC()が描画出来るようになっただけです。
 *	  今後、仮実装のコードは削除して、PDW_Draw_VQTC()をきちんと実装して行く予定です。
 *	* Thu Dec 22 21:24:33 JST 2016 Naoyuki Sawa
 *	- PDW_Draw_VQTCの仮実装コードを削除し、本実装コードを作成しました。
 *	  本実装コードは、framdraw.cのPDW_Draw_4BNのアセンブラ版の実装を元にして作成しました。
 *	  PDW_Draw_VQTCはまだC言語版のみですが、アルゴリズムは充分最適化されていると思います。
 *	  近い内に、PDW_Draw_VQTCのアセンブラ版も作成する予定です。
 *	* Fri Dec 23 23:24:50 JST 2016 Naoyuki Sawa
 *	- clipvqtc.cモジュールにて、コードブックの5バイトの圧縮データの1バイト目のビット詰めの順序を逆にした事に伴い、PDW_Draw_VQTC()関数のC言語版の実装も修正しました。
 *	  PDW_Draw_VQTC()関数のアセンブラ版はこれから作成するので、直接、変更後のビット詰め順序に合わせて作成します。
 *	- PDW_Draw_VQTC()関数のアセンブラ版を作成しました。
 *	  C言語版に比べて、アセンブラ版の方が3.5倍ぐらい(!)早くなりました。
 *	  アセンブラ版を使っても、P/ECEカーネルの2bitmaskテクスチャ描画より、4.8倍ぐらい遅いです。
 *	  しかし、framvqtd.oとframbary.oを高速RAMに配置すれば、1.4倍ぐらい遅くなるだけで済みます。
 *	  VQ圧縮によるテクスチャ容量低減の効果が大きい割には、充分許容出来る速度低下だと思います。
 *	* Sat Dec 24 21:19:40 JST 2016 Naoyuki Sawa
 *	- clipvqtc.cモジュールにて、コードブックに格納する色の値を「0=白〜3=黒,4=透明」⇒「0=透明,1=白〜4=黒」に変更した事に伴い、PDW_Draw_VQTCの処理も変更しました。
 *	  詳細は、clipvqtc.hの同日のコメントを参照して下さい。
 *	* Sun Dec 25 21:14:35 JST 2016 Naoyuki Sawa
 *	- アセンブラ版のPDW_Draw_VQTCを、前半と後半に分割し、前半をframvqtd.c⇒clipvqtd.cへ移しました。
 *	  変更した理由は、高速RAMの使用量を節約するためです。
 *	  詳細は、以下の通りです。
 *	- PDW_Draw_VQTCの前半は初期化処理であり、PDW_Draw_VQTCの呼び出し一回当たり一回しか実行されません。
 *	  PDW_Draw_VQTCの前半はループ処理であり、各ライン,及び,各ピクセルについて実行されます。
 *	  重点的に高速化すべきなのは後半であり、前半を高速化してもあまり恩恵は有りません。
 *	  これまでは、PDW_Draw_VQTC全体をframvqtd.cに書いていたので、framvqtd.oを高速RAMに配置すると、あまり高速化の必要が無い前半までもが高速RAMに配置されてしまい、高速RAMの使用量を無駄に消費していました。
 *	  そこで今回、アセンブラ版のPDW_Draw_VQTCを前半と後半に分割し、あまり高速化の必要が無い前半を、framvqtd.c⇒clipvqtd.cへ移しました。
 *	  尚、C言語版のPDW_Draw_VQTCは関数を前半と後半に分割する事は出来ないので、今回変更を行ったのはアセンブラ版のPDW_Draw_VQTCのみです。
 *	  元々、C言語版のPDW_Draw_VQTCはアルゴリズムを確認するためだけのもので、実際に使用する事は無いので、問題有りません。
 *	- 検証結果は以下の通りです。
 *	  16x16ピクセルのベタ塗りのキャラクタを10000回描画するのにかかる時間と、高速RAMの消費量を確認しました。
 *	  □変更前
 *	  │framvqtd.o 352バイト┬高速RAM使用量=488バイト
 *	  │frambary.o 136バイト┘
 *	  │framvqtd.oとframbary.oを両方とも高速RAMに置いた場合の時間 3366[ms]
 *	  │framvqtd.oだけを高速RAMに置いた場合の時間                 4879[ms]
 *	  │frambary.oだけを高速RAMに置いた場合の時間                 9105[ms]
 *	  □変更後
 *	  │framvqtd.o 152バイト┬高速RAM使用量=288バイト                       200バイト節約。充分な効果だと思います。
 *	  │frambary.o 136バイト┘
 *	  │framvqtd.oとframbary.oを両方とも高速RAMに置いた場合の時間 3406[ms]  1.2%低速。高速RAMの使用量節約の効果が高い事に比べれば、許容出来ると思います。
 *	  │framvqtd.oだけを高速RAMに置いた場合の時間                 4919[ms]  これは参考値です。実際にはframvqtd.oだけを高速RAMに置くのではなく、framvqtd.oとframbary.oを両方とも高速RAMに置いて下さい。
 *	  │frambary.oだけを高速RAMに置いた場合の時間                 9107[ms]  これも参考値です。前半と後半の間にジャンプ命令が増えた分、高速RAMを使用しない場合も僅かに低速化したのだと思います。
 *	* Sun Dec 25 23:57:41 JST 2016 Naoyuki Sawa
 *	- clipvqtc.cモジュールにて、符号の数の上限を256⇒65536に変更した事に伴い、PDW_Draw_VQTC()関数も修正しました。
 *	  この変更による速度低下は、上記と同じ計測方法で、約1%未満です。
 *	  この変更によるコードサイズ増加は、clipvqtd.cが10バイト程度増加しただけで、高速RAMの容量には影響有りません。
 *	* Mon Dec 26 21:39:12 JST 2016 Naoyuki Sawa
 *	- PDW_Draw_VQTCの除算ループを僅かに高速化しました。
 *	  除算ループ内の命令を一つ、除算ループ外へ移動出来る事に気付いたからです。
 *	  全体の命令数は変わっていません。
 *	  高速化の効果は約0.5%程度ですが、デメリットは無いので良い最適化だと思います。
 *	* Wed Dec 28 21:04:25 JST 2016 Naoyuki Sawa
 *	- 2016/12/27のframbary.cモジュールにてAsm版のbitarray_lsb1st_get,及び,bitarray_msb1st_getが破壊するレジスタを減らした事に伴い、PDW_Draw_VQTC(前半),及び,PDW_Draw_VQTC_READY(後半)のAsm版がレジスタに保持する値を増やして最適化しました。
 *	  16x16ピクセルのベタ塗りのキャラクタを描画するテスト(2016/12/25の検証方法と同様の方法)で、約8.1%高速になりました。
 *	  もっと差が出易い、128x88ピクセルのキャラクタパターン画像を画面全体に描画するテストでは、約9.4%も高速になりました。
 *	  また、framvqtd.oのコードサイズが、152バイト⇒128バイトへと、24バイトも減りました。
 *	  高速化の効果もコードサイズ低減の効果も高くて、かなり良い最適化が出来たと思います。
 *	* Sun Jan 01 21:54:31 JST 2017 Naoyuki Sawa
 *	- PDW_Draw_VQTCの、レジスタの使用方法を少し変更して、僅かに高速化しました。
 *	  変更前は、&cellline[i_pixel]のアドレスを毎ループ計算していましたが、変更後は、最初に計算してそれ以降はインクリメントするだけにしました。
 *	  元々、毎ループ計算していた理由は、i_pixelをインクリメントして4の倍数になるタイミングを検出するためだったのですが、
 *	  よく考えると、&cellline[0]のアドレスは必ず4の倍数に整列しているので、&cellline[i_pixel]のアドレスが4の倍数かを判断する方法でも可能である事に気付いたからです。
 *	- 16x16ピクセルのベタ塗りのキャラクタを描画するテスト(2016/12/25の検証方法と同様の方法)で、約1.7%高速になりました。
 *	  framvqtd.oのコードサイズは、128バイトのまま変わっていません。
 *	* Thu Jan 05 21:50:41 JST 2017 Naoyuki Sawa
 *	- PDW_Draw_VQTCにおいて、転送元のピクセル位置がセル境界を跨いだかを判定する方法を変更して、高速化しました。
 *	  詳細は、以下の通りです。
 *	- 前回(2017/01/01)変更したコードでは、転送元のピクセル位置がセル境界を跨いだかを判定する方法は、転送元アドレスと3のAndを取って判定していました。
 *	  しかし、転送元アドレスを破壊せずに3とのAndを取るには、アセンブラで2命令掛かっており、最内周ループで毎回発生するので、やや効率が悪い処理でした。
 *	  そこで、転送元アドレスと3のAndを取るのではなく、転送元アドレスと終端アドレス(&cellline[4])を比較する事により、最内周ループを1命令節約しました。
 *	  デメリットとしては、'&cellline[4]'をレジスタに保持するために、これまではレジスタに保持出来ていた'&cellline[obj.sx&3]'がメモリからのロードになりましたが、外周ループなので速度低下の影響は小さいです。
 *	  デメリットよりも、前述の、最内周ループを1命令節約出来た恩恵の方が大きいので、全体としては高速化しました。
 *	- 高速化の検証結果は以下の通りです。
 *	  │16x16ピクセルのベタ塗りのキャラクタを10000回描画するのにかかる時間:  変更前 3136[ms] → 変更後 3094[ms] … 約1.3%高速化
 *	  │128x88ピクセルのキャラクタパターン画像を画面全体に500回描画する時間: 変更前 5129[ms] → 変更後 5013[ms] … 約2.2%高速化
 *	- 尚、今回の目的は高速化であり、コードサイズ低減は意図していなかったのですが、framvqtd.oのコードサイズが128バイト→124バイトへと4バイト減りました。
 *	  今回の変更で実際に減ったのは1命令(2バイト)だけなのですが、4バイトの倍数に切り上げられるため、これまで無駄な2バイトが有った分、4バイト減りました。
 *	  とは言え、前述の通り、今回はコードサイズ低減は意図していなかったので、あまり重要ではありません。
 */
#ifndef __CLIP_VQTD_H__
#define __CLIP_VQTD_H__
#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus
#ifdef  PIECE
#define USE_PDW_Draw_VQTC_ASM	//このシンボルを定義するとアセンブラ版のPDW_Draw_VQTCを使用します。このシンボルを定義しなければC言語版のPDW_Draw_VQTCを使用します。通常はアセンブラ版のPDW_Draw_VQTCを使用して下さい。C言語版のPDW_Draw_VQTCはアルゴリズムを確認するためだけのものです。
#endif//PIECE
/*****************************************************************************
 *	
 *****************************************************************************/
void VqTc_InitDrawing();
void VqTc_ExitDrawing();
#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus
#endif//__CLIP_VQTD_H__
