/*
 *	clipvsl.h
 *
 *	ビデオスロットゲーム用サブルーチン集
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2017 Naoyuki Sawa
 *
 *	* Thu Feb 11 21:46:05 JST 2016 Naoyuki Sawa
 *	- 1st リリース。
 *	* Fri Jun 03 21:47:06 JST 2016 Naoyuki Sawa
 *	- シンボルタイプの定数を定義しました。
 *	  これまではシンボルタイプを直値(-1,0,1)で指定していましたが、今後はシンボル(VslTyp_*)で指定して下さい。
 *	* Tue Jun 07 22:13:11 JST 2016 Naoyuki Sawa
 *	- 通常ラインタイプの、配当額取得関数(旧:fnGetPay)を、ライン配当額取得関数(新:fnLinPay)と、スキャッター配当額取得関数(新:fnScaPay)に分けました。
 *	  243ウェイ・ルート払い戻しタイプの、配当額取得関数(旧:fnGetPay)を、ウェイ配当額取得(新:fnWayPay)と、スキャッター配当額取得関数(新:fnScaPay)に分けました。
 *	  上記のように変更した理由は、揃ったライン(又はウェイ)によって、配当額が変わるケースに対応するためです。
 *	  揃ったライン(又はウェイ)によって配当額が変わるルールの場合は、引数iLin(又はiRow[])を参照して、揃ったラインに応じた配当額を返して下さい。
 *	  揃ったライン(又はウェイ)によって配当額が変わらないルールの場合は、引数iLin(又はiRow[])を無視して下さい。
 *	* Thu Jul 07 21:12:07 JST 2016 Naoyuki Sawa
 *	- 3行以外の行数に対応しました。
 *	  これまでは、5リール3行固定でしたが、今後は、5リール1行〜5リール(VslRow_Max)行まで対応可能になりました。
 *	  行数は、ST_Vsl5nl_GetWin_Inf構造体,又は,ST_Vsl243_GetWin_InfのnRowフィールドで指定して下さい。
 *	- 今回の変更により、'243ウェイ・ルート払い戻しタイプ'は厳密には243ウェイではなく、(nRow^5)ウェイとなります。
 *	  しかし便宜上、243ウェイという名前の方が判り易いので、関数名は変えない事にしました。
 *	- 変更後の検証がまだ不十分です。(特にVsl243_GetWin())
 *	  今後、実際に使いながら、検証する予定です。
 *	* Wed Jul 20 21:23:00 JST 2016 Naoyuki Sawa
 *	- シンボルタイプ(列挙値)を廃止し、シンボル属性(フラグ)に変更しました。
 *	  アプリケーション定義の、シンボルタイプ取得関数(*fnGetTyp)()を、シンボル属性取得関数(*fnGetAtt)()に変更しました。
 *	  この変更によって、通常シンボル,ワイルドシンボル,スキャッターシンボルに加えて、スキャッターワイルドシンボルも表現出来るようになりました。
 *	* Sun Aug 07 21:13:31 JST 2016 Naoyuki Sawa
 *	- VslRel_GetSensorCrossingCount_Linear(),VslRel_GetSensorCrossingCount_Circular()を追加しました。
 *	  直線上,又は,円周上の移動において、特定の位置を跨いだ回数を求める、汎用的な処理ですが、
 *	  今回は、リールアニメーション処理で使用するために作成したので、当モジュールに含める事にしました。
 *	  他の用途にも、使用出来ると思います。
 *	* Mon Aug 29 21:46:36 JST 2016 Naoyuki Sawa
 *	- VslRel_GetSensorExceedingCount_Linear()を追加しました。
 *	* Thu Feb 23 21:53:55 JST 2017 Naoyuki Sawa
 *	- 「dVslDefC.exe対応ユーティリティ」を追加しました。
 *	* Fri Feb 24 21:21:52 JST 2017 Naoyuki Sawa
 *	- dVslDefC.exeが出力する列挙定義スクリプトの、シンボルの列挙定義名を"Symbol_*"→"VslSym_*","GameMode_*"→"VslGmd_*"に変更した事に伴い、「dVslDefC.exe対応ユーティリティ」の関数の仮引数名も変更しました。
 *	  関数の仮引数名の修正だけなので、プログラムの動作には変更有りません。
 *	  今回の変更は些細な変更なので、変更前のコードは残していません。
 *	* Thu Mar 16 22:31:07 JST 2017 Naoyuki Sawa
 *	- dVslDefC.exeがライン定義も出力するように変更した事に伴い、「dVslDefC.exe対応ユーティリティ」もやや大幅な変更を行いました。
 *	  具体的には、以下の通りです。
 *	- レジストリ構造が変わった事に伴い、既存の関数の内部処理を変更しました。
 *	  これまでは、ゲームモードのレジストリキーの直下に、リールストリップとペイテーブルのBLOBが有り、bit15が0(=リールストリップ)か1(=ペイテーブル)かによって、両者を区別していました。
 *	  □変更前
 *	  │VslDef─┬─0        リール0のリールストリップのBLOB
 *	  │        ├─1        リール1のリールストリップのBLOB
 *	  │        ├─2        リール2のリールストリップのBLOB
 *	  │        ├─1|0x8000 シンボル1のペイテーブルのBLOB
 *	  │        ├─2|0x8000 シンボル1のペイテーブルのBLOB
 *	  │        └─3|0x8000 シンボル1のペイテーブルのBLOB
 *	  今回、dVslDefC.exeがライン定義を出力するために、ゲームモードのレジストリキーの直下にライン定義も置いてbit14等で区別する方法も可能ではあったのですが、それでは判り辛いし今後の拡張が行い辛いのでその方法は取らない事にしました。
 *	  素直に、ゲームモードのレジストリキーの直下は、リールストリップのキーと、ペイテーブルのキーと、ライン定義のキーを設けて、それぞれのキーの中にそれぞれのデータを入れるように変更しました。
 *	  □変更後
 *	  │VslDef─┬─1─┬─0 リール0のリールストリップのBLOB
 *	  │        │ 	   ├─1 リール1のリールストリップのBLOB
 *	  │        │     └─2 リール2のリールストリップのBLOB
 *	  │        ├─2─┬─0 ライン0のライン定義のBLOB
 *	  │        │ 	   ├─1 ライン1のライン定義のBLOB
 *	  │        │     └─2 ライン2のライン定義のBLOB
 *	  │        └─3─┬─1 シンボル1のペイテーブルのBLOB
 *	  │           	   ├─2 シンボル2のペイテーブルのBLOB
 *	  │               └─3 シンボル3のペイテーブルのBLOB
 *	  尚、ゲームモードのレジストリキーの直下のキー値を「1=リールストリップ,2=ライン定義,3=ペイテーブル」の順番にした理由は、一般的なアプリケーションの処理の順序に一致させた方が直観的に判り易いと思っただけで、特に意味は有りません。
 *	  0ベースでなく1ベースとした理由も、特に意味は有りません。
 *	- 「dVslDefC.exe対応ユーティリティ」の、既存の関数のやや大幅な変更を行ったので、変更前のコードはコメントアウトして残していません。
 *	  変更前のコードを参照する必要が有る場合は、前回のアーカイブを参照して下さい。
 *	  既存の関数の内部処理は変更しましたが、アプリケーションインターフェイスは変更していないので、アプリケーション側での変更は不要です。
 *	- また、今回、ライン定義を追加した事に伴い、新たにVslDef_GetLinNum()関数とVslDef_GetLinRow()関数を追加しました。
 *	  VslDef_GetLinNum()関数の使い方は、自明だと思います。
 *	  VslDef_GetLinRow()関数の使い方は、iReel引数について注意点が有るので補足します。
 *	  一般的には、VslDef_GetLinRow()関数のiReel引数に渡せる範囲は、0〜VslDef_GetRstNum()-1 の範囲です。
 *	  しかし、一つのゲームモードの中で(BET数等によって)リールストリップが変化するようなゲーム仕様の場合は、(例えば)5リールでも、リールストリップのデータは6本以上定義しておいて、アプリケーション側で選択して使用する場合が有り得ます。
 *	  その場合、VslDef_GetRstNum()は6以上の値を返すが、VslDef_GetLinRow()関数のiReel引数に渡せる範囲は6-1未満でなくてはならない(一般的には0〜4)というケースも生じ得ます。
 *	  実際のリールの本数はアプリケーションしか知り得ないので、VslDef_GetLinRow()関数のiReel引数には適切な範囲の値を指定して下さい。
 *	  もし、ライン定義で定義されたリール数よりも大きな値をVslDef_GetLinRow()関数のiReel引数に指定すると、VslDef_GetLinRow()関数の中でエラー停止します。
 *	* Fri Mar 17 23:53:28 JST 2017 Naoyuki Sawa
 *	- VslDef_GetRstSym_w()を追加しました。
 *	  既存のVslDef_GetRstSym()との違いは、引数iPosの値を自動的に 0〜VslDef_GetRstLen()-1 の範囲に折り返す事です。(関数名の'_w'はWraparoundの'w'です。)
 *	  既存のVslDef_GetRstSym()とVslDef_GetRstLen()を使えば、アプリケーション側でも実現出来る処理ではあるのですが、アプリケーション側でこの処理を行う頻度が特に高いので、アプリケーション側の実装の手間を省くために、当モジュール側で共通処理として用意する事にしました。
 *	* Wed Apr 12 22:29:29 JST 2017 Naoyuki Sawa
 *	- VslDef_GetSymName(),VslDef_GetSymDesc(),VslDef_GetGmdName()を追加しました。
 */
#ifndef __CLIP_VSL_H__
#define __CLIP_VSL_H__
#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus
/****************************************************************************
 *	定数
 ****************************************************************************/
//行数の最大値
#define VslRow_Max		9		//行数の最大値(変更可)
/*--------------------------------------------------------------------------*/
//シンボル属性
// - アプリケーション定義のシンボル属性取得関数(fnGetAtt)は、以下の値の0個以上の組み合わせを返してください。
//   各組み合わせの意味は、以下の通りです。
//	0				通常シンボル。
//					ラインウィンを構成します。
//	VslAtt_Wild			ワイルドシンボル。
//					通常シンボルと混合して,又は,ワイルドシンボル単体で、ラインウィンを構成します。
//	VslAtt_Scatter			スキャッターシンボル。
//					スキャッターウィンを構成します。
//	VslAtt_Wild|VslAtt_Scatter	スキャッターワイルドシンボル。
//					通常シンボル及びワイルドシンボルと混合して,又は,スキャッターワイルドシンボル単体で、ラインウィンを構成します。
//					スキャッターシンボルと混合して,又は,スキャッターワイルドシンボル単体で、スキャッターウィンを構成します。
//					ただし実際には、スキャッターワイルドシンボル単体でラインウィンとスキャッターウィンを同時に払い出すと問題が有ると思うので、リールストリップ,又は,ペイテーブルの設計で回避して下さい。
//					前者の例としては、スキャッターワイルドシンボルを1stリールには配置しないようにしてスキャッターワイルドシンボル単体でラインウィンが構成されないようにする、等です。
//					後者の例としては、(*fnLinPay)()がスキャッターワイルドシンボルに対して常に0を返すようにして、スキャッターワイルドシンボル単体のラインウィン配当を0にする、等です。
#define VslAtt_Wild		(1<<0)		//ワイルドシンボル
#define VslAtt_Scatter		(1<<1)		//スキャッターシンボル
/****************************************************************************
 *	通常ラインタイプ
 ****************************************************************************/
typedef struct _ST_Vsl5nl_GetWin_Inf {
	int nRow;										//行数				1〜VslRow_Max
	int nLin;										//ライン数			1〜
	int (*fnGetRow)(int iLin, int iRel, void* arg);						//ライン行取得			(ライン番号=iLin,リール番号=iRel)に対する、行番号(0〜(nRow-1))を返して下さい。
	int (*fnLinPay)(int iSym, int nOak, int iLin, void* arg);				//ライン配当額取得		(シンボル番号=iSym,出現数=nOak,ライン番号=iLin)に対する、配当額(0〜)を返して下さい。
	int (*fnScaPay)(int iSym, int nOak, void* arg);						//スキャッター配当額取得	(シンボル番号=iSym,出現数=nOak)に対する、配当額(0〜)を返して下さい。
	int (*fnGetAtt)(int iSym, void* arg);							//シンボル属性取得		0,VslAtt_Wild,VslAtt_Scatter,(VslAtt_Wild|VslAtt_Scatter)のいずれかの値を返して下さい。
	int (*fnGetSta)(int iRel, int iRow, void* arg);						//停止形取得(Stationary)	0以上の値で、アプリケーション定義のシンボル番号を返して下さい。
	void (*fnLinWin)(int iSym, int nOak, int iLin, int nPay, void* arg);			//ラインウィン通知		このラインで揃った(nOak≧1)のコンビネーションの内、最大の配当額(0も含む)について通知する。
	void (*fnScaWin)(int iSym, int nOak, int nPay, void* arg);				//スキャッターウィン通知	当関数は配当額を考慮しない。(nOak≧1)のコンビネーションを全て通知する。
} ST_Vsl5nl_GetWin_Inf;
int Vsl5nl_GetWin(const ST_Vsl5nl_GetWin_Inf* pInf, void* arg);
/****************************************************************************
 *	243ウェイ・ルート払い戻しタイプ
 ****************************************************************************/
typedef struct _ST_Vsl243_GetWin_Inf {
	int nRow;										//行数				1〜VslRow_Max
//無し	int nLin;										//ライン数			1〜
//無し	int (*fnGetRow)(int iLin, int iRel, void* arg);						//ライン行取得			(ライン番号=iLin,リール番号=iRel)に対する、行番号(0〜(nRow-1))を返して下さい。
	int (*fnWayPay)(int iSym, int nOak, const int iRow[/*nOak*/], void* arg);		//ウェイ配当額取得		(シンボル番号=iSym,出現数=nOak,ウェイ=iRow[0〜(nOak-1)])に対する、配当額(0〜)を返して下さい。
	int (*fnScaPay)(int iSym, int nOak, void* arg);						//スキャッター配当額取得	(シンボル番号=iSym,出現数=nOak)に対する、配当額(0〜)を返して下さい。
	int (*fnGetAtt)(int iSym, void* arg);							//シンボル属性取得		0,VslAtt_Wild,VslAtt_Scatter,(VslAtt_Wild|VslAtt_Scatter)のいずれかの値を返して下さい。
	int (*fnGetSta)(int iRel, int iRow, void* arg);						//停止形取得(Stationary)	0以上の値で、アプリケーション定義のシンボル番号を返して下さい。
	void (*fnWayWin)(int iSym, int nOak, const int iRow[/*nOak*/], int nPay, void* arg);	//ウェイウィン通知		当関数は配当額を考慮しない。(nOak≧1)のコンビネーションを全て通知する。
	void (*fnScaWin)(int iSym, int nOak, int nPay, void* arg);				//スキャッターウィン通知	当関数は配当額を考慮しない。(nOak≧1)のコンビネーションを全て通知する。
} ST_Vsl243_GetWin_Inf;
int Vsl243_GetWin(const ST_Vsl243_GetWin_Inf* pInf, void* arg);
/****************************************************************************
 *	リールアニメーション処理の補助関数
 ****************************************************************************/
int VslRel_GetSensorCrossingCount_Linear(double oldpos, double vec, double snspos, double* pnewpos/*NULL可*/);
int VslRel_GetSensorCrossingCount_Circular(double oldpos, double vec, double snspos, double lbound, double ubound, double* pnewpos/*NULL可*/);
/*--------------------------------------------------------------------------*/
int VslRel_GetSensorExceedingCount_Linear(double oldpos, double vec, double snspos, double* pnewpos/*NULL可*/);
/****************************************************************************
 *	dVslDefC.exe対応ユーティリティ
 ****************************************************************************/
//ゲームモードのレジストリキーに属する、キーの名前
#define VslDef_ReelStrip	1		//リールストリップ
#define VslDef_LineDef		2		//ライン定義
#define VslDef_PayTable		3		//ペイテーブル
/*--------------------------------------------------------------------------*/
int VslDef_GetSymNum(const void* pEnmKey, int _RegKey_VslSym);
const char* VslDef_GetSymName(const void* pEnmKey, int _RegKey_VslSym, int iVslSym);	//{{2017/04/12追加:VslDef_GetSymName(),VslDef_GetSymDesc(),VslDef_GetGmdName()を追加しました。}}
const char* VslDef_GetSymDesc(const void* pEnmKey, int _RegKey_VslSym, int iVslSym);	//{{2017/04/12追加:VslDef_GetSymName(),VslDef_GetSymDesc(),VslDef_GetGmdName()を追加しました。}}
int VslDef_GetGmdNum(const void* pEnmKey, int _RegKey_VslGmd);
const char* VslDef_GetGmdName(const void* pEnmKey, int _RegKey_VslGmd, int iVslGmd);	//{{2017/04/12追加:VslDef_GetSymName(),VslDef_GetSymDesc(),VslDef_GetGmdName()を追加しました。}}
int VslDef_GetRstNum(const void* pVslKey, int iVslGmd);
int VslDef_GetRstLen(const void* pVslKey, int iVslGmd, int iReel);
int VslDef_GetRstSym(const void* pVslKey, int iVslGmd, int iReel, int iPos);
int VslDef_GetRstSym_w(const void* pVslKey, int iVslGmd, int iReel, int iPos);	//{{2017/03/17追加:VslDef_GetRstSym_w()を追加しました。}}
int VslDef_GetLinNum(const void* pVslKey, int iVslGmd);
int VslDef_GetLinRow(const void* pVslKey, int iVslGmd, int iLine, int iReel);
int VslDef_GetMaxOak(const void* pVslKey, int iVslGmd, int iVslSym);
int VslDef_GetPay(const void* pVslKey, int iVslGmd, int iVslSym, int nOfAKind);
#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus
#endif//__CLIP_VSL_H__
