/*	
 *	clipslot.c
 *
 *	スロットゲーム用サブルーチン集
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2014 Naoyuki Sawa
 *
 *	* Sun Jun 02 15:09:44 JST 2013 Naoyuki Sawa
 *	- 1stリリース。
 *	* Sun Aug 18 17:39:58 JST 2013 Naoyuki Sawa
 *	- 役比管理を追加しました。
 *	* Sat Mar 29 15:51:51 JST 2014 Naoyuki Sawa
 *	- テンパイ判定を追加しました。
 *	* Tue Apr 01 00:42:49 JST 2014 Naoyuki Sawa
 *	- 入賞判定を追加しました。
 *	- リール配列を追加しました。
 *	* Tue Apr 08 00:24:56 JST 2014 Naoyuki Sawa
 *	- ラインを追加しました。
 *	- 押順を追加しました。
 *	* Sat May 03 23:21:41 JST 2014 Naoyuki Sawa
 *	- 停止制御を追加しました。
 *	* Mon May 05 15:01:01 JST 2014 Naoyuki Sawa
 *	- 停止制御データビルダを追加しました。
 *	  PC上でツールを作成する時に使用します。P/ECE上では使用しません。
 *	* Mon May 12 12:39:59 JST 2014 Naoyuki Sawa
 *	- スペックデータ作成・出力を追加しました。
 *	  PC上でスペックデータを作成する時に使用します。P/ECE上では使用しません。
 *	* Sat May 31 13:04:14 JST 2014 Naoyuki Sawa
 *	- Slot_PrintStpCtl()が、ST_Slot_StpCtl構造体も出力するように変更しました。
 *	  これまでは、Slot_PrintStpCtl()は個々のテーブルを出力して、アプリケーション側でST_Slot_StpCtl構造体を定義していました。
 *	  今後は、Slot_PrintStpCtl()がST_Slot_StpCtl構造体にまとめて出力するので、アプリケーション側で定義する必要はありません。
 */
#include "clip.h"

/****************************************************************************
 *	出率管理
 ****************************************************************************/

void SlotDeritu_Init(ST_SlotDeritu* Me) {
	/* 全てのフィールドを0クリアする。 */
	memset(Me, 0, sizeof(ST_SlotDeritu));
}

/*--------------------------------------------------------------------------*/

void SlotDeritu_Update(ST_SlotDeritu* Me, int In, int Out) {
	/* 短期,中期,長期のゲーム数定義 */
	static const unsigned short TermLength[3/*0=短,1=中,2=長*/] = { 400, 6000, 17500 };
	int iTerm, iLog;

	/* 投入枚数が0〜3、払出枚数が0〜15の範囲であることを確認する。 */
	if(((unsigned)In > 3) || ((unsigned)Out > 15)) { DIE(); }
	/* 短期,中期,長期について･･･ */
	for(iTerm = 0; iTerm < 3/*0=短,1=中,2=長*/; iTerm++) {
		/* Nゲーム前の投入(払出)枚数が格納されている、レコードインデクス(0〜17499)を求める。 */
		iLog = (unsigned)(Me->GameCount - TermLength[iTerm] + 17500) % (unsigned)17500;
		/* 総投入(払出)枚数に、今回の投入(払出)枚数を足し、Nゲーム前の投入(払出)枚数を引く。
		 * - Nゲーム前の投入(払出)枚数が未格納ならば、レコード値は0なので、同じ処理で構わない。
		 */
		Me->TotalIn[ iTerm] += (In  - ((Me->InLog[ iLog>>2] >> ((iLog&3)<<1)) &  3));
		Me->TotalOut[iTerm] += (Out - ((Me->OutLog[iLog>>1] >> ((iLog&1)<<2)) & 15));
		/*                           └──── Nゲーム前の投入(払出)枚数 ────┘ */
		/* Nゲーム以上経過している場合のみ、Nゲーム間の出率を算出可能である。
		 * - ここではまだ経過ゲーム数を進めていないので、(Nゲーム-1)と比較することに注意せよ。
		 */
		if((unsigned)Me->GameCount >= (unsigned)(TermLength[iTerm] - 1/*上記コメント参照*/)) {
			/* 出率[%]＝総払出枚数[枚]÷総投入枚数[枚]×100 である。
			 * - ただし、Nゲーム間の総投入枚数が0の場合のみ、出率＝総払出枚数×100 とする。
			 *   Nゲーム間、全て再遊技が当選した場合に、総投入枚数が0となることがあり得る。
			 */
			Me->Deritu[iTerm] = (double)Me->TotalOut[iTerm] * 100.0;
			if(Me->TotalIn[iTerm] != 0) { Me->Deritu[iTerm] /= Me->TotalIn[iTerm]; }
		} else {
			/* Nゲーム以上経過するまでは、Nゲーム間の出率を、初期値(0.0)のまま維持する。 */
		}
	}
	/* 今回の投入(払出)枚数を格納する、レコードインデクス(0〜17499)を求める。 */
	iLog = Me->GameCount % 17500;
	/* 投入(払出)枚数ログに、今回の投入(払出)枚数を格納する。 */
	Me->InLog[ iLog>>2] = (Me->InLog[ iLog>>2] & ~( 3 << ((iLog&3)<<1))) | (In  << ((iLog&3)<<1));
	Me->OutLog[iLog>>1] = (Me->OutLog[iLog>>1] & ~(15 << ((iLog&1)<<2))) | (Out << ((iLog&1)<<2));
	/* 経過ゲーム数を進める。オーバーフローしたら、エラー停止とする。 */
	if(++Me->GameCount == 0) { DIE(); }
}

/****************************************************************************
 *	役比管理
 ****************************************************************************/

void SlotYakuhi_Init(ST_SlotYakuhi* Me) {
	/* 全てのフィールドを0クリアする。 */
	memset(Me, 0, sizeof(ST_SlotYakuhi));
}

/*--------------------------------------------------------------------------*/

void SlotYakuhi_Update(ST_SlotYakuhi* Me, int Yak, int Out) {
	int iLog, YakLog, OutLog;

	/* 役物作動中フラグを、0,又は1の値に変換する。 */
	if(Yak) { Yak = 1; }
	/* 払出枚数が0〜15の範囲であることを確認する。 */
	if((unsigned)Out > 15) { DIE(); }
	/* 全払出枚数に、今回の払出枚数を足す。 */
	Me->AllOut += Out;
	/* 今回役物作動中ならば、役物作動中払出枚数にも、今回の払出枚数を足す。 */
	if(Yak) { Me->YakOut += Out; }
	/* 6000ゲーム前の役物作動中フラグ,及び,払出枚数が格納されている、レコードインデクス(0〜5999)を求める。 */
	iLog = Me->GameCount % 6000;
	/* 6000ゲーム前の役物作動中フラグ,及び,払出枚数を取得する。 */
	YakLog = (Me->YakLog[iLog>>3] >> ((iLog&7)   )) &  1;
	OutLog = (Me->OutLog[iLog>>1] >> ((iLog&1)<<2)) & 15;
	/* ログに、今回の役物作動中フラグ,及び,払出枚数を格納する。 */
	Me->YakLog[iLog>>3] = (Me->YakLog[iLog>>3] & ~( 1 << ((iLog&7)   ))) | (Yak << ((iLog&7)   ));
	Me->OutLog[iLog>>1] = (Me->OutLog[iLog>>1] & ~(15 << ((iLog&1)<<2))) | (Out << ((iLog&1)<<2));
	/* 全払出枚数から、6000ゲーム前の払出枚数を引く。 */
	Me->AllOut -= OutLog;
	/* 6000ゲーム前が役物作動中ならば、役物作動中払出枚数からも、6000ゲーム前の払出枚数を引く。 */
	if(YakLog) { Me->YakOut -= OutLog; }
	/* 経過ゲーム数を進める。オーバーフローしたら、エラー停止とする。 */
	if(++Me->GameCount == 0) { DIE(); }
	/* 6000ゲーム以上経過している場合のみ、6000ゲーム間の役比を算出可能である。 */
	if(Me->GameCount >= 6000) {
		/* 役比[%]＝役物作動中払出枚数[枚]÷全払出枚数[枚]×100 である。
		 * - ただし、6000ゲーム間の全払出枚数が0の場合のみ、役比＝役物作動中払出枚数×100 とする。
		 *   6000ゲーム間、全てはずれ,又は,再遊技が当選した場合に、全払出枚数が0となることがあり得る。
		 */
		Me->Yakuhi = (double)Me->YakOut * 100.0;
		if(Me->AllOut != 0) { Me->Yakuhi /= Me->AllOut; }
	} else {
		/* 6000ゲーム以上経過するまでは、6000ゲーム間の役比を、初期値(0.0)のまま維持する。 */
	}
}

/****************************************************************************
 *	テンパイ判定
 ****************************************************************************/

#ifndef PIECE
int Slot_CheckTenpai(const unsigned char aStopPict[3/*上中下*/][3/*左中右*/], int iPictLCR) {
	int iTenpaiLineMask = 0;
	int iMask, iRow, iPictL, iPictC, iPictR, iStopPictL, iStopPictC, iStopPictR;

	/* 同一回胴内に停止と未停止が混在していないことを確認する。(=｢上中下の内一つでも0｣,かつ,｢上中下の内一つでも0以外｣ならばエラー。) */
	if(((aStopPict[0][0]*aStopPict[1][0]*aStopPict[2][0]) == 0) && ((aStopPict[0][0]+aStopPict[1][0]+aStopPict[2][0]) != 0)) { DIE(); }
	if(((aStopPict[0][1]*aStopPict[1][1]*aStopPict[2][1]) == 0) && ((aStopPict[0][1]+aStopPict[1][1]+aStopPict[2][1]) != 0)) { DIE(); }
	if(((aStopPict[0][2]*aStopPict[1][2]*aStopPict[2][2]) == 0) && ((aStopPict[0][2]+aStopPict[1][2]+aStopPict[2][2]) != 0)) { DIE(); }
	/* 絵柄組合せを分解する。(0=Any) */
	iPictL = (iPictLCR>>0) & 15;
	iPictC = (iPictLCR>>4) & 15;
	iPictR = (iPictLCR>>8) & 15;
	/* 各ラインについて… */
	iMask = (1<<4); /* (1<<4)昇斜ライン,(1<<3)降斜ライン,(1<<2)下段ライン,(1<<1)中段ライン,(1<<0)上段ラインの順に判定する */
	iRow = (2/*下*/<< 0)|(1/*中*/<< 2)|(0/*上*/<< 4)| /* 4 昇斜ライン … 以下のdo〜whileの、1ループ目で使用する */
	       (0/*上*/<< 6)|(1/*中*/<< 8)|(2/*下*/<<10)| /* 3 降斜ライン … 以下のdo〜whileの、2ループ目で使用する */
	       (2/*下*/<<12)|(2/*下*/<<14)|(2/*下*/<<16)| /* 2 下段ライン … 以下のdo〜whileの、3ループ目で使用する */
	       (1/*中*/<<18)|(1/*中*/<<20)|(1/*中*/<<22)| /* 1 中段ライン … 以下のdo〜whileの、4ループ目で使用する */
	       (0/*上*/<<24)|(0/*上*/<<26)|(0/*上*/<<28); /* 0 上段ライン … 以下のdo〜whileの、5ループ目で使用する */
	do {
		/* 左中右回胴の停止絵柄を取得する。(0=未停止) */
		iStopPictL = aStopPict[iRow & 3][0/*左*/]; iRow >>= 2;
		iStopPictC = aStopPict[iRow & 3][1/*中*/]; iRow >>= 2;
		iStopPictR = aStopPict[iRow & 3][2/*右*/]; iRow >>= 2;
		/* 一回胴でも「停止済み,かつ,非Anyで、不一致」ならば、このラインでテンパイではない。 */
		if((iPictL && iStopPictL) && (iPictL != iStopPictL)) { continue; }
		if((iPictC && iStopPictC) && (iPictC != iStopPictC)) { continue; }
		if((iPictR && iStopPictR) && (iPictR != iStopPictR)) { continue; }
		/* このラインでテンパイである。テンパイラインのビットマスクに、このラインのビットマスクを追加する。 */
		iTenpaiLineMask |= iMask;
	} while(iMask >>= 1);
	/* テンパイラインのビットマスクを返す。 */
	return iTenpaiLineMask;
}
#else //PIECE
int Slot_CheckTenpai(const unsigned char aStopPict[3/*上中下*/][3/*左中右*/], int iPictLCR);
asm("
		.code
		.align		1
		.global		Slot_CheckTenpai
Slot_CheckTenpai:
		;// %r12 := aStopPict
		;// %r13 := iPictLCR
		ld.ub		%r4,  [%r12]+			;// %r4  := aStopPict[0][0]
		ld.ub		%r5,  [%r12]+			;// %r5  := aStopPict[0][1]
		ld.ub		%r6,  [%r12]+			;// %r6  := aStopPict[0][2]
;//{{容量節約
;//		ld.ub		%r9,  [%r12]+			;// %r9  :=                 aStopPict[1][0]
;//		mltu.h		%r4,  %r9			;// %alr := aStopPict[0][0]*aStopPict[1][0]
;//		ld.w		%r4,  %alr			;// %r4  := aStopPict[0][0]*aStopPict[1][0]
;//		ld.ub		%r9,  [%r12]+			;// %r9  :=                 aStopPict[1][1]
;//		mltu.h		%r5,  %r9			;// %alr := aStopPict[0][1]*aStopPict[1][1]
;//		ld.w		%r5,  %alr			;// %r5  := aStopPict[0][1]*aStopPict[1][1]
;//		ld.ub		%r9,  [%r12]+			;// %r9  :=                 aStopPict[1][2]
;//		mltu.h		%r6,  %r9			;// %alr := aStopPict[0][2]*aStopPict[1][2]
;//		ld.w		%r6,  %alr			;// %r6  := aStopPict[0][2]*aStopPict[1][2]
;//		ld.ub		%r9,  [%r12]+			;// %r9  :=                                 aStopPict[2][0]
;//		mltu.h		%r4,  %r9			;// %alr := aStopPict[0][0]*aStopPict[1][0]*aStopPict[2][0]
;//		ld.w		%r4,  %alr			;// %r4  := aStopPict[0][0]*aStopPict[1][0]*aStopPict[2][0]
;//		ld.ub		%r9,  [%r12]+			;// %r9  :=                                 aStopPict[2][1]
;//		mltu.h		%r5,  %r9			;// %alr := aStopPict[0][1]*aStopPict[1][1]*aStopPict[2][1]
;//		ld.w		%r5,  %alr			;// %r5  := aStopPict[0][1]*aStopPict[1][1]*aStopPict[2][1]
;//		ld.ub		%r9,  [%r12]			;// %r9  :=                                 aStopPict[2][2]
;//		mltu.h		%r6,  %r9			;// %alr := aStopPict[0][2]*aStopPict[1][2]*aStopPict[2][2]
;//		ld.w		%r6,  %alr			;// %r6  := aStopPict[0][2]*aStopPict[1][2]*aStopPict[2][2]
;//↓容量節約
		ld.w		%r7,  2				;// %r7  := i = 2; do {
		 ld.ub		%r9,  [%r12]+			;//   %r9  :=                 aStopPict[1][0]│%r9  :=                                 aStopPict[2][0]
		 mltu.h		%r4,  %r9			;//   %alr := aStopPict[0][0]*aStopPict[1][0]│%alr := aStopPict[0][0]*aStopPict[1][0]*aStopPict[2][0]
		 ld.w		%r4,  %alr			;//   %r4  := aStopPict[0][0]*aStopPict[1][0]│%r4  := aStopPict[0][0]*aStopPict[1][0]*aStopPict[2][0]
		 ld.ub		%r9,  [%r12]+			;//   %r9  :=                 aStopPict[1][1]│%r9  :=                                 aStopPict[2][1]
		 mltu.h		%r5,  %r9			;//   %alr := aStopPict[0][1]*aStopPict[1][1]│%alr := aStopPict[0][1]*aStopPict[1][1]*aStopPict[2][1]
		 ld.w		%r5,  %alr			;//   %r5  := aStopPict[0][1]*aStopPict[1][1]│%r5  := aStopPict[0][1]*aStopPict[1][1]*aStopPict[2][1]
		 ld.ub		%r9,  [%r12]+			;//   %r9  :=                 aStopPict[1][2]│%r9  :=                                 aStopPict[2][2]
		 mltu.h		%r6,  %r9			;//   %alr := aStopPict[0][2]*aStopPict[1][2]│%alr := aStopPict[0][2]*aStopPict[1][2]*aStopPict[2][2]
		 ld.w		%r6,  %alr			;//   %r6  := aStopPict[0][2]*aStopPict[1][2]│%r6  := aStopPict[0][2]*aStopPict[1][2]*aStopPict[2][2]
		 sub		%r7,  1				;//   %r7  := i--
		jrne		-10				;// } while(i)
;//}}容量節約
		sub		%r12, 9				;// %r12 := aStopPict
		ld.ub		%r7,  [%r12]+			;// %r7  := aStopPict[0][0]
		ld.ub		%r10, [%r12]+			;// %r10 := aStopPict[0][1]
		ld.ub		%r11, [%r12]+			;// %r11 := aStopPict[0][2]
		ld.ub		%r9,  [%r12]+			;// %r9  :=                 aStopPict[1][0]
		add		%r7,  %r9			;// %r7  := aStopPict[0][0]+aStopPict[1][0]
		ld.ub		%r9,  [%r12]+			;// %r9  :=                 aStopPict[1][1]
		add		%r10, %r9			;// %r10 := aStopPict[0][1]+aStopPict[1][1]
		ld.ub		%r9,  [%r12]+			;// %r9  :=                 aStopPict[1][2]
		add		%r11, %r9			;// %r11 := aStopPict[0][2]+aStopPict[1][2]
		ld.ub		%r9,  [%r12]+			;// %r9  :=                                 aStopPict[2][0]
		add		%r7,  %r9			;// %r7  := aStopPict[0][0]+aStopPict[1][0]+aStopPict[2][0]
		jreq.d		4				;//     if((aStopPict[0][0]+aStopPict[1][0]+aStopPict[2][0]) != 0) &&
		 ld.w		%r14, %r13			;// %r14 :=           iPictLCR			*delay*		←───────┐
		 cmp		%r4,  0				;//        (aStopPict[0][0]*aStopPict[1][0]*aStopPict[2][0]) == 0)) {		│
		 jreq		Slot_CheckTenpai_DIE		;//        DIE }								│
		ld.ub		%r9,  [%r12]+			;// %r9  :=                                 aStopPict[2][1]			│
		add		%r10, %r9			;// %r10 := aStopPict[0][1]+aStopPict[1][1]+aStopPict[2][1]			│
		jreq.d		4				;//     if((aStopPict[0][1]+aStopPict[1][1]+aStopPict[2][1]) != 0) &&		│
		 ld.w		%r15, %r13			;// %r15 :=           iPictLCR			*delay*		←────────┐
		 cmp		%r5,  0				;//        (aStopPict[0][1]*aStopPict[1][1]*aStopPict[2][1]) == 0)) {		││
		 jreq		Slot_CheckTenpai_DIE		;//        DIE }								││
		ld.ub		%r9,  [%r12]			;// %r9  :=                                 aStopPict[2][2]			││
		add		%r11, %r9			;// %r11 := aStopPict[0][2]+aStopPict[1][2]+aStopPict[2][2]			││
		jreq.d		4				;//     if((aStopPict[0][2]+aStopPict[1][2]+aStopPict[2][2]) != 0) &&		││
		 sub		%r12, 8				;// %r12 := aStopPict				*delay*		←───┐	││
		 cmp		%r6,  0				;//        (aStopPict[0][2]*aStopPict[1][2]*aStopPict[2][2]) == 0)) {	│	││
		 jreq		Slot_CheckTenpai_DIE		;//        DIE }							│	││
;//		sub		%r12, 8				;// %r12 := aStopPict						────┘	││
		;//---------------------------------------------;//										││
;//		ld.w		%r14, %r13			;// %r14 :=           iPictLCR					────────┘│
;//		ld.w		%r15, %r13			;// %r15 :=           iPictLCR					─────────┘
		sra		%r14, 4				;// %r14 :=          (iPictLCR>>4)
		sra		%r15, 8				;// %r15 :=          (iPictLCR>>8)
		and		%r13, 15			;// %r13 := iPictL = (iPictLCR>>0) & 15
		and		%r14, 15			;// %r14 := iPictC = (iPictLCR>>4) & 15
		and		%r15, 15			;// %r15 := iPictR = (iPictLCR>>8) & 15
		ld.w		%r7,  16			;// %r7  := iMask = (1<<4)
		ld.w		%r9,  3				;// %r9  := sizeof aStopPict[0] = 3
		ld.w		%r10, 0				;// %r10 := iTenpaiLineMask = 0
		xld.w		%r11, 0x0056A906		;// %r11 := iRow = (2<<0)|(1<<2)|(0<<4) | (0<<6)|(1<<8)|(2<<10) | (2<<12)|(2<<14)|(2<<16) | (1<<18)|(1<<20)|(1<<22) | (0<<24)|(0<<26)|(0<<28)
		;// %r7  := iMask
		;// %r9  := sizeof aStopPict[0]
		;// %r10 := iTenpaiLineMask
		;// %r11 := iRow
		;// %r12 := aStopPict
		;// %r13 := iPictL
		;// %r14 := iPictC
		;// %r15 := iPictR
Slot_CheckTenpai_LOOP:						;// do {
		ld.w		%r4,  %r11			;//   %r4  := iRowL = iRow
		sra		%r11, 2				;//   %r11 :=         iRow >>= 2
		ld.w		%r5,  %r11			;//   %r5  := iRowC = iRow
		sra		%r11, 2				;//   %r11 :=         iRow >>= 2
		ld.w		%r6,  %r11			;//   %r6  := iRowR = iRow
;//		sra		%r11, 2				;//   %r11 :=         iRow >>= 2				────┐
		cmp		%r13, 0				;//   if(iPictL) {							│
		jreq		10				;//     								│
		 and		%r4,  3				;//     %r4  := iRowL &= 3						│
		 mlt.h		%r4,  %r9			;//     %alr := iRowL *= 3						│
		 ld.w		%r4,  %alr			;//     %r4  :=                        iRowL				│
		 add		%r4,  %r12			;//     %r4  :=              aStopPict[iRowL]				│
		 ld.ub		%r4,  [%r4]			;//     %r4  := iStopPictL = aStopPict[iRowL][0]			│
		 cmp		%r4,  0				;//     if(iStopPictL) {			!INTERLOCK!		│
		 jreq		3				;//       								│
		  cmp		%r13, %r4			;//       if(iPictL != iStopPictL) { continue }				│
		  jrne		Slot_CheckTenpai_NEXT		;//   } }								│
		cmp		%r14, 0				;//   if(iPictC) {							│
		jreq		11				;//     								│
		 and		%r5,  3				;//     %r5  := iRowC &= 3						│
		 mlt.h		%r5,  %r9			;//     %alr := iRowC *= 3						│
		 ld.w		%r5,  %alr			;//     %r5  :=                        iRowC				│
		 add		%r5,  %r12			;//     %r5  :=              aStopPict[iRowC]				│
		 ext		1				;//     								│
		 ld.ub		%r5,  [%r5]			;//     %r5  := iStopPictC = aStopPict[iRowC][1]			│
		 cmp		%r5,  0				;//     if(iStopPictC) {			!INTERLOCK!		│
		 jreq		3				;//       								│
		  cmp		%r14, %r5			;//       if(iPictC != iStopPictC) { continue }				│
		  jrne		Slot_CheckTenpai_NEXT		;//   } }								│
		cmp		%r15, 0				;//   if(iPictR) {							│
		jreq		11				;//     								│
		 and		%r6,  3				;//     %r6  := iRowR &= 3						│
		 mlt.h		%r6,  %r9			;//     %alr := iRowR *= 3						│
		 ld.w		%r6,  %alr			;//     %r6  :=                        iRowR				│
		 add		%r6,  %r12			;//     %r6  :=              aStopPict[iRowR]				│
		 ext		2				;//     								│
		 ld.ub		%r6,  [%r6]			;//     %r6  := iStopPictR = aStopPict[iRowR][2]			│
		 cmp		%r6,  0				;//     if(iStopPictR) {			!INTERLOCK!		│
		 jreq		3				;//       								│
		  cmp		%r15, %r6			;//       if(iPictR != iStopPictR) { continue }				│
		  jrne		Slot_CheckTenpai_NEXT		;//   } }								│
		or		%r10, %r7			;//   %r10 := iTenpaiLineMask |= iMask					│
Slot_CheckTenpai_NEXT:						;//									│
		sra		%r7,  1				;// } while(iMask >>= 1)						│
		jrne.d		Slot_CheckTenpai_LOOP		;//									│
		sra		%r11, 2				;//   %r11 := iRow >>= 2			*delay*		←───┘
		ret
");
static void __attribute__((noreturn,unused)) Slot_CheckTenpai_DIE() { DIE(); }
#endif//PIECE

/****************************************************************************
 *	入賞判定
 ****************************************************************************/

#ifndef PIECE
#if 0
/* 単純な実装。処理内容の意図を把握するには、こちらを参照してください。 */
void Slot_CheckPrize(const unsigned char aStopPict[3/*上中下*/][3/*左中右*/], const unsigned short aHitFlg[/*nHitFlg*/], int nHitFlg, unsigned char aResult[/*上中下降昇*/]) {
	int iHitFlg, iMask, iLine;
	/* 引数nHitFlg(絵柄組合せテーブルの要素数)が、(1〜256)であることを確認する。 */
	if((nHitFlg < 1) || (nHitFlg > 256)) { DIE(); }
	/* 絵柄組合せテーブルの各要素について… */
	for(iHitFlg = 0; iHitFlg < nHitFlg; iHitFlg++) {
		/* この絵柄組合せについて、5ラインの入賞判定を行う。 */
		iMask = Slot_CheckTenpai(aStopPict, aHitFlg[iHitFlg]);
		/* 各ラインについて… */
		for(iLine = 0; iLine < 5; iLine++) {
			/* このラインに入賞していたら、この絵柄組合せ番号を結果配列へ格納する。 */
			if(iMask & (1<<iLine)) { aResult[iLine] = iHitFlg; }
		}
	}
}
#else
/* 最適化した実装。アセンブラ版は、これをベースにアセンブラ化しました。 */
void Slot_CheckPrize(const unsigned char aStopPict[3/*上中下*/][3/*左中右*/], const unsigned short aHitFlg[/*nHitFlg*/], int nHitFlg, unsigned char aResult[/*上中下降昇*/]) {
	/* 引数nHitFlg(絵柄組合せテーブルの要素数)が、(1〜256)であることを確認する。ただし、処理の都合上あらかじめ(-1)しているので、(0〜255)であることを確認する。 */
	if((unsigned)--nHitFlg > 255) { DIE(); } /* 引数不正 */
	/* nHitFlg[31:8]=(絵柄組合せテーブルの残り要素数-1),nHitFlg[7:0]=(絵柄組合せ番号)とする。ループ変数を一つ減らすための工夫である。 */
	nHitFlg <<= 8;
	/* 絵柄組合せテーブルの各要素について… */
	do {
		/* この絵柄組合せについて、5ラインの入賞判定を行う。 */
		int iMask = Slot_CheckTenpai(aStopPict, *aHitFlg++);
		/* 各ラインについて… */
		unsigned char* pResult = aResult; /* 最初のラインに対する、結果配列へのポインタ */
		do {
			/* このラインに入賞していたら、この絵柄組合せ番号を結果配列へ格納する。 */
			if(iMask & 1) { *pResult = nHitFlg; } /* nHitFlg[7:0]=(絵柄組合せ番号) */
			/* 結果配列へのポインタを、次のラインへ進める。 */
			pResult++;
		} while(iMask >>= 1); /* 入賞フラグを次のラインへ進める。1のビットが無くなったら終了する。5ライン入賞無しでも、1ループ回ることになるが、害は無い。 */
	/* nHitFlg[31:8]=(絵柄組合せテーブルの残り要素数-1)を(-1)し,nHitFlg[7:0]=(絵柄組合せ番号)を(+1)する。即ち、nHitFlg[31:0]を(-255)する。 */
	/* - ループ終了条件は、0*未満*ではなく、0*以下*であることに注意せよ。                                                                  */
	/*   呼出時の引数(nHitFlg=256)の場合、最後は(nHitFlg[31:8]:0⇒0,nHitFlg[7:0]:255⇒0)、即ち(nHitFlg[31:0]:255⇒0)で終了するからである。 */
	} while((nHitFlg -= 255) > 0);
}
#endif
#else //PIECE
void Slot_CheckPrize(const unsigned char aStopPict[3/*上中下*/][3/*左中右*/], const unsigned short aHitFlg[/*nHitFlg*/], int nHitFlg, unsigned char aResult[/*上中下降昇*/]);
asm("
		.code
		.align		1
		.global		Slot_CheckPrize
Slot_CheckPrize:
		;// %r12 := aStopPict
		;// %r13 := aHitFlg
		;// %r14 := nHitFlg
		;// %r15 := aResult
		sub		%r14, 1			;// if((unsigned)--nHitFlg > 255) {
		xcmp		%r14, 255		;//   DIE
		jrugt		Slot_CheckPrize_DIE	;// }
		pushn		%r3
		ld.w		%r0, %r12		;// %r0       := aStopPict
		ld.w		%r1, %r13		;// %r1       := aHitFlg
		ld.w		%r2, %r14		;// %r2[31:8] := nHitFlg
		sla		%r2, 8			;// %r2[ 7:0] := iHitFlg = 0
		ld.w		%r3, %r15		;// %r3       := aResult
		;// %r0       := aStopPict
		;// %r1       := aHitFlg
		;// %r2[31:8] := nHitFlg
		;// %r2[ 7:0] := iHitFlg = 0
		;// %r3       := aResult
Slot_CheckPrize_LOOP:					;// do {
		ld.uh		%r13, [%r1]+		;//   %r13 :=                                     *aHitFlg++
		xcall.d		Slot_CheckTenpai	;//   %r10 := iMask = Slot_CheckTenpai(aStopPict, *aHitFlg++)	iMask[ 0] := 上段, iMask[ 1] := 中段, iMask[ 2] := 下段, iMask[ 3] := 降斜, iMask[ 4] := 昇斜
		ld.w		%r12, %r0		;//   %r12 :=                          aStopPict		*delay*
		swap		%r10, %r10		;//   %r10 := iMask =   swap(iMask)				iMask[24] := 上段, iMask[25] := 中段, iMask[26] := 下段, iMask[27] := 降斜, iMask[28] := 昇斜
		mirror		%r10, %r10		;//   %r10 := iMask = mirror(iMask)				iMask[31] := 上段, iMask[30] := 中段, iMask[29] := 下段, iMask[28] := 降斜, iMask[27] := 昇斜
		ld.w		%r12, %r3		;//   %r12 := pResult = aResult
		add		%r10, %r10		;//   do {
		 jruge		2			;//     %psr(C) := iMask[31], %r10 := iMask <<= 1
		  ld.b		[%r12], %r2		;//     if(%psr(C)) { *pResult = iHitFlg }
		jrne.d		-3			;//   } while(iMask)
		add		%r12, 1			;//   %r12 := pResult++						*delay*
		xsub		%r2, %r2, 255		;//   %r2[31:8] := nHitFlg--, %r2[7:0] := iHitFlg++
		jrgt		Slot_CheckPrize_LOOP	;// } while(((nHitFlg<<8)|iHitFlg) > 0)				呼出時の引数(nHitFlg=256)の場合、最後は(nHitFlg:0⇒0,iHitFlg:255⇒0)、即ち(%r2:255⇒0)で終了する。容量節約前と判断条件が違うことに注意せよ。jrgeでなくjrgtである。
		popn		%r3
		ret
");
static void __attribute__((noreturn,unused)) Slot_CheckPrize_DIE() { DIE(); }
#endif//PIECE

/****************************************************************************
 *	リール配列
 ****************************************************************************/

#ifndef PIECE
int Slot_GetReelPict(const unsigned short aReel[/*21*/], int iPos, int iReel) {
	int iPict;
	/* 回胴番号が(0〜2)の範囲であることを確認する。 */
	if((unsigned)iReel > 2) { DIE(); }
	/* 絵柄位置が(0〜20)の範囲外ならば、(0〜20)の範囲に折り返す。 */
	if((iPos %= 21) < 0) { iPos += 21; }
	/* リール配列の、絵柄位置の要素の、回胴番号の絵柄を取得する。 */
	iPict = (aReel[iPos] >> (iReel << 2)) & 15;
	if(!iPict) { DIE(); }
	return iPict;
}
#else //PIECE
int Slot_GetReelPict(const unsigned short aReel[/*21*/], int iPos, int iReel);
asm("
		.code
		.align		1
		.global		Slot_GetReelPict
Slot_GetReelPict:
		cmp		%r14, 2				;// if((unsigned)iReel > 2) {
		jrugt		Slot_GetReelPict_DIE		;//   DIE() }
		ld.w		%r15, %r12			;// %r15 := aReel
		ld.w		%r12, %r13			;// %r12 := iPos
		xcall.d		__modsi3			;// %r10 := iPos %= 21
		ld.w		%r13, 21			;// %r13 :=         21		*delay*
		add		%r10, %r10			;// %r10 := iPos *= sizeof aReel[0]
		jrge.d		3				;// if(iPos < 0) {
		 sla		%r14, 2				;// %r14 := iReel *= 4		*delay*
		 add		%r10, 42			;//   %r10 := iPos += (21 * sizeof aReel[0]) }
		add		%r10, %r15			;// %r10 := iPict =  aReel += iPos
		ld.uh		%r10, [%r10]			;// %r10 := iPict = *aReel
		sra		%r10, %r14			;// %r10 := iPict >>= iReel	!INTERLOCK!
		and		%r10, 15			;// %r10 := iPict &= 15
		jreq		Slot_GetReelPict_DIE		;// if(!iPict) { DIE() }
		ret						;// return  iPict
");
static void __attribute__((noreturn,unused)) Slot_GetReelPict_DIE() { DIE(); }
#endif//PIECE

//■メモ
//リール配列データのビット12〜15は不定値で構わないので、アプリケーションが他の用途に利用して構わない。
//実際のところ、有効な利用方法は無いだろう。実質、これらのビットは無駄である。
//そこで、絵柄位置3行を2バイトにパックする案も考えてみた。実装例は下記の通り:
//□実装例
//│	int Slot_GetReelPict_Packed(const unsigned char aReel[/*32*/], int iPos, int iReel) {
//│		int i, iPict;
//│		/* 回胴番号が(0〜2)の範囲であることを確認する。 */
//│		if((unsigned)iReel > 2) { DIE(); }
//│		/* 絵柄位置が(0〜20)の範囲外ならば、(0〜20)の範囲に折り返す。 */
//│		if((iPos %= 21) < 0) { iPos += 21; }
//│		/* 絵柄位置と回胴番号から、リール配列へのニブル単位のインデクスを求める。 */
//│		i = (iPos * 3) + iReel;
//│		/* リール配列の、絵柄位置の要素の、回胴番号の絵柄を取得する。 */
//│		iPict = (aReel[i>>1] >> ((i&1)<<2)) & 15;
//│		if(!iPict) { DIE(); }
//│		return iPict;
//│	}
//│	#else //PIECE
//│	int Slot_GetReelPict_Packed(const unsigned char aReel[/*21*/], int iPos, int iReel);
//│	asm("
//│			.code
//│			.align		1
//│			.global		Slot_GetReelPict_Packed
//│	Slot_GetReelPict_Packed:
//│			cmp		%r14, 2				;// if((unsigned)iReel > 2) {
//│			jrugt		Slot_GetReelPict_Packed_DIE	;//   DIE() }
//│			ld.w		%r15, %r12			;// %r15 := aReel
//│			ld.w		%r12, %r13			;// %r12 := iPos
//│			xcall.d		__modsi3			;// %r10 := iPos %= 21
//│			ld.w		%r13, 21			;// %r13 :=         21		*delay*
//│			ld.w		%r12, %r10			;// %r12 := iPos
//│			add		%r10, %r10			;// %r10 := iPos * 2
//│			jrge.d		3				;// if(iPos < 0) {
//│			 add		%r10, %r12			;// %r10 := iPos * 3		*delay*
//│			 add		%r10, 63			;//   iPos += 21 * 3 }
//│			add		%r10, %r14			;// %r10 := i = iPos + iReel
//│			ld.w		%r14, %r10			;// %r14 := i
//│			sra		%r10, 1				;// %r10 :=               i>>1
//│			add		%r10, %r15			;// %r10 :=        &aReel[i>>1]
//│			ld.ub		%r10, [%r10]			;// %r10 := iPict = aReel[i>>1]
//│			and		%r14, 1				;// %r14 :=            i&1
//│			sla		%r14, 2				;// %r14 :=           (i&1)*4
//│			sra		%r10, %r14			;// %r10 := iPict >>= (i&1)*4
//│			and		%r10, 15			;// %r10 := iPict &= 15
//│			jreq		Slot_GetReelPict_Packed_DIE	;// if(!iPict) { DIE() }
//│			ret						;// return  iPict
//│	");
//│	static void __attribute__((noreturn,unused)) Slot_GetReelPict_Packed_DIE() { DIE(); }
//│	#endif//PIECE
//│上記のバージョンを使うと、リール配列データに無駄なビットが生じない。
//│しかし、計算してみると、リール配列データの減少分よりも、コードサイズの増加分の方が多かった。
//│・ﾃﾞｰﾀｻｲｽﾞ: 42⇒32 10ﾊﾞｲﾄ減
//│・ｺｰﾄﾞｻｲｽﾞ: 17⇒23 12ﾊﾞｲﾄ増
//│というわけで、上記のバージョンは利点が無かったので、採用しない。一応、記録までに残しておく。

/****************************************************************************
 *	ライン
 ****************************************************************************/

#ifndef PIECE
int Slot_GetLineRow(int iLine, int iReel) {
	if(((unsigned)iLine > 4) || ((unsigned)iReel > 2)) { DIE(); }
	if(iLine <= 2) { return iLine; } /* T,M,B */
	if(iLine == 3) { return iReel; } /* F */
	return 2 - iReel;                /* Z */
}
#else //PIECE
int Slot_GetLineRow(int iLine, int iReel);
asm("
		.code
		.align		1
		.global		Slot_GetLineRow
Slot_GetLineRow:
		cmp		%r12, 4			;// if(((unsigned)iLine > 4) { DIE }
		jrugt		Slot_GetLineRow_DIE
		cmp		%r13, 2			;// if(((unsigned)iCol  > 2) { DIE }
		jrugt		Slot_GetLineRow_DIE
		cmp		%r12, 3			;// if(iLine <= 2) { return iLine }
		jrlt		5
		 ld.w		%r12, %r13		;// if(iLine == 3) { return iCol }
		 jreq		3
		  ld.w		%r12, 2			;// return 2 - iCol
		  sub		%r12, %r13
		ret.d
		ld.w		%r10, %r12		;//	*delay*
");
static void __attribute__((noreturn,unused)) Slot_GetLineRow_DIE() { DIE(); }
#endif//PIECE

//□テストスイート
//void TestSuite() {
//  if((Slot_GetLineRow(Slot_Line_T,0)!=0)||(Slot_GetLineRow(Slot_Line_T,1)!=0)||(Slot_GetLineRow(Slot_Line_T,2)!=0)){DIE();}
//  if((Slot_GetLineRow(Slot_Line_M,0)!=1)||(Slot_GetLineRow(Slot_Line_M,1)!=1)||(Slot_GetLineRow(Slot_Line_M,2)!=1)){DIE();}
//  if((Slot_GetLineRow(Slot_Line_B,0)!=2)||(Slot_GetLineRow(Slot_Line_B,1)!=2)||(Slot_GetLineRow(Slot_Line_B,2)!=2)){DIE();}
//  if((Slot_GetLineRow(Slot_Line_F,0)!=0)||(Slot_GetLineRow(Slot_Line_F,1)!=1)||(Slot_GetLineRow(Slot_Line_F,2)!=2)){DIE();}
//  if((Slot_GetLineRow(Slot_Line_Z,0)!=2)||(Slot_GetLineRow(Slot_Line_Z,1)!=1)||(Slot_GetLineRow(Slot_Line_Z,2)!=0)){DIE();}
//}

/****************************************************************************
 *	押順
 ****************************************************************************/

#ifndef PIECE
int Slot_GetOrderReel(int iOrder, int iStop) {
	if(((unsigned)iOrder > 5) || ((unsigned)iStop > 2)) { DIE(); }
	if((iOrder -= 3) < 0) { iOrder += iStop; }	/* LCR,CRL,RLC */	//(-3〜1)┐
	                 else { iOrder -= iStop; }	/* LRC,CLR,RCL */	//(-2〜2)┴(-3〜2)
	if(iOrder < 0) { iOrder += 3; }						//         ( 0〜2)

	return iOrder;
}
#else //PIECE
int Slot_GetOrderReel(int iOrder, int iStop);
asm("
		.code
		.align		1
		.global		Slot_GetOrderReel
Slot_GetOrderReel:
		cmp		%r12, 5			;// if((unsigned)iOrder > 5) { DIE }
		jrugt		Slot_GetOrderReel_DIE
		cmp		%r13, 2			;// if((unsigned)iStop  > 2) { DIE }
		jrugt		Slot_GetOrderReel_DIE
		sub		%r12, 3			;// %r12 :=   iOrder -= 3
		jrlt.d		4			;// if(iOrder) < 0) {
		add		%r12, %r13		;// %r12 :=   iOrder += iStop } else {	*delay*		%psr(N)=?,%psr(V)=0	────┐この加算でオーバーフローは発生しないので、常に%psr(V)=0となる。
		 sub		%r12, %r13		;//   %r12 := iOrder									│
		 sub		%r12, %r13		;//   %r12 := iOrder -= iStop }				%psr(N)=?,%psr(V)=0	────┤この減算でオーバーフローは発生しないので、常に%psr(V)=0となる。
		jrge		2			;// if(iOrder < 0) {					←───────────────┘jrgeの分岐条件は(N=V)。%psr(V)=0なので、%psr(N)のみで判断する。
		 add		%r12, 3			;//   %r12 := iOrder += 3 }
		ret.d					;// return    iOrder
		ld.w		%r10, %r12		;// %r10   := iOrder			*delay*
");
static void __attribute__((noreturn,unused)) Slot_GetOrderReel_DIE() { DIE(); }
#endif//PIECE

//□テストスイート
//void TestSuite() {
//  if((Slot_GetOrderReel(Slot_Order_LCR,0)!=0)||(Slot_GetOrderReel(Slot_Order_LCR,1)!=1)||(Slot_GetOrderReel(Slot_Order_LCR,2)!=2)){DIE();}
//  if((Slot_GetOrderReel(Slot_Order_CRL,0)!=1)||(Slot_GetOrderReel(Slot_Order_CRL,1)!=2)||(Slot_GetOrderReel(Slot_Order_CRL,2)!=0)){DIE();}
//  if((Slot_GetOrderReel(Slot_Order_RLC,0)!=2)||(Slot_GetOrderReel(Slot_Order_RLC,1)!=0)||(Slot_GetOrderReel(Slot_Order_RLC,2)!=1)){DIE();}
//  if((Slot_GetOrderReel(Slot_Order_LRC,0)!=0)||(Slot_GetOrderReel(Slot_Order_LRC,1)!=2)||(Slot_GetOrderReel(Slot_Order_LRC,2)!=1)){DIE();}
//  if((Slot_GetOrderReel(Slot_Order_CLR,0)!=1)||(Slot_GetOrderReel(Slot_Order_CLR,1)!=0)||(Slot_GetOrderReel(Slot_Order_CLR,2)!=2)){DIE();}
//  if((Slot_GetOrderReel(Slot_Order_RCL,0)!=2)||(Slot_GetOrderReel(Slot_Order_RCL,1)!=1)||(Slot_GetOrderReel(Slot_Order_RCL,2)!=0)){DIE();}
//}

/*--------------------------------------------------------------------------*/

#ifndef PIECE
int Slot_FindOrder(int iReel1, int iReel2) {
	if(((unsigned)iReel1 > 2) || ((unsigned)iReel2 > 2) || (iReel1 == iReel2)) { DIE(); }
	if((iReel2 -= iReel1) < 0) { iReel2 += 3; }	//iReel2=1,2
	if(iReel2 != 1) { iReel1 += 3; }		//iReel1=0~5
	return iReel1;
}
#else //PIECE
int Slot_FindOrder(int iReel1, int iReel2);
asm("
		.code
		.align		1
		.global		Slot_FindOrder
Slot_FindOrder:
		cmp		%r12, 2			;// if((unsigned)iReel1 > 2) { DIE }
		jrugt		Slot_FindOrder_DIE
		cmp		%r13, 2			;// if((unsigned)iReel2 > 2) { DIE }
		jrugt		Slot_FindOrder_DIE
		sub		%r13, %r12		;// %r13 := iReel2 -= iReel1
		jrgt		3			;// if(  iReel2 <= 0) {
		 jreq		Slot_FindOrder_DIE	;//   if(iReel2 == 0) { DIE }
		 add		%r13, 3			;//   %r13 := iReel2 += 3 }
		cmp		%r13, 1			;// if(iReel2 != 1) {
		jreq		2
		 add		%r12, 3			;//   %r12 := iReel1 += 3 }
		ret.d					;// return  iReel1
		ld.w		%r10, %r12		;// %r10 := iReel1		*delay*
");
static void __attribute__((noreturn,unused)) Slot_FindOrder_DIE() { DIE(); }
#endif//PIECE

//□テストスイート
//void TestSuite() {
//  if(Slot_FindOrder(0,1)!=Slot_Order_LCR){DIE();}
//  if(Slot_FindOrder(1,2)!=Slot_Order_CRL){DIE();}
//  if(Slot_FindOrder(2,0)!=Slot_Order_RLC){DIE();}
//  if(Slot_FindOrder(0,2)!=Slot_Order_LRC){DIE();}
//  if(Slot_FindOrder(1,0)!=Slot_Order_CLR){DIE();}
//  if(Slot_FindOrder(2,1)!=Slot_Order_RCL){DIE();}
//}

/****************************************************************************
 *	停止制御
 ****************************************************************************/

/*--------------------------------------------------------------------------*
 *	1リール停止制御
 *--------------------------------------------------------------------------*/

/* 引込セット1番号(iHkmSet1)の、押下位置1が(iPushPos1)の、引込駒数を取得する。
 * [in]
 *	pStpCtl		停止制御データ
 *	iHkmSet1	引込セット1番号		0〜(HkmSet1_Size-1)
 *	iPushPos1	押下位置1		0〜20
 * [out]
 *	戻り値		引込駒数		0〜4
 * [note]
 *	- 引込セット1とは、(引込駒数×押下位置1)の組合せを、重複無く登録したものです。
 */
static int GetHkmSet1(const ST_Slot_StpCtl* pStpCtl, int iHkmSet1, int iPushPos1) {
	unsigned char (*Buf/*[HkmSet1_CompUnit]*/)[21 / 3] = alloca(pStpCtl->HkmSet1_CompUnit * (21 / 3));
	int nHkmCnt, iCompData, iCompSize, nUncompSize;
	if((unsigned)iHkmSet1 >= pStpCtl->HkmSet1_Size) { DIE(); }
	if((unsigned)iPushPos1 > 20) { DIE(); }
	iCompData = 0;
	for(iCompSize = 0;
	    iCompSize < (iHkmSet1 / pStpCtl->HkmSet1_CompUnit);
	    iCompSize++) {
		iCompData += pStpCtl->TBL_HkmSet1_CompSize[iCompSize];
	}
	if((unsigned)iCompData >= pStpCtl->HkmSet1_CompData_Size) { DIE(); }
	nUncompSize = TinyLZ_uncompress(
		Buf, pStpCtl->HkmSet1_CompUnit * 21,
		&pStpCtl->TBL_HkmSet1_CompData[iCompData],
		 pStpCtl->TBL_HkmSet1_CompSize[iCompSize]);
	if(((nUncompSize % (21 / 3)) != 0) ||
	   ((nUncompSize / (21 / 3)) < (iHkmSet1 % pStpCtl->HkmSet1_CompUnit))) { DIE(); }
	nHkmCnt = Buf[iHkmSet1 % pStpCtl->HkmSet1_CompUnit][iPushPos1 / 3];
	switch(iPushPos1 % 3) {
	case 0: nHkmCnt = nHkmCnt      % 6; break;
	case 1: nHkmCnt = nHkmCnt /  6 % 6; break;
	case 2: nHkmCnt = nHkmCnt / 36    ; break;
	default: DIE();
	}
	if((unsigned)nHkmCnt > 4) { DIE(); }
	return nHkmCnt;
}

/*--------------------------------------------------------------------------*/

int Slot_GetStpCtl1(const ST_Slot_StpCtl* pStpCtl, int iHitCd, int iReel1, int iPushPos1) {
	int iHkmSet1;
	if((unsigned)iHitCd >= pStpCtl->HitCd_Size) { DIE(); }
	if((unsigned)iReel1 > 2) { DIE(); }
	if((unsigned)iPushPos1 > 20) { DIE(); }
	iHkmSet1 = pStpCtl->TBL_StpCtl1[iHitCd][iReel1];
	return GetHkmSet1(pStpCtl, iHkmSet1, iPushPos1);
}

/*--------------------------------------------------------------------------*
 *	2リール停止制御
 *--------------------------------------------------------------------------*/

/* 引込セット2番号(iHkmSet2)の、停止位置1が(iStopPos1),押下位置2が(iPushPos2)の、引込駒数を取得する。
 * [in]
 *	pStpCtl		停止制御データ
 *	iHkmSet2	引込セット2番号		0〜(HkmSet2_Size-1)
 *	iStopPos1	停止位置1		0〜20
 *	iPushPos2	押下位置2		0〜20
 * [out]
 *	戻り値		引込駒数		0〜4
 * [note]
 *	- 引込セット2とは、(引込セット1番号×停止位置1)の組合せを、重複無く登録したものです。
 *	- 引込セット2データは、(HkmSet2_CompUnit)個単位で、圧縮されています。
 */
static int GetHkmSet2(const ST_Slot_StpCtl* pStpCtl, int iHkmSet2, int iStopPos1, int iPushPos2) {
	unsigned char (*Buf/*[HkmSet2_CompUnit]*/)[21] = alloca(pStpCtl->HkmSet2_CompUnit * 21);
	int iHkmSet1, iCompData, iCompSize, nUncompSize;
	if((unsigned)iHkmSet2 >= pStpCtl->HkmSet2_Size) { DIE(); }
	if((unsigned)iStopPos1 > 20) { DIE(); }
	if((unsigned)iPushPos2 > 20) { DIE(); }
	iCompData = 0;
	for(iCompSize = 0;
	    iCompSize < (iHkmSet2 / pStpCtl->HkmSet2_CompUnit);
	    iCompSize++) {
		iCompData += pStpCtl->TBL_HkmSet2_CompSize[iCompSize];
	}
	if((unsigned)iCompData >= pStpCtl->HkmSet2_CompData_Size) { DIE(); }
	nUncompSize = TinyLZ_uncompress(
		Buf, pStpCtl->HkmSet2_CompUnit * 21,
		&pStpCtl->TBL_HkmSet2_CompData[iCompData],
		 pStpCtl->TBL_HkmSet2_CompSize[iCompSize]);
	if(((nUncompSize % 21) != 0) ||
	   ((nUncompSize / 21) < (iHkmSet2 % pStpCtl->HkmSet2_CompUnit))) { DIE(); }
	iHkmSet1 = Buf[iHkmSet2 % pStpCtl->HkmSet2_CompUnit][iStopPos1];
	return GetHkmSet1(pStpCtl, iHkmSet1, iPushPos2);
}

/*--------------------------------------------------------------------------*/

int Slot_GetStpCtl2(const ST_Slot_StpCtl* pStpCtl, int iHitCd, int iReel1, int iReel2, int iStopPos1, int iPushPos2) {
	int iHkmSet2, iOrder;
	if((unsigned)iHitCd >= pStpCtl->HitCd_Size) { DIE(); }
	if((unsigned)iReel1 > 2) { DIE(); }
	if((unsigned)iReel2 > 2) { DIE(); }
	if((unsigned)iStopPos1 > 20) { DIE(); }
	if((unsigned)iPushPos2 > 20) { DIE(); }
	iOrder = Slot_FindOrder(iReel1, iReel2);
	iHkmSet2 = pStpCtl->TBL_StpCtl2[iHitCd][iOrder];
	return GetHkmSet2(pStpCtl, iHkmSet2, iStopPos1, iPushPos2);
}

/*--------------------------------------------------------------------------*
 *	3リール停止制御
 *--------------------------------------------------------------------------*/

/* 引込セット3番号(iHkmSet3)の、停止位置1が(iStopPos1),停止位置2が(iStopPos2),押下位置3が(iPushPos3)の、引込駒数を取得する。
 * [in]
 *	pStpCtl		停止制御データ
 *	iHkmSet3	引込セット3番号		0〜(HkmSet3_Size-1)
 *	iStopPos1	停止位置1		0〜20
 *	iStopPos2	停止位置2		0〜20
 *	iPushPos3	押下位置3		0〜20
 * [out]
 *	戻り値		引込駒数		0〜4
 * [note]
 *	- 引込セット3とは、(引込セット2番号×停止位置1)の組合せを、重複無く登録したものです。
 *	- 引込セット3データは、(HkmSet3_CompUnit)個単位で、圧縮されています。
 */
static int GetHkmSet3(const ST_Slot_StpCtl* pStpCtl, int iHkmSet3, int iStopPos1, int iStopPos2, int iPushPos3) {
	unsigned char (*Buf/*[HkmSet3_CompUnit]*/)[21] = alloca(pStpCtl->HkmSet3_CompUnit * 21);
	int iHkmSet2, iCompData, iCompSize, nUncompSize;
	if((unsigned)iHkmSet3 >= pStpCtl->HkmSet3_Size) { DIE(); }
	if((unsigned)iStopPos1 > 20) { DIE(); }
	if((unsigned)iStopPos2 > 20) { DIE(); }
	if((unsigned)iPushPos3 > 20) { DIE(); }
	iCompData = 0;
	for(iCompSize = 0;
	    iCompSize < (iHkmSet3 / pStpCtl->HkmSet3_CompUnit);
	    iCompSize++) {
		iCompData += pStpCtl->TBL_HkmSet3_CompSize[iCompSize];
	}
	if((unsigned)iCompData >= pStpCtl->HkmSet3_CompData_Size) { DIE(); }
	nUncompSize = TinyLZ_uncompress(
		Buf, pStpCtl->HkmSet3_CompUnit * 21,
		&pStpCtl->TBL_HkmSet3_CompData[iCompData],
		 pStpCtl->TBL_HkmSet3_CompSize[iCompSize]);
	if(((nUncompSize % 21) != 0) ||
	   ((nUncompSize / 21) < (iHkmSet3 % pStpCtl->HkmSet3_CompUnit))) { DIE(); }
	iHkmSet2 = Buf[iHkmSet3 % pStpCtl->HkmSet3_CompUnit][iStopPos1];
	return GetHkmSet2(pStpCtl, iHkmSet2, iStopPos2, iPushPos3);
}

/*--------------------------------------------------------------------------*/

int Slot_GetStpCtl3(const ST_Slot_StpCtl* pStpCtl, int iHitCd, int iReel1, int iReel2, int iReel3, int iStopPos1, int iStopPos2, int iPushPos3) {
	int iHkmSet3, iOrder;
	if((unsigned)iHitCd >= pStpCtl->HitCd_Size) { DIE(); }
	if((unsigned)iReel1 > 2) { DIE(); }
	if((unsigned)iReel2 > 2) { DIE(); }
	if((unsigned)iReel3 > 2) { DIE(); }
	if((unsigned)iStopPos1 > 20) { DIE(); }
	if((unsigned)iStopPos2 > 20) { DIE(); }
	if((unsigned)iPushPos3 > 20) { DIE(); }
	iOrder = Slot_FindOrder(iReel1, iReel2);
	iHkmSet3 = pStpCtl->TBL_StpCtl3[iHitCd][iOrder];
	return GetHkmSet3(pStpCtl, iHkmSet3, iStopPos1, iStopPos2, iPushPos3);
}

/****************************************************************************
 *	停止制御データビルダ
 ****************************************************************************/
#ifdef  WIN32	//PC上で停止制御データを作成する時に使用します。P/ECE上では使用しません。
/* 停止制御データビルダ */
typedef struct _ST_Slot_StpCtl_Builder {
	unsigned short HkmSet1_Size;
	unsigned short HkmSet2_Size;
	unsigned short HkmSet3_Size;
	unsigned short HkmSet1_CompData_Size;
	unsigned short HkmSet2_CompData_Size;
	unsigned short HkmSet3_CompData_Size;
	unsigned char (*TBL_StpCtl1/*[HitCd_Size]*/)[3]/*[21]*/;		//                                                                                          ⇒TBL_HkmSet1
	unsigned char (*TBL_StpCtl2/*[HitCd_Size]*/)[6]/*[21][21]*/;		//                                             ⇒(TBL_HkmSet2_CompSize,TBL_HkmSet2_CompData)⇒TBL_HkmSet1
	unsigned char (*TBL_StpCtl3/*[HitCd_Size]*/)[6]/*[21][21][21]*/;	//⇒(TBL_HkmSet3_CompSize,TBL_HkmSet3_CompData)⇒(TBL_HkmSet2_CompSize,TBL_HkmSet2_CompData)⇒TBL_HkmSet1
	unsigned char TBL_HkmSet1[256/*HkmSet1_Sizeの上限*/][21];
	unsigned char TBL_HkmSet2[256/*HkmSet2_Sizeの上限*/][21];
	unsigned char TBL_HkmSet3[256/*HkmSet3_Sizeの上限*/][21];
	unsigned char TBL_HkmSet1_CompSize[ 256/*充分なサイズ*/];
	unsigned char TBL_HkmSet2_CompSize[ 256/*充分なサイズ*/];
	unsigned char TBL_HkmSet3_CompSize[ 256/*充分なサイズ*/];
	unsigned char TBL_HkmSet1_CompData[8192/*充分なサイズ*/];
	unsigned char TBL_HkmSet2_CompData[8192/*充分なサイズ*/];
	unsigned char TBL_HkmSet3_CompData[8192/*充分なサイズ*/];
	unsigned char (*TBL_StpFlg1/*[HitCd_Size]*/)[/*iPos1*/21];		//1リール停止フラグ。条件装置が(HitCd_Size)で、押順が(bit0-5に対応)の時に、第1停止リールが(iPos1)に停止し得るかを示す。
	unsigned char (*TBL_StpFlg2/*[HitCd_Size]*/)[/*iPos1*/21][/*iPos2*/21];	//2リール停止フラグ。条件装置が(HitCd_Size)で、押順が(bit0-5に対応)の時に、第1停止リールが(iPos1),第2停止リールが(iPos2)に停止し得るかを示す。
	unsigned char TBL_HkmSet1_Pack[256/*HkmSet1_Sizeの上限*/][21 / 3];
} ST_Slot_StpCtl_Builder;
/*--------------------------------------------------------------------------*/
static int memcmp21(const void* x, const void* y) { return memcmp(x, y, 21); }
/*--------------------------------------------------------------------------*/
/* 引込セット1を重複無く登録する */
static int UnionHkmSet1(ST_Slot_StpCtl_Builder* pBuilder, const unsigned char aHkmCnt[21]) {
	int iHkmSet1;
	for(iHkmSet1 = 0; iHkmSet1 < pBuilder->HkmSet1_Size; iHkmSet1++) {
		if(!memcmp21(pBuilder->TBL_HkmSet1[iHkmSet1], aHkmCnt)) { return iHkmSet1; }
	}
	if(pBuilder->HkmSet1_Size >= ARRAY_SIZE(pBuilder->TBL_HkmSet1)) { DIE(); }
	memcpy(pBuilder->TBL_HkmSet1[pBuilder->HkmSet1_Size], aHkmCnt, 21);
	return pBuilder->HkmSet1_Size++;
}
/*--------------------------------------------------------------------------*/
/* 引込セット2を重複無く登録する */
static int UnionHkmSet2(ST_Slot_StpCtl_Builder* pBuilder, const unsigned char aHkmSet1[21]) {
	int iHkmSet2;
	for(iHkmSet2 = 0; iHkmSet2 < pBuilder->HkmSet2_Size; iHkmSet2++) {
		if(!memcmp21(pBuilder->TBL_HkmSet2[iHkmSet2], aHkmSet1)) { return iHkmSet2; }
	}
	if(pBuilder->HkmSet2_Size >= ARRAY_SIZE(pBuilder->TBL_HkmSet2)) { DIE(); }
	memcpy(pBuilder->TBL_HkmSet2[pBuilder->HkmSet2_Size], aHkmSet1, 21);
	return pBuilder->HkmSet2_Size++;
}
/*--------------------------------------------------------------------------*/
/* 引込セット3を重複無く登録する */
static int UnionHkmSet3(ST_Slot_StpCtl_Builder* pBuilder, const unsigned char aHkmSet2[21]) {
	int iHkmSet3;
	for(iHkmSet3 = 0; iHkmSet3 < pBuilder->HkmSet3_Size; iHkmSet3++) {
		if(!memcmp21(pBuilder->TBL_HkmSet3[iHkmSet3], aHkmSet2)) { return iHkmSet3; }
	}
	if(pBuilder->HkmSet3_Size >= ARRAY_SIZE(pBuilder->TBL_HkmSet3)) { DIE(); }
	memcpy(pBuilder->TBL_HkmSet3[pBuilder->HkmSet3_Size], aHkmSet2, 21);
	return pBuilder->HkmSet3_Size++;
}
/*--------------------------------------------------------------------------*/
ST_Slot_StpCtl* Slot_BuildStpCtl(const ST_Slot_StpCtl_BuilderInfo* pInfo) {
	ST_Slot_StpCtl* pStpCtl;
	ST_Slot_StpCtl_Builder* pBuilder;
	int iHitCd, iOrder, iReel1, iReel2, iReel3, iPos1, iPos2, iPos3, i, j, n;
	unsigned char aHkmCnt[21], aHkmSet1[21], aHkmSet2[21];
	unsigned char* p;
	/* 圧縮単位を取得する。0が指定された場合、推奨値を使用する。 */
	int HkmSet1_CompUnit = pInfo->HkmSet1_CompUnit ? pInfo->HkmSet1_CompUnit : 16/*推奨値*/;
	int HkmSet2_CompUnit = pInfo->HkmSet2_CompUnit ? pInfo->HkmSet2_CompUnit : 16/*推奨値*/;
	int HkmSet3_CompUnit = pInfo->HkmSet3_CompUnit ? pInfo->HkmSet3_CompUnit : 16/*推奨値*/;
	/* 停止制御データビルダのメモリを確保する。(1個のメモリブロックとして確保する。解放時も1個のメモリブロックとして開放せよ。) */
	p = calloc(1, sizeof(ST_Slot_StpCtl_Builder) +
		(pInfo->HitCd_Size * 3) +	/* TBL_StpCtl1 */
		(pInfo->HitCd_Size * 6) +	/* TBL_StpCtl2 */
		(pInfo->HitCd_Size * 6) +	/* TBL_StpCtl3 */
		(pInfo->HitCd_Size * 21) +	/* TBL_StpFlg1 */
		(pInfo->HitCd_Size * 21 * 21));	/* TBL_StpFlg2 */
	if(!p) { DIE(); }
	pBuilder              = (void*)p;   p += sizeof(ST_Slot_StpCtl_Builder);
	pBuilder->TBL_StpCtl1 = (void*)p;   p += (pInfo->HitCd_Size * 3);
	pBuilder->TBL_StpCtl2 = (void*)p;   p += (pInfo->HitCd_Size * 6);
	pBuilder->TBL_StpCtl3 = (void*)p;   p += (pInfo->HitCd_Size * 6);
	pBuilder->TBL_StpFlg1 = (void*)p;   p += (pInfo->HitCd_Size * 21);
	pBuilder->TBL_StpFlg2 = (void*)p; //p += (pInfo->HitCd_Size * 21 * 21);
	/*--- 引込セット1を重複無く登録する ---*/
	/* 1リール停止制御 */
	for(iHitCd = 0; iHitCd < pInfo->HitCd_Size; iHitCd++) {
		for(iOrder = 0; iOrder < 3; iOrder++) {
			iReel1 = Slot_GetOrderReel(iOrder, 0);		/* 停止中リール */
			for(iPos1 = 0; iPos1 < 21; iPos1++) {
				n = (*pInfo->fnGetStpCtl1)(pInfo->pParam, iHitCd, iReel1, iPos1);
				if((unsigned)n > 4) { DIE(); }
				pBuilder->TBL_StpFlg1[iHitCd][(iPos1 - n + 21) % 21] |= (((1<<0)|(1<<3))<<iOrder);		//1リール停止フラグをセットする。第2停止で可能性の有る2種類の押順に対してセットする。
				aHkmCnt[iPos1] = n;
			}
			UnionHkmSet1(pBuilder, aHkmCnt);			//ソートするまで、引込セット1番号は未確定。ここでは、登録のみ行う。
		}
	}
	/* 2リール停止制御 */
	for(iHitCd = 0; iHitCd < pInfo->HitCd_Size; iHitCd++) {
		for(iOrder = 0; iOrder < 6; iOrder++) {
			iReel1 = Slot_GetOrderReel(iOrder, 0);		/* 停止済リール */
			iReel2 = Slot_GetOrderReel(iOrder, 1);		/* 停止中リール */
			for(iPos1 = 0; iPos1 < 21; iPos1++) {
				for(iPos2 = 0; iPos2 < 21; iPos2++) {
					if(pBuilder->TBL_StpFlg1[iHitCd][iPos1] & (1<<iOrder)) {
						n = (*pInfo->fnGetStpCtl2)(pInfo->pParam, iHitCd, iReel1, iReel2, iPos1, iPos2);
						if((unsigned)n > 4) { DIE(); }
						pBuilder->TBL_StpFlg2[iHitCd][iPos1][(iPos2 - n + 21) % 21] |= (1<<iOrder);	//2リール停止フラグをセットする。
					} else {
						n = 5;
					}
					aHkmCnt[iPos2] = n;
				}
				UnionHkmSet1(pBuilder, aHkmCnt);		//ソートするまで、引込セット1番号は未確定。ここでは、登録のみ行う。
			}
		}
	}
	/* 3リール停止制御 */
	for(iHitCd = 0; iHitCd < pInfo->HitCd_Size; iHitCd++) {
		for(iOrder = 0; iOrder < 6; iOrder++) {
			iReel1 = Slot_GetOrderReel(iOrder, 0);		/* 停止済リール1 */
			iReel2 = Slot_GetOrderReel(iOrder, 1);		/* 停止済リール2 */
			iReel3 = Slot_GetOrderReel(iOrder, 2);		/* 停止中リール  */
			for(iPos1 = 0; iPos1 < 21; iPos1++) {
				for(iPos2 = 0; iPos2 < 21; iPos2++) {
					for(iPos3 = 0; iPos3 < 21; iPos3++) {
						if(pBuilder->TBL_StpFlg2[iHitCd][iPos1][iPos2] & (1<<iOrder)) {
							n = (*pInfo->fnGetStpCtl3)(pInfo->pParam, iHitCd, iReel1, iReel2, iReel3, iPos1, iPos2, iPos3);
							if((unsigned)n > 4) { DIE(); }
						} else {
							n = 5;
						}
						aHkmCnt[iPos3] = n;
					}
					UnionHkmSet1(pBuilder, aHkmCnt);	//ソートするまで、引込セット1番号は未確定。ここでは、登録のみ行う。
				}
			}
		}
	}
	/* 引込セット1をソートする。ソートすると、圧縮率が多少良くなる。 */
	qsort(pBuilder->TBL_HkmSet1, pBuilder->HkmSet1_Size, 21, memcmp21);	//これで、引込セット1番号が確定する。
	/*--- 引込セット2を重複無く登録する ---*/
	/* 2リール停止制御 */
	for(iHitCd = 0; iHitCd < pInfo->HitCd_Size; iHitCd++) {
		for(iOrder = 0; iOrder < 6; iOrder++) {
			iReel1 = Slot_GetOrderReel(iOrder, 0);		/* 停止済リール */
			iReel2 = Slot_GetOrderReel(iOrder, 1);		/* 停止中リール */
			for(iPos1 = 0; iPos1 < 21; iPos1++) {
				for(iPos2 = 0; iPos2 < 21; iPos2++) {
					if(pBuilder->TBL_StpFlg1[iHitCd][iPos1] & (1<<iOrder)) {
						n = (*pInfo->fnGetStpCtl2)(pInfo->pParam, iHitCd, iReel1, iReel2, iPos1, iPos2);
						if((unsigned)n > 4) { DIE(); }
					} else {
						n = 5;
					}
					aHkmCnt[iPos2] = n;
				}
				aHkmSet1[iPos1] = UnionHkmSet1(pBuilder, aHkmCnt);
			}
			UnionHkmSet2(pBuilder, aHkmSet1);			//ソートするまで、引込セット2番号は未確定。ここでは、登録のみ行う。
		}
	}
	/* 3リール停止制御 */
	for(iHitCd = 0; iHitCd < pInfo->HitCd_Size; iHitCd++) {
		for(iOrder = 0; iOrder < 6; iOrder++) {
			iReel1 = Slot_GetOrderReel(iOrder, 0);		/* 停止済リール1 */
			iReel2 = Slot_GetOrderReel(iOrder, 1);		/* 停止済リール2 */
			iReel3 = Slot_GetOrderReel(iOrder, 2);		/* 停止中リール  */
			for(iPos1 = 0; iPos1 < 21; iPos1++) {
				for(iPos2 = 0; iPos2 < 21; iPos2++) {
					for(iPos3 = 0; iPos3 < 21; iPos3++) {
						if(pBuilder->TBL_StpFlg2[iHitCd][iPos1][iPos2] & (1<<iOrder)) {
							n = (*pInfo->fnGetStpCtl3)(pInfo->pParam, iHitCd, iReel1, iReel2, iReel3, iPos1, iPos2, iPos3);
							if((unsigned)n > 4) { DIE(); }
						} else {
							n = 5;
						}
						aHkmCnt[iPos3] = n;
					}
					aHkmSet1[iPos2] = UnionHkmSet1(pBuilder, aHkmCnt);
				}
				UnionHkmSet2(pBuilder, aHkmSet1);		//ソートするまで、引込セット2番号は未確定。ここでは、登録のみ行う。
			}
		}
	}
	/* 引込セット2をソートする。ソートすると、圧縮率が多少良くなる。 */
	qsort(pBuilder->TBL_HkmSet2, pBuilder->HkmSet2_Size, 21, memcmp21);	//これで、引込セット2番号が確定する。
	/*--- 引込セット3を重複無く登録する ---*/
	/* 3リール停止制御 */
	for(iHitCd = 0; iHitCd < pInfo->HitCd_Size; iHitCd++) {
		for(iOrder = 0; iOrder < 6; iOrder++) {
			iReel1 = Slot_GetOrderReel(iOrder, 0);		/* 停止済リール1 */
			iReel2 = Slot_GetOrderReel(iOrder, 1);		/* 停止済リール2 */
			iReel3 = Slot_GetOrderReel(iOrder, 2);		/* 停止中リール  */
			for(iPos1 = 0; iPos1 < 21; iPos1++) {
				for(iPos2 = 0; iPos2 < 21; iPos2++) {
					for(iPos3 = 0; iPos3 < 21; iPos3++) {
						if(pBuilder->TBL_StpFlg2[iHitCd][iPos1][iPos2] & (1<<iOrder)) {
							n = (*pInfo->fnGetStpCtl3)(pInfo->pParam, iHitCd, iReel1, iReel2, iReel3, iPos1, iPos2, iPos3);
							if((unsigned)n > 4) { DIE(); }
						} else {
							n = 5;
						}
						aHkmCnt[iPos3] = n;
					}
					aHkmSet1[iPos2] = UnionHkmSet1(pBuilder, aHkmCnt);
				}
				aHkmSet2[iPos1] = UnionHkmSet2(pBuilder, aHkmSet1);
			}
			UnionHkmSet3(pBuilder, aHkmSet2);			//ソートするまで、引込セット3番号は未確定。ここでは、登録のみ行う。
		}
	}
	/* 引込セット3をソートする。ソートすると、圧縮率が多少良くなる。 */
	qsort(pBuilder->TBL_HkmSet2, pBuilder->HkmSet2_Size, 21, memcmp21);	//これで、引込セット3番号が確定する。
	/*--- 1リール停止制御データ,2リール停止制御データ,3リール停止制御データを作成する ---*/
	/* 1リール停止制御 */
	for(iHitCd = 0; iHitCd < pInfo->HitCd_Size; iHitCd++) {
		for(iOrder = 0; iOrder < 3; iOrder++) {
			iReel1 = Slot_GetOrderReel(iOrder, 0);		/* 停止中リール */
			for(iPos1 = 0; iPos1 < 21; iPos1++) {
				n = (*pInfo->fnGetStpCtl1)(pInfo->pParam, iHitCd, iReel1, iPos1);
				if((unsigned)n > 4) { DIE(); }
				aHkmCnt[iPos1] = n;
			}
			pBuilder->TBL_StpCtl1[iHitCd][iOrder] = UnionHkmSet1(pBuilder, aHkmCnt);
		}
	}
	for(i = 0; i < pBuilder->HkmSet1_Size; i++) {
		for(j = 0; j < (21 / 3); j++) {
			pBuilder->TBL_HkmSet1_Pack[i][j] = (pBuilder->TBL_HkmSet1[i][(j * 3) + 0]     ) +
			                                   (pBuilder->TBL_HkmSet1[i][(j * 3) + 1] *  6) +
			                                   (pBuilder->TBL_HkmSet1[i][(j * 3) + 2] * 36);
		}
	}
	for(i = 0; i < pBuilder->HkmSet1_Size; i += HkmSet1_CompUnit) {
		n = pBuilder->HkmSet1_Size - i;
		if(n > HkmSet1_CompUnit) { n = HkmSet1_CompUnit; }
		n = TinyLZ_compress(
			&pBuilder->TBL_HkmSet1_CompData[pBuilder->HkmSet1_CompData_Size],
			ARRAY_SIZE(pBuilder->TBL_HkmSet1_CompData) - pBuilder->HkmSet1_CompData_Size,
			&pBuilder->TBL_HkmSet1_Pack[i], n * (21 / 3));
		pBuilder->TBL_HkmSet1_CompSize[i / HkmSet1_CompUnit] = n;
		if((pBuilder->HkmSet1_CompData_Size += n) > ARRAY_SIZE(pBuilder->TBL_HkmSet1_CompData)) { DIE(); }
	}
	/* 2リール停止制御 */
	for(iHitCd = 0; iHitCd < pInfo->HitCd_Size; iHitCd++) {
		for(iOrder = 0; iOrder < 6; iOrder++) {
			iReel1 = Slot_GetOrderReel(iOrder, 0);		/* 停止済リール */
			iReel2 = Slot_GetOrderReel(iOrder, 1);		/* 停止中リール */
			for(iPos1 = 0; iPos1 < 21; iPos1++) {
				for(iPos2 = 0; iPos2 < 21; iPos2++) {
					if(pBuilder->TBL_StpFlg1[iHitCd][iPos1] & (1<<iOrder)) {
						n = (*pInfo->fnGetStpCtl2)(pInfo->pParam, iHitCd, iReel1, iReel2, iPos1, iPos2);
						if((unsigned)n > 4) { DIE(); }
					} else {
						n = 5;
					}
					aHkmCnt[iPos2] = n;
				}
				aHkmSet1[iPos1] = UnionHkmSet1(pBuilder, aHkmCnt);
			}
			pBuilder->TBL_StpCtl2[iHitCd][iOrder] = UnionHkmSet2(pBuilder, aHkmSet1);
		}
	}
	for(i = 0; i < pBuilder->HkmSet2_Size; i += HkmSet2_CompUnit) {
		n = pBuilder->HkmSet2_Size - i;
		if(n > HkmSet2_CompUnit) { n = HkmSet2_CompUnit; }
		n = TinyLZ_compress(
			&pBuilder->TBL_HkmSet2_CompData[pBuilder->HkmSet2_CompData_Size],
			ARRAY_SIZE(pBuilder->TBL_HkmSet2_CompData) - pBuilder->HkmSet2_CompData_Size,
			&pBuilder->TBL_HkmSet2[i], n * 21);
		pBuilder->TBL_HkmSet2_CompSize[i / HkmSet2_CompUnit] = n;
		if((pBuilder->HkmSet2_CompData_Size += n) > ARRAY_SIZE(pBuilder->TBL_HkmSet2_CompData)) { DIE(); }
	}
	/* 3リール停止制御 */
	for(iHitCd = 0; iHitCd < pInfo->HitCd_Size; iHitCd++) {
		for(iOrder = 0; iOrder < 6; iOrder++) {
			iReel1 = Slot_GetOrderReel(iOrder, 0);		/* 停止済リール1 */
			iReel2 = Slot_GetOrderReel(iOrder, 1);		/* 停止済リール2 */
			iReel3 = Slot_GetOrderReel(iOrder, 2);		/* 停止中リール  */
			for(iPos1 = 0; iPos1 < 21; iPos1++) {
				for(iPos2 = 0; iPos2 < 21; iPos2++) {
					for(iPos3 = 0; iPos3 < 21; iPos3++) {
						if(pBuilder->TBL_StpFlg2[iHitCd][iPos1][iPos2] & (1<<iOrder)) {
							n = (*pInfo->fnGetStpCtl3)(pInfo->pParam, iHitCd, iReel1, iReel2, iReel3, iPos1, iPos2, iPos3);
							if((unsigned)n > 4) { DIE(); }
						} else {
							n = 5;
						}
						aHkmCnt[iPos3] = n;
					}
					aHkmSet1[iPos2] = UnionHkmSet1(pBuilder, aHkmCnt);
				}
				aHkmSet2[iPos1] = UnionHkmSet2(pBuilder, aHkmSet1);
			}
			pBuilder->TBL_StpCtl3[iHitCd][iOrder] = UnionHkmSet3(pBuilder, aHkmSet2);
		}
	}
	for(i = 0; i < pBuilder->HkmSet3_Size; i += HkmSet3_CompUnit) {
		n = pBuilder->HkmSet3_Size - i;
		if(n > HkmSet3_CompUnit) { n = HkmSet3_CompUnit; }
		n = TinyLZ_compress(
			&pBuilder->TBL_HkmSet3_CompData[pBuilder->HkmSet3_CompData_Size],
			ARRAY_SIZE(pBuilder->TBL_HkmSet3_CompData) - pBuilder->HkmSet3_CompData_Size,
			&pBuilder->TBL_HkmSet3[i], n * 21);
		pBuilder->TBL_HkmSet3_CompSize[i / HkmSet3_CompUnit] = n;
		if((pBuilder->HkmSet3_CompData_Size += n) > ARRAY_SIZE(pBuilder->TBL_HkmSet3_CompData)) { DIE(); }
	}
	/* 停止制御データのメモリを確保する。(1個のメモリブロックとして確保する。解放時も1個のメモリブロックとして開放せよ。) */
	p = calloc(1, sizeof(ST_Slot_StpCtl) +
		(pInfo->HitCd_Size * 3) +						/* TBL_StpCtl1 */
		(pInfo->HitCd_Size * 6) +						/* TBL_StpCtl2 */
		(pInfo->HitCd_Size * 6) +						/* TBL_StpCtl3 */
		((pBuilder->HkmSet1_Size + HkmSet1_CompUnit - 1) / HkmSet1_CompUnit) +	/* TBL_HkmSet1_CompSize */
		((pBuilder->HkmSet2_Size + HkmSet2_CompUnit - 1) / HkmSet2_CompUnit) +	/* TBL_HkmSet2_CompSize */
		((pBuilder->HkmSet3_Size + HkmSet3_CompUnit - 1) / HkmSet3_CompUnit) +	/* TBL_HkmSet3_CompSize */
		pBuilder->HkmSet1_CompData_Size +					/* TBL_HkmSet1_CompData */
		pBuilder->HkmSet2_CompData_Size +					/* TBL_HkmSet2_CompData */
		pBuilder->HkmSet3_CompData_Size);					/* TBL_HkmSet3_CompData */
	if(!p) { DIE(); }
	pStpCtl                       = (void*)p;   p += sizeof(ST_Slot_StpCtl);
	pStpCtl->TBL_StpCtl1          = (void*)p;   p += (pInfo->HitCd_Size * 3);
	pStpCtl->TBL_StpCtl2          = (void*)p;   p += (pInfo->HitCd_Size * 6);
	pStpCtl->TBL_StpCtl3          = (void*)p;   p += (pInfo->HitCd_Size * 6);
	pStpCtl->TBL_HkmSet1_CompSize = (void*)p;   p += ((pBuilder->HkmSet1_Size + HkmSet1_CompUnit - 1) / HkmSet1_CompUnit);
	pStpCtl->TBL_HkmSet2_CompSize = (void*)p;   p += ((pBuilder->HkmSet2_Size + HkmSet2_CompUnit - 1) / HkmSet2_CompUnit);
	pStpCtl->TBL_HkmSet3_CompSize = (void*)p;   p += ((pBuilder->HkmSet3_Size + HkmSet3_CompUnit - 1) / HkmSet3_CompUnit);
	pStpCtl->TBL_HkmSet1_CompData = (void*)p;   p += pBuilder->HkmSet1_CompData_Size;
	pStpCtl->TBL_HkmSet2_CompData = (void*)p;   p += pBuilder->HkmSet2_CompData_Size;
	pStpCtl->TBL_HkmSet3_CompData = (void*)p; //p += pBuilder->HkmSet3_CompData_Size;
	/* 停止制御データを格納する。 */
	pStpCtl->HitCd_Size            =    pInfo->HitCd_Size;
	pStpCtl->HkmSet1_CompUnit      =           HkmSet1_CompUnit;
	pStpCtl->HkmSet2_CompUnit      =           HkmSet2_CompUnit;
	pStpCtl->HkmSet3_CompUnit      =           HkmSet3_CompUnit;
	pStpCtl->HkmSet1_Size          = pBuilder->HkmSet1_Size;
	pStpCtl->HkmSet2_Size          = pBuilder->HkmSet2_Size;
	pStpCtl->HkmSet3_Size          = pBuilder->HkmSet3_Size;
	pStpCtl->HkmSet1_CompData_Size = pBuilder->HkmSet1_CompData_Size;
	pStpCtl->HkmSet2_CompData_Size = pBuilder->HkmSet2_CompData_Size;
	pStpCtl->HkmSet3_CompData_Size = pBuilder->HkmSet3_CompData_Size;
	memcpy((void*)pStpCtl->TBL_StpCtl1, pBuilder->TBL_StpCtl1, (pInfo->HitCd_Size * 3));									//キャストはconst警告抑制のため
	memcpy((void*)pStpCtl->TBL_StpCtl2, pBuilder->TBL_StpCtl2, (pInfo->HitCd_Size * 6));									//キャストはconst警告抑制のため
	memcpy((void*)pStpCtl->TBL_StpCtl3, pBuilder->TBL_StpCtl3, (pInfo->HitCd_Size * 6));									//キャストはconst警告抑制のため
	memcpy((void*)pStpCtl->TBL_HkmSet1_CompSize, pBuilder->TBL_HkmSet1_CompSize, ((pBuilder->HkmSet1_Size + HkmSet1_CompUnit - 1) / HkmSet1_CompUnit));	//キャストはconst警告抑制のため
	memcpy((void*)pStpCtl->TBL_HkmSet2_CompSize, pBuilder->TBL_HkmSet2_CompSize, ((pBuilder->HkmSet2_Size + HkmSet2_CompUnit - 1) / HkmSet2_CompUnit));	//キャストはconst警告抑制のため
	memcpy((void*)pStpCtl->TBL_HkmSet3_CompSize, pBuilder->TBL_HkmSet3_CompSize, ((pBuilder->HkmSet3_Size + HkmSet3_CompUnit - 1) / HkmSet3_CompUnit));	//キャストはconst警告抑制のため
	memcpy((void*)pStpCtl->TBL_HkmSet1_CompData, pBuilder->TBL_HkmSet1_CompData, pBuilder->HkmSet1_CompData_Size);						//キャストはconst警告抑制のため
	memcpy((void*)pStpCtl->TBL_HkmSet2_CompData, pBuilder->TBL_HkmSet2_CompData, pBuilder->HkmSet2_CompData_Size);						//キャストはconst警告抑制のため
	memcpy((void*)pStpCtl->TBL_HkmSet3_CompData, pBuilder->TBL_HkmSet3_CompData, pBuilder->HkmSet3_CompData_Size);						//キャストはconst警告抑制のため
	/* 停止制御データビルダのメモリを開放する。 */
	free(pBuilder);
	/* 停止制御データのメモリを返す。呼出側で開放せよ。 */
	return pStpCtl;
}
/*--------------------------------------------------------------------------*/
void Slot_PrintStpCtl(const ST_Slot_StpCtl* pStpCtl, FILE* fpH, FILE* fpC) {
	int iHitCd, iOrder, i;
	//1リール停止制御データを出力する。
	fprintf(fpC, "static const unsigned char TBL_StpCtl1[/*HitCd_Size*/][3]/*[21]*/={//⇒(TBL_HkmSet1_CompSize,TBL_HkmSet1_CompData)\n");
	for(iHitCd = 0; iHitCd < pStpCtl->HitCd_Size; iHitCd++) {
		fprintf(fpC, "{");
		for(iOrder = 0; iOrder < 3; iOrder++) {
			if(iOrder) { fprintf(fpC, ","); }
			fprintf(fpC, "%3d", pStpCtl->TBL_StpCtl1[iHitCd][iOrder]);
		}
		fprintf(fpC, "},//%2d\n", iHitCd);
	}
	fprintf(fpC, "};\n");
	//2リール停止制御データを出力する。
	fprintf(fpC, "static const unsigned char TBL_StpCtl2[/*HitCd_Size*/][6]/*[21][21]*/={//⇒{TBL_HkmSet2_CompSize,TBL_HkmSet2_CompData}⇒(TBL_HkmSet1_CompSize,TBL_HkmSet1_CompData)\n");
	for(iHitCd = 0; iHitCd < pStpCtl->HitCd_Size; iHitCd++) {
		fprintf(fpC, "{");
		for(iOrder = 0; iOrder < 6; iOrder++) {
			if(iOrder) { fprintf(fpC, ","); }
			fprintf(fpC, "%3d", pStpCtl->TBL_StpCtl2[iHitCd][iOrder]);
		}
		fprintf(fpC, "},//%2d\n", iHitCd);
	}
	fprintf(fpC, "};\n");
	//3リール停止制御データを出力する。
	fprintf(fpC, "static const unsigned char TBL_StpCtl3[/*HitCd_Size*/][6]/*[21][21][21]*/={//⇒(TBL_HkmSet3_CompSize,TBL_HkmSet3_CompData)⇒(TBL_HkmSet2_CompSize,TBL_HkmSet2_CompData)⇒(TBL_HkmSet1_CompSize,TBL_HkmSet1_CompData)\n");
	for(iHitCd = 0; iHitCd < pStpCtl->HitCd_Size; iHitCd++) {
		fprintf(fpC, "{");
		for(iOrder = 0; iOrder < 6; iOrder++) {
			if(iOrder) { fprintf(fpC, ","); }
			fprintf(fpC, "%3d", pStpCtl->TBL_StpCtl3[iHitCd][iOrder]);
		}
		fprintf(fpC, "},//%2d\n", iHitCd);
	}
	fprintf(fpC, "};\n");
	//引込セット1を出力する。
	fprintf(fpC, "static const unsigned char TBL_HkmSet1_CompSize[/*(HkmSet1_Size+HkmSet1_CompUnit-1)/HkmSet1_CompUnit*/]={\n");
	for(i = 0; i < pStpCtl->HkmSet1_Size; i += pStpCtl->HkmSet1_CompUnit) {
		fprintf(fpC, "%3d,//%2d %3d-%3d\n",
			pStpCtl->TBL_HkmSet1_CompSize[i/pStpCtl->HkmSet1_CompUnit],
			                             (i/pStpCtl->HkmSet1_CompUnit),
			i, (((i+pStpCtl->HkmSet1_CompUnit)<pStpCtl->HkmSet1_Size)?(i+pStpCtl->HkmSet1_CompUnit):pStpCtl->HkmSet1_Size)-1);
	}
	fprintf(fpC, "};\n");
	fprintf(fpC, "static const unsigned char TBL_HkmSet1_CompData[/*HkmSet1_CompData_Size*/]={");
	for(i = 0; i < pStpCtl->HkmSet1_CompData_Size; i++) {
		if(!(i&15)) { fprintf(fpC, "\n"); }
		fprintf(fpC, "%3d,", pStpCtl->TBL_HkmSet1_CompData[i]);
		if(((i&15)==15) || (i==(pStpCtl->HkmSet1_CompData_Size-1))) { fprintf(fpC, "//%4d-%4d", (i&~15), i); }
	}
	fprintf(fpC, "\n};\n");
	//引込セット2を出力する。
	fprintf(fpC, "static const unsigned char TBL_HkmSet2_CompSize[/*(HkmSet2_Size+HkmSet2_CompUnit-1)/HkmSet2_CompUnit*/]={\n");
	for(i = 0; i < pStpCtl->HkmSet2_Size; i += pStpCtl->HkmSet2_CompUnit) {
		fprintf(fpC, "%3d,//%2d %3d-%3d\n",
			pStpCtl->TBL_HkmSet2_CompSize[i/pStpCtl->HkmSet2_CompUnit],
			                             (i/pStpCtl->HkmSet2_CompUnit),
			i, (((i+pStpCtl->HkmSet2_CompUnit)<pStpCtl->HkmSet2_Size)?(i+pStpCtl->HkmSet2_CompUnit):pStpCtl->HkmSet2_Size)-1);
	}
	fprintf(fpC, "};\n");
	fprintf(fpC, "static const unsigned char TBL_HkmSet2_CompData[/*HkmSet2_CompData_Size*/]={");
	for(i = 0; i < pStpCtl->HkmSet2_CompData_Size; i++) {
		if(!(i&15)) { fprintf(fpC, "\n"); }
		fprintf(fpC, "%3d,", pStpCtl->TBL_HkmSet2_CompData[i]);
		if(((i&15)==15) || (i==(pStpCtl->HkmSet2_CompData_Size-1))) { fprintf(fpC, "//%4d-%4d", (i&~15), i); }
	}
	fprintf(fpC, "\n};\n");
	//引込セット3を出力する。
	fprintf(fpC, "static const unsigned char TBL_HkmSet3_CompSize[/*(HkmSet3_Size+HkmSet3_CompUnit-1)/HkmSet3_CompUnit*/]={\n");
	for(i = 0; i < pStpCtl->HkmSet3_Size; i += pStpCtl->HkmSet3_CompUnit) {
		fprintf(fpC, "%3d,//%2d %3d-%3d\n",
			pStpCtl->TBL_HkmSet3_CompSize[i/pStpCtl->HkmSet3_CompUnit],
			                             (i/pStpCtl->HkmSet3_CompUnit),
			i, (((i+pStpCtl->HkmSet3_CompUnit)<pStpCtl->HkmSet3_Size)?(i+pStpCtl->HkmSet3_CompUnit):pStpCtl->HkmSet3_Size)-1);
	}
	fprintf(fpC, "};\n");
	fprintf(fpC, "static const unsigned char TBL_HkmSet3_CompData[/*HkmSet3_CompData_Size*/]={");
	for(i = 0; i < pStpCtl->HkmSet3_CompData_Size; i++) {
		if(!(i&15)) { fprintf(fpC, "\n"); }
		fprintf(fpC, "%3d,", pStpCtl->TBL_HkmSet3_CompData[i]);
		if(((i&15)==15) || (i==(pStpCtl->HkmSet3_CompData_Size-1))) { fprintf(fpC, "//%4d-%4d", (i&~15), i); }
	}
	fprintf(fpC, "\n};\n");
	//停止制御データを出力する。
	fprintf(fpH, "extern const ST_Slot_StpCtl stStpCtl;\n");
	fprintf(fpC,        "const ST_Slot_StpCtl stStpCtl={\n");
	fprintf(fpC, "%4d,//HitCd_Size\n",            pStpCtl->HitCd_Size);
	fprintf(fpC, "%4d,//HkmSet1_CompUnit\n",      pStpCtl->HkmSet1_CompUnit);
	fprintf(fpC, "%4d,//HkmSet2_CompUnit\n",      pStpCtl->HkmSet2_CompUnit);
	fprintf(fpC, "%4d,//HkmSet3_CompUnit\n",      pStpCtl->HkmSet3_CompUnit);
	fprintf(fpC, "%4d,//HkmSet1_Size\n",          pStpCtl->HkmSet1_Size);
	fprintf(fpC, "%4d,//HkmSet2_Size\n",          pStpCtl->HkmSet2_Size);
	fprintf(fpC, "%4d,//HkmSet3_Size\n",          pStpCtl->HkmSet3_Size);
	fprintf(fpC, "%4d,//HkmSet1_CompData_Size\n", pStpCtl->HkmSet1_CompData_Size);
	fprintf(fpC, "%4d,//HkmSet2_CompData_Size\n", pStpCtl->HkmSet2_CompData_Size);
	fprintf(fpC, "%4d,//HkmSet3_CompData_Size\n", pStpCtl->HkmSet3_CompData_Size);
	fprintf(fpC, "TBL_StpCtl1,\n");
	fprintf(fpC, "TBL_StpCtl2,\n");
	fprintf(fpC, "TBL_StpCtl3,\n");
	fprintf(fpC, "TBL_HkmSet1_CompSize,\n");
	fprintf(fpC, "TBL_HkmSet2_CompSize,\n");
	fprintf(fpC, "TBL_HkmSet3_CompSize,\n");
	fprintf(fpC, "TBL_HkmSet1_CompData,\n");
	fprintf(fpC, "TBL_HkmSet2_CompData,\n");
	fprintf(fpC, "TBL_HkmSet3_CompData,\n");
	fprintf(fpC, "};\n");
}
#endif//WIN32	//PC上で停止制御データを作成する時に使用します。P/ECE上では使用しません。

/****************************************************************************
 *	スペックデータ作成・出力
 ****************************************************************************/
#ifdef  WIN32	//PC上でスペックデータを作成する時に使用します。P/ECE上では使用しません。
/*--------------------------------------------------------------------------*
 *	演出上の判断
 *--------------------------------------------------------------------------*/
//#define SLOT_SPEC_ALLOW_TPIHZ_NOBONUS	//このシンボルを定義すると、ダブルテンパイハズレ・トリプルテンパイハズレを許容する。
//#define SLOT_SPEC_ALLOW_MIDCH_NOBONUS	//このシンボルを定義すると、中段チェリーをリーチ目としない。
//#define SLOT_SPEC_ALLOW_CHSEV_NOBONUS	//このシンボルを定義すると、下段チェリー付きセブンをリーチ目としない。
/*--------------------------------------------------------------------------*
 *	構造体
 *--------------------------------------------------------------------------*/
/* 3リール入賞判定 */
typedef struct _ST_Slot_HitChk3 {
	unsigned char	iHitFlg[5/*iLine*/];					//[ライン番号]⇒絵柄組合せ番号				0〜(SIZE_HitFlg-1)
	unsigned char	aPriority[64/*SIZE_HitCd*/];				//[条件装置番号]⇒優先度				0,1〜		「優先度=0」ならば、停止不可であることを示す。
} ST_Slot_HitChk3;
/* 2リール入賞予測 */
typedef struct _ST_Slot_HitChk2 {
	unsigned char	aMinPriority[64/*SIZE_HitCd*/];				//[条件装置番号]⇒最小優先度				0,1〜		「最小優先度=0」ならば、停止不可であることを示す。
	unsigned char	aMaxPriority[64/*SIZE_HitCd*/];				//[条件装置番号]⇒最大優先度				0,1〜		最大優先度≧最小優先度
} ST_Slot_HitChk2;
/* 1リール入賞予測 */
typedef struct _ST_Slot_HitChk1 {
	unsigned char	aMinPriority[64/*SIZE_HitCd*/];				//[条件装置番号]⇒最小優先度				0,1〜		「最小優先度=0」ならば、停止不可であることを示す。
	unsigned char	aMaxPriority[64/*SIZE_HitCd*/];				//[条件装置番号]⇒最大優先度				0,1〜		最大優先度≧最小優先度
} ST_Slot_HitChk1;
/* 1リール停止制御 */
typedef struct _ST_Slot_StpCtl1 {
	unsigned char	aHkmCnt[64/*SIZE_HitCd*/];				//[条件装置番号]⇒引込駒数				0〜4
	unsigned char	aStpFlg[64/*SIZE_HitCd*/];				//[条件装置番号]⇒停止可能				0,1
} ST_Slot_StpCtl1;
/* 2リール停止制御 */
typedef struct _ST_Slot_StpCtl2 {
	unsigned char	aHkmCnt[64/*SIZE_HitCd*/];				//[条件装置番号]⇒引込駒数				0〜4,5		「引込駒数=5」とは、停止済リールの停止不可位置であり、引込駒数が定義されていないことを示す。
	unsigned char	aStpFlg[64/*SIZE_HitCd*/];				//[条件装置番号]⇒停止可能				0,1
} ST_Slot_StpCtl2;
/* 3リール停止制御 */
typedef struct _ST_Slot_StpCtl3 {
	unsigned char	aHkmCnt[64/*SIZE_HitCd*/];				//[条件装置番号]⇒引込駒数				0〜4,5		「引込駒数=5」とは、停止済リールの停止不可位置であり、引込駒数が定義されていないことを示す。
	unsigned char	aStpFlg[64/*SIZE_HitCd*/];				//[条件装置番号]⇒停止可能				0,1
} ST_Slot_StpCtl3;
/* 停止制御テスト */
typedef struct _ST_Slot_StpTst {
	unsigned char	aHkmCnt[64/*SIZE_HitCd*/][3];				//[条件装置番号][リール番号]⇒引込駒数			0〜4,5		「引込駒数=5」とは、停止済リールの停止不可位置であり、引込駒数が定義されていないことを示す。
	unsigned char	aPriority[64/*SIZE_HitCd*/];				//[条件装置番号]⇒優先度				0,1〜
} ST_Slot_StpTst;
/* 絵柄組合せテスト */
typedef struct _ST_Slot_CmbTst {
	int		nCmbCnt;						//絵柄組合せ個数					0~
	int		aStpCnt[64/*SIZE_HitCd*/][5/*iLine*/];			//[条件装置番号][ライン番号]⇒絵柄組合せ表示回数	0~
	unsigned char	aResult[64/*SIZE_HitCd*/];				//[条件装置番号]⇒検査結果				0~2		0=正常,1=エラー:条件装置に含まれないのに表示された,2=警告:条件装置に含まれるのに表示されなかった
} ST_Slot_CmbTst;
/* スペックデータビルダ */
typedef struct _ST_Slot_Spec_Builder {
	const ST_Slot_SpecInfo* pInfo;						//スペック情報
	ST_Slot_HitChk3 TBL_HitChk3[21][21][21];				//[左リール停止位置][中リール停止位置][右リール停止位置]⇒3リール入賞判定
	ST_Slot_HitChk2 TBL_HitChk2[3][21][21];					//[押順][停止済リール1停止位置][停止済リール2停止位置]⇒2リール入賞予測
										// 押順=0…停止済リール1=左,停止済リール2=中
										// 押順=1…停止済リール1=中,停止済リール2=右
										// 押順=2…停止済リール1=右,停止済リール2=左
	ST_Slot_HitChk1 TBL_HitChk1[3][21];					//[押順][停止済リール停止位置]⇒1リール入賞予測
										// 押順=0…停止済リール=左
										// 押順=1…停止済リール=中
										// 押順=2…停止済リール=右
	ST_Slot_StpCtl1 TBL_StpCtl1[3][21];					//[押順][停止中リール押下位置]⇒1リール停止制御
										// 押順=0…停止中リール=左
										// 押順=1…停止中リール=中
										// 押順=2…停止中リール=右
	ST_Slot_StpCtl2 TBL_StpCtl2[6][21][21];					//[押順][停止済リール停止位置][停止中リール押下位置]⇒2リール停止制御
										// 押順=0…停止済リール=左,停止中リール=中
										// 押順=1…停止済リール=中,停止中リール=右
										// 押順=2…停止済リール=右,停止中リール=左
										// 押順=3…停止済リール=左,停止中リール=右
										// 押順=4…停止済リール=中,停止中リール=左
										// 押順=5…停止済リール=右,停止中リール=中
	ST_Slot_StpCtl3 TBL_StpCtl3[6][21][21][21];				//[押順][停止済リール1停止位置][停止済リール2停止位置][停止中リール押下位置]⇒3リール停止制御
										// 押順=0…停止済リール1=左,停止済リール2=中,停止中リール=右
										// 押順=1…停止済リール1=中,停止済リール2=右,停止中リール=左
										// 押順=2…停止済リール1=右,停止済リール2=左,停止中リール=中
										// 押順=3…停止済リール1=左,停止済リール2=右,停止中リール=中
										// 押順=4…停止済リール1=中,停止済リール2=左,停止中リール=右
										// 押順=5…停止済リール1=右,停止済リール2=中,停止中リール=左
	ST_Slot_StpTst TBL_StpTst[6][21][21][21];				//[押順番号][第1停止リール押下位置][第2停止リール押下位置][第3停止リール押下位置]⇒停止制御テスト
	ST_Slot_CmbTst TBL_CmbTst[256/*SIZE_HitFlg*/];				//[絵柄組合せ番号]⇒絵柄組合せテスト
} ST_Slot_Spec_Builder;
/*--------------------------------------------------------------------------*
 *	ローカル定数
 *--------------------------------------------------------------------------*/
static const char* const TBL_Slot_Spec_Color[7+1]={"gray","red","green","yellow","blue","magenta","cyan","white"};	//[色番号]⇒HTMLカラーネーム
static const unsigned char TBL_Slot_Spec_HkmCnt_Color[5+1]={7,6,3,5,1,0};	//[引込駒数]⇒色番号
static const char* const TBL_Slot_Spec_Result_Mark[2+1]={"○","×","△"};	//[検査結果]⇒検査結果記号
static const unsigned char TBL_Slot_Spec_Result_Color[2+1]={4,1,3};		//[検査結果]⇒色番号
/*--------------------------------------------------------------------------*
 *	ローカル関数
 *--------------------------------------------------------------------------*/
/* 絵柄位置(iPictPos)から、引込駒数(nHkmCnt)駒、引込んだ絵柄位置を求める。
 * [in]
 *	iPictPos	絵柄位置	0〜20
 *	nHkmCnt		引込駒数	0〜4
 * [out]
 *	戻り値		絵柄位置	0〜20
 */
static int Slot_Spec_GetPictPos_Hkm(int iPictPos, int nHkmCnt) {
	if((unsigned)iPictPos > 20) { DIE(); }
	if((unsigned)nHkmCnt > 4) { DIE(); }
	if((iPictPos -= nHkmCnt) < 0) { iPictPos += 21; }
	return iPictPos;
}
/*--------------------------------------------------------------------------*/
/* 各リールの停止絵柄が、iPict1,iPict2,iPict3である、絵柄組合せを検索する。
 * [in]
 *	pBuilder	スペックデータビルダ
 *	iPict1		左リールの絵柄番号	0〜(SIZE_Pict-1)
 *	iPict2		中リールの絵柄番号	0〜(SIZE_Pict-1)
 *	iPict3		右リールの絵柄番号	0〜(SIZE_Pict-1)
 * [out]
 *	戻り値		絵柄組合せ番号		0〜(SIZE_HitFlg-1)
 */
static int Slot_Spec_FindHitFlg(ST_Slot_Spec_Builder* pBuilder, int iPict1, int iPict2, int iPict3) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int iHitFlg;
	const ST_Slot_Spec_HitFlg* pHitFlg;
	/* 指定された絵柄番号が正常であることを確認する。 */
	if(((unsigned)iPict1 >= (unsigned)pInfo->SIZE_Pict) ||
	   ((unsigned)iPict2 >= (unsigned)pInfo->SIZE_Pict) ||
	   ((unsigned)iPict3 >= (unsigned)pInfo->SIZE_Pict)) { DIE(); }
	/* 各絵柄組合せについて… */
	for(iHitFlg = pInfo->SIZE_HitFlg - 1; iHitFlg >= 0; iHitFlg--) {
		pHitFlg = &pInfo->TBL_HitFlg[iHitFlg];
		/* 絵柄組合せデータが破損していないことを確認する。 */
		if(((unsigned)pHitFlg->aPict[0] >= (unsigned)pInfo->SIZE_Pict) ||
		   ((unsigned)pHitFlg->aPict[1] >= (unsigned)pInfo->SIZE_Pict) ||
		   ((unsigned)pHitFlg->aPict[2] >= (unsigned)pInfo->SIZE_Pict)) { DIE(); }
		/* 絵柄番号が一致したら、絵柄組合せ番号を返す。 */
		if((!pHitFlg->aPict[0] || (pHitFlg->aPict[0] == iPict1)) &&
		   (!pHitFlg->aPict[1] || (pHitFlg->aPict[1] == iPict2)) &&
		   (!pHitFlg->aPict[2] || (pHitFlg->aPict[2] == iPict3))) { return iHitFlg; }
	}
	DIE(); /* 少なくとも、(iHitFlg=0:ハズレ)に一致するはずなので、ここへ到達したらエラー。 */
}
/*--------------------------------------------------------------------------*
 *	3リール入賞判定
 *--------------------------------------------------------------------------*/
/* 3リール入賞判定データを作成する。
 * [in]
 *	pBuilder	スペックデータビルダ
 * [out]
 *	無し
 */
static void Slot_Spec_BuildHitChk3(ST_Slot_Spec_Builder* pBuilder) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iReel1, iReel2, iReel3, iLine, iHitCd;
	ST_Slot_HitChk3* pHitChk3;
	const ST_Slot_Spec_HitFlg* pHitFlg;
	iReel1 = 0; /* 左リール */
	iReel2 = 1; /* 中リール */
	iReel3 = 2; /* 右リール */
	/* 左リールの各停止位置について… */
	for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
		/* 中リールの各停止位置について… */
		for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
			/* 右リールの各停止位置について… */
			for(aPictPos[iReel3] = 0; aPictPos[iReel3] < 21; aPictPos[iReel3]++) {
				pHitChk3 = &pBuilder->TBL_HitChk3[aPictPos[iReel1]][aPictPos[iReel2]][aPictPos[iReel3]];
				/* 各ラインについて… */
				for(iLine = 0; iLine < 5; iLine++) {
					/* 絵柄組合せ番号を取得する。 */
					pHitChk3->iHitFlg[iLine] = Slot_Spec_FindHitFlg(pBuilder,
						Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel1] + Slot_GetLineRow(iLine, iReel1), iReel1),
						Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel2] + Slot_GetLineRow(iLine, iReel2), iReel2),
						Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel3] + Slot_GetLineRow(iLine, iReel3), iReel3));
				}
				/* 各条件装置について… */
				for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
					/* 各ラインについて… */
					for(iLine = 0; iLine < 5; iLine++) {
						/* このラインの、絵柄組合せを取得する。 */
						pHitFlg = &pInfo->TBL_HitFlg[pHitChk3->iHitFlg[iLine]];
						if(pHitFlg->aPriority[iHitCd] < -1) { DIE(); }
						/* この条件装置で停止可能な絵柄組合せならば… */	//この判断では、優先度(-1)も含める。
						if(pHitFlg->aPriority[iHitCd]) {
							/* 優先度を更新する。 */			//この判断で、優先度(-1)を除外する。
							if((int)pHitFlg->aPriority[iHitCd] > (int)pHitChk3->aPriority[iHitCd]) { pHitChk3->aPriority[iHitCd] = pHitFlg->aPriority[iHitCd]; }
						/* この条件装置で停止不可な絵柄組合せが1つでも有れば… */
						} else {
							/* 停止不可と決定する。 */
							pHitChk3->aPriority[iHitCd] = 0;
							break; /* ここまで */
						}
					}
				}
			}
		}
	}
}
/*--------------------------------------------------------------------------*/
/* 3リール入賞判定データをHTML出力する。
 * [in]
 *	pBuilder	スペックデータビルダ
 *	fp		出力ストリーム
 * [out]
 *	無し
 */
static void Slot_Spec_PrintHitChk3(ST_Slot_Spec_Builder* pBuilder, FILE* fp) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iReel1, iReel2, iReel3, iLine, iHitCd;
	const ST_Slot_HitChk3* pHitChk3;
	const ST_Slot_Spec_Pict* pPict;
	iReel1 = 0; /* 左リール */
	iReel2 = 1; /* 中リール */
	iReel3 = 2; /* 右リール */
	fprintf(fp, "<table>\n");
	fprintf(fp, "<caption>%s</caption>\n", "TBL_HitChk3");
	/* 左リールの各停止位置について… */
	for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
		/* 中リールの各停止位置について… */
		for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
			/* 右リールの各停止位置について… */
			for(aPictPos[iReel3] = 0; aPictPos[iReel3] < 21; aPictPos[iReel3]++) {
				pHitChk3 = &pBuilder->TBL_HitChk3[aPictPos[iReel1]][aPictPos[iReel2]][aPictPos[iReel3]];
				fprintf(fp, "<tr>");
				  fprintf(fp, "<td>");
				    fprintf(fp, "%2d", aPictPos[iReel1]);							//左リール停止位置
				    fprintf(fp, " ");
				    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel1], iReel1)];
				    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
				      fprintf(fp, "%s", pPict->pName);								//左リール停止絵柄
				    fprintf(fp, "</font>");
				    fprintf(fp, " ");
				    fprintf(fp, "%2d", aPictPos[iReel2]);							//中リール停止位置
				    fprintf(fp, " ");
				    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel2], iReel2)];
				    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
				      fprintf(fp, "%s", pPict->pName);								//中リール停止絵柄
				    fprintf(fp, "</font>");
				    fprintf(fp, " ");
				    fprintf(fp, "%2d", aPictPos[iReel3]);							//右リール停止位置
				    fprintf(fp, " ");
				    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel3], iReel3)];
				    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
				      fprintf(fp, "%s", pPict->pName);								//右リール停止絵柄
				    fprintf(fp, "</font>");
				  fprintf(fp, "</td>");
				  /* 各ラインについて… */
				  fprintf(fp, "<td>");
				    for(iLine = 0; iLine < 5; iLine++) {
				    	if(iLine) { fprintf(fp, " "); }
				    	fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pInfo->TBL_HitFlg[pHitChk3->iHitFlg[iLine]].iColor]);
				    	  fprintf(fp, "%s", pInfo->TBL_HitFlg[pHitChk3->iHitFlg[iLine]].pName);			//絵柄組合せ
				    	fprintf(fp, "</font>");
				    }
				  fprintf(fp, "</td>");
				  //各条件装置について…
				  fprintf(fp, "<td>");
				    for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
				    	if(iHitCd) { fprintf(fp, " "); }
				    	fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pHitChk3->aPriority[iHitCd] ? 7 : 0]);
				    	  fprintf(fp, "%d", pHitChk3->aPriority[iHitCd]);					//優先度
				    	fprintf(fp, "</font>");
				    }
				  fprintf(fp, "</td>");
				fprintf(fp, "</tr>\n");
			}
		}
	}
	fprintf(fp, "</table>\n");
}
/*--------------------------------------------------------------------------*
 *	2リール入賞予測
 *--------------------------------------------------------------------------*/
/* 2リール入賞予測データを作成する。
 * [in]
 *	pBuilder	スペックデータビルダ
 * [out]
 *	無し
 */
static void Slot_Spec_BuildHitChk2(ST_Slot_Spec_Builder* pBuilder) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iReel2, iReel3, iHitCd, nHkmCnt, nMinPriority1, nMaxPriority1, nMinPriority2, nMaxPriority2;
	ST_Slot_HitChk2* pHitChk2;
	const ST_Slot_HitChk3* pHitChk3;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 3; iOrder++) {
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 停止済リール1 */
		iReel2 = Slot_GetOrderReel(iOrder, 1); /* 停止済リール2 */
		iReel3 = Slot_GetOrderReel(iOrder, 2); /* 回転中リール */
		/* 停止済リール1の各停止位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			/* 停止済リール2の各停止位置について… */
			for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
				pHitChk2 = &pBuilder->TBL_HitChk2[iOrder][aPictPos[iReel1]][aPictPos[iReel2]];
				/* 各条件装置について… */
				for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
					nMinPriority1 = nMaxPriority1 = 0;
					/* 回転中リールの各停止位置について… */
					for(aPictPos[iReel3] = 0; aPictPos[iReel3] < 21; aPictPos[iReel3]++) {
						nMinPriority2 = nMaxPriority2 = 0;
						/* 最大引込駒数を取得する。 */
						nHkmCnt = (strstr(pInfo->TBL_HitCd[iHitCd].pName, "全小役") && (iReel3 == pInfo->CT_Reel)) ? 1 : 4;
						/* 各引込駒数について… */
						do {
							/* 3リール入賞判定データを取得する */
							switch(iReel3) {
							case 0: pHitChk3 = &pBuilder->TBL_HitChk3[Slot_Spec_GetPictPos_Hkm(aPictPos[0], nHkmCnt)][                         aPictPos[1]          ][                         aPictPos[2]          ]; break;
							case 1: pHitChk3 = &pBuilder->TBL_HitChk3[                         aPictPos[0]          ][Slot_Spec_GetPictPos_Hkm(aPictPos[1], nHkmCnt)][                         aPictPos[2]          ]; break;
							case 2: pHitChk3 = &pBuilder->TBL_HitChk3[                         aPictPos[0]          ][                         aPictPos[1]          ][Slot_Spec_GetPictPos_Hkm(aPictPos[2], nHkmCnt)]; break;
							default: DIE();
							}
							/* 停止可能ならば… */
							if(pHitChk3->aPriority[iHitCd]) {
								/* 最小優先度と最大優先度を更新する。 */
								if(!nMinPriority2) {	/* 初回 */
									nMinPriority2 = pHitChk3->aPriority[iHitCd];
									nMaxPriority2 = pHitChk3->aPriority[iHitCd];
								} else {		/* 更新 */
									if(pHitChk3->aPriority[iHitCd] < nMinPriority2) { nMinPriority2 = pHitChk3->aPriority[iHitCd]; }
									if(pHitChk3->aPriority[iHitCd] > nMaxPriority2) { nMaxPriority2 = pHitChk3->aPriority[iHitCd]; }
								}
							}
						} while(--nHkmCnt >= 0);
						/* 全ての引込駒数で停止不可ならば… */
						if(!nMinPriority2) {
							/* 停止不可と決定する。 */
							nMinPriority1 = nMaxPriority1 = 0;
							break; /* ここまで */
						}
						/* 最小優先度と最大優先度を更新する。 */
						if(!nMinPriority1) {	/* 初回 */
							nMinPriority1 = nMinPriority2;
							nMaxPriority1 = nMaxPriority2;
						} else {		/* 更新 */
							if(nMinPriority2 < nMinPriority1) { nMinPriority1 = nMinPriority2; }
							if(nMaxPriority2 > nMaxPriority1) { nMaxPriority1 = nMaxPriority2; }
						}
					}
#ifndef SLOT_SPEC_ALLOW_TPIHZ_NOBONUS
					//{{--- ダブルテンパイハズレ・トリプルテンパイハズレを禁止する場合は、このブロックを有効にせよ。これは演出上の判断であり、必須ではない。 ---
					/* 条件装置がハズレならば… */
					if(!iHitCd) {
						int iLine, TpiCnt = 0;
						/* 各ラインについて… */
						for(iLine = 0; iLine < 5; iLine++) {
							/* テンパイ判定を行う。 */
							if(Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel1] + Slot_GetLineRow(iLine, iReel1), iReel1) ==
							   Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel2] + Slot_GetLineRow(iLine, iReel2), iReel2)) { TpiCnt++; }
						}
						/* 条件装置がハズレで、テンパイライン数が2ライン以上ならば、停止不可と決定する。 */
						if(TpiCnt >= 2) { nMinPriority1 = nMaxPriority1 = 0; }
					}
					//}}--- ダブルテンパイハズレ・トリプルテンパイハズレを禁止する場合は、このブロックを有効にせよ。これは演出上の判断であり、必須ではない。 ---
#endif//SLOT_SPEC_ALLOW_TPIHZ_NOBONUS
					/* 最小優先度と最大優先度を格納する。 */
					pHitChk2->aMinPriority[iHitCd] = nMinPriority1;
					pHitChk2->aMaxPriority[iHitCd] = nMaxPriority1;
				}
			}
		}
	}
}
/*--------------------------------------------------------------------------*/
/* 2リール入賞予測データをHTML出力する。
 * [in]
 *	pBuilder	スペックデータビルダ
 *	fp		出力ストリーム
 * [out]
 *	無し
 */
static void Slot_Spec_PrintHitChk2(ST_Slot_Spec_Builder* pBuilder, FILE* fp) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iReel2, iHitCd;
	const ST_Slot_HitChk2* pHitChk2;
	const ST_Slot_Spec_Pict* pPict;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 3; iOrder++) {
		fprintf(fp, "<table>\n");
		fprintf(fp, "<caption>%s[%d]</caption>\n", "TBL_HitChk2", iOrder);
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 停止済リール1 */
		iReel2 = Slot_GetOrderReel(iOrder, 1); /* 停止済リール2 */
		/* 停止済リール1の各停止位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			/* 停止済リール2の各停止位置について… */
			for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
				pHitChk2 = &pBuilder->TBL_HitChk2[iOrder][aPictPos[iReel1]][aPictPos[iReel2]];
				fprintf(fp, "<tr>");
				  fprintf(fp, "<td>");
				    fprintf(fp, "%2d", aPictPos[iReel1]);							//停止済リール1停止位置
				    fprintf(fp, " ");
				    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel1], iReel1)];
				    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
				      fprintf(fp, "%s", pPict->pName);								//停止済リール1停止絵柄
				    fprintf(fp, "</font>");
				    fprintf(fp, " ");
				    fprintf(fp, "%2d", aPictPos[iReel2]);							//停止済リール2停止位置
				    fprintf(fp, " ");
				    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel2], iReel2)];
				    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
				      fprintf(fp, "%s", pPict->pName);								//停止済リール2停止絵柄
				    fprintf(fp, "</font>");
				  fprintf(fp, "</td>");
				  /* 各条件装置について… */
				  fprintf(fp, "<td>");
				    for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
				    	if(iHitCd) { fprintf(fp, " "); }
				    	fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pHitChk2->aMinPriority[iHitCd] ? 7 : 0]);
				    	  fprintf(fp, "%d-%d", pHitChk2->aMinPriority[iHitCd], pHitChk2->aMaxPriority[iHitCd]);	//最小優先度,最大優先度
				    	fprintf(fp, "</font>");
				    }
				  fprintf(fp, "</td>");
				fprintf(fp, "</tr>\n");
			}
		}
		fprintf(fp, "</table>\n");
	}
}
/*--------------------------------------------------------------------------*
 *	1リール入賞予測
 *--------------------------------------------------------------------------*/
/* 1リール入賞予測データを作成する。
 * [in]
 *	pBuilder	スペックデータビルダ
 * [out]
 *	無し
 */
static void Slot_Spec_BuildHitChk1(ST_Slot_Spec_Builder* pBuilder) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iReel2, iHitCd, nHkmCnt, nMinPriority1, nMaxPriority1, nMinPriority2, nMaxPriority2, nMinPriority3, nMaxPriority3;
	ST_Slot_HitChk1* pHitChk1;
	const ST_Slot_HitChk2* pHitChk2;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 3; iOrder++) {
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 停止済リール */
		/* 停止済リールの各停止位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			pHitChk1 = &pBuilder->TBL_HitChk1[iOrder][aPictPos[iReel1]];
			/* 各条件装置について… */
			for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
				nMinPriority1 = nMaxPriority1 = 0;
				/* 回転中リール1と回転中リール2について… */
				for(iReel2 = (iReel1+1)%3; iReel2 != iReel1; iReel2 = (iReel2+1)%3) {
					nMinPriority2 = nMaxPriority2 = 0;
					/* 回転中リールの各停止位置について… */
					for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
						nMinPriority3 = nMaxPriority3 = 0;
						/* 最大引込駒数を取得する。 */
						nHkmCnt = (strstr(pInfo->TBL_HitCd[iHitCd].pName, "全小役") && (iReel2 == pInfo->CT_Reel)) ? 1 : 4;
						/* 各引込駒数について… */
						do {
							/* 2リール入賞予測データを取得する */
							switch(iReel1) {
							case 0:
								switch(iReel2) {
								case 1: pHitChk2 = &pBuilder->TBL_HitChk2[0][                         aPictPos[0]          ][Slot_Spec_GetPictPos_Hkm(aPictPos[1], nHkmCnt)]; break;
								case 2: pHitChk2 = &pBuilder->TBL_HitChk2[2][Slot_Spec_GetPictPos_Hkm(aPictPos[2], nHkmCnt)][                         aPictPos[0]          ]; break;
								default: DIE();
								}
								break;
							case 1:
								switch(iReel2) {
								case 2: pHitChk2 = &pBuilder->TBL_HitChk2[1][                         aPictPos[1]          ][Slot_Spec_GetPictPos_Hkm(aPictPos[2], nHkmCnt)]; break;
								case 0: pHitChk2 = &pBuilder->TBL_HitChk2[0][Slot_Spec_GetPictPos_Hkm(aPictPos[0], nHkmCnt)][                         aPictPos[1]          ]; break;
								default: DIE();
								}
								break;
							case 2:
								switch(iReel2) {
								case 0: pHitChk2 = &pBuilder->TBL_HitChk2[2][                         aPictPos[2]          ][Slot_Spec_GetPictPos_Hkm(aPictPos[0], nHkmCnt)]; break;
								case 1: pHitChk2 = &pBuilder->TBL_HitChk2[1][Slot_Spec_GetPictPos_Hkm(aPictPos[1], nHkmCnt)][                         aPictPos[2]          ]; break;
								default: DIE();
								}
								break;
							default:
								DIE();
							}
							/* 停止可能ならば… */
							if(pHitChk2->aMinPriority[iHitCd]) {
								/* 最小優先度と最大優先度を更新する。 */
								if(!nMinPriority3) {
									nMinPriority3 = pHitChk2->aMinPriority[iHitCd];
									nMaxPriority3 = pHitChk2->aMaxPriority[iHitCd];
								} else {
									if(pHitChk2->aMinPriority[iHitCd] < nMinPriority3) { nMinPriority3 = pHitChk2->aMinPriority[iHitCd]; }
									if(pHitChk2->aMaxPriority[iHitCd] > nMaxPriority3) { nMaxPriority3 = pHitChk2->aMaxPriority[iHitCd]; }
								}
							}
						} while(--nHkmCnt >= 0);
						/* 全ての引込駒数で停止不可ならば… */
						if(!nMinPriority3) {
							/* 停止不可と決定する。 */
							nMinPriority2 = nMaxPriority2 = 0;
							break; /* ここまで */
						}
						/* 最小優先度と最大優先度を更新する。 */
						if(!nMinPriority2) {
							nMinPriority2 = nMinPriority3;
							nMaxPriority2 = nMaxPriority3;
						} else {
							if(nMinPriority3 < nMinPriority2) { nMinPriority2 = nMinPriority3; }
							if(nMaxPriority3 > nMaxPriority2) { nMaxPriority2 = nMaxPriority3; }
						}
					}
					/* 回転中リールの片方でも停止不可ならば… */
					if(!nMinPriority2) {
						/* 停止不可と決定する。 */
						nMinPriority1 = nMaxPriority1 = 0;
						break; /* ここまで */
					}
					/* 最小優先度と最大優先度を更新する。 */
					if(!nMinPriority1) {
						nMinPriority1 = nMinPriority2;
						nMaxPriority1 = nMaxPriority2;
					} else {
						if(nMinPriority2 < nMinPriority1) { nMinPriority1 = nMinPriority2; }
						if(nMaxPriority2 > nMaxPriority1) { nMaxPriority1 = nMaxPriority2; }
					}
				}
#ifndef SLOT_SPEC_ALLOW_MIDCH_NOBONUS
				//{{--- 左リール第1停止時、中段チェリーをリーチ目とする場合は、このブロックを有効にせよ。これは演出上の判断であり、必須ではない。 ---
				/* 左リール第1停止ならば… */
				if(iReel1 == 0) {
					/* 中段チェリーならば… */
					if(strstr(pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel1] + 1/*中段*/, iReel1)].pName, "ﾁｪﾘｰ")) {
						/* 条件装置がボーナスならば… */
						if(strstr(pInfo->TBL_HitCd[iHitCd].pName, "ﾎﾞｰﾅｽ")) {
							/* 出来る限り、リーチ目を引込むことにする。これは演出上の判断であり、必須ではない。 */
							if(!nMinPriority1) { DIE(); }	/* 最小優先度が、停止可能であるはず。もしそうでなければ設計ミス。 */
							nMaxPriority1++;		/* 最大優先度を、セブン揃いの既定の優先度+1とする。 */			//「最大優先度≧最小優先度」を維持するために、最大優先度の方を増やすことにした。これで良いか要検討。今回は違うが、ボーナスと小役が重複当選し小役優先制御としたい場合に、小役優先にならない問題が生じるかも知れない。最小優先度を増やす方が適切か?
						/* 条件装置がボーナス以外ならば… */
						} else {
							/* 停止不可と決定する。 */
							nMinPriority1 = nMaxPriority1 = 0;
						}
					}
				}
				//}}--- 左リール第1停止時、中段チェリーをリーチ目とする場合は、このブロックを有効にせよ。これは演出上の判断であり、必須ではない。 ---
#endif//SLOT_SPEC_ALLOW_MIDCH_NOBONUS
#ifndef SLOT_SPEC_ALLOW_CHSEV_NOBONUS
				//{{--- 右リール第1停止時、下段チェリー付きセブンをリーチ目とする場合は、このブロックを有効にせよ。これは演出上の判断であり、必須ではない。 ---
				/* 右リール第1停止ならば… */
				if(iReel1 == 2) {
					/* 下段チェリー付きセブンならば… */
					if(strstr(pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel1] + 1/*中段*/, iReel1)].pName, "ﾁｪﾘｰ") &&
					   strstr(pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel1] + 2/*下段*/, iReel1)].pName, "ｾﾌﾞﾝ")) {
						/* 条件装置がボーナスならば… */
						if(strstr(pInfo->TBL_HitCd[iHitCd].pName, "ﾎﾞｰﾅｽ")) {
							/* 出来る限り、リーチ目を引込むことにする。これは演出上の判断であり、必須ではない。 */
							if(!nMinPriority1) { DIE(); }	/* 最小優先度が、停止可能であるはず。もしそうでなければ設計ミス。 */
							nMaxPriority1++;		/* 最大優先度を、セブン揃いの既定の優先度+1とする。 */			//「最大優先度≧最小優先度」を維持するために、最大優先度の方を増やすことにした。これで良いか要検討。今回は違うが、ボーナスと小役が重複当選し小役優先制御としたい場合に、小役優先にならない問題が生じるかも知れない。最小優先度を増やす方が適切か?
						/* 条件装置がボーナス以外ならば… */
						} else {
							/* 停止不可と決定する。 */
							nMinPriority1 = nMaxPriority1 = 0;
						}
					}
				}
				//}}--- 右リール第1停止時、下段チェリー付きセブンをリーチ目とする場合は、このブロックを有効にせよ。これは演出上の判断であり、必須ではない。 ---
#endif//SLOT_SPEC_ALLOW_CHSEV_NOBONUS
				/* 最小優先度と最大優先度を格納する。 */
				pHitChk1->aMinPriority[iHitCd] = nMinPriority1;
				pHitChk1->aMaxPriority[iHitCd] = nMaxPriority1;
			}
		}
	}
}
/*--------------------------------------------------------------------------*/
/* 1リール入賞予測データをHTML出力する。
 * [in]
 *	pBuilder	スペックデータビルダ
 *	fp		出力ストリーム
 * [out]
 *	無し
 */
static void Slot_Spec_PrintHitChk1(ST_Slot_Spec_Builder* pBuilder, FILE* fp) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iHitCd;
	const ST_Slot_HitChk1* pHitChk1;
	const ST_Slot_Spec_Pict* pPict;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 3; iOrder++) {
		fprintf(fp, "<table>\n");
		fprintf(fp, "<caption>%s[%d]</caption>\n", "TBL_HitChk1", iOrder);
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 停止済リール */
		/* 停止済リールの各停止位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			pHitChk1 = &pBuilder->TBL_HitChk1[iOrder][aPictPos[iReel1]];
			fprintf(fp, "<tr>");
			  fprintf(fp, "<td>");
			    fprintf(fp, "%2d", aPictPos[iReel1]);								//停止済リール停止位置
			    fprintf(fp, " ");
			    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel1], iReel1)];
			    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
			      fprintf(fp, "%s", pPict->pName);									//停止済リール停止絵柄
			    fprintf(fp, "</font>");
			  fprintf(fp, "</td>");
			  /* 各条件装置について… */
			  fprintf(fp, "<td>");
			    for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
			    	if(iHitCd) { fprintf(fp, " "); }
			    	fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pHitChk1->aMinPriority[iHitCd] ? 7 : 0]);
			    	  fprintf(fp, "%d-%d", pHitChk1->aMinPriority[iHitCd], pHitChk1->aMaxPriority[iHitCd]);		//最小優先度,最大優先度
			    	fprintf(fp, "</font>");
			    }
			  fprintf(fp, "</td>");
			fprintf(fp, "</tr>\n");
		}
		fprintf(fp, "</table>\n");
	}
}
/*--------------------------------------------------------------------------*
 *	1リール停止制御
 *--------------------------------------------------------------------------*/
/* 1リール停止制御データを作成する。
 * [in]
 *	pBuilder	スペックデータビルダ
 * [out]
 *	無し
 */
static void Slot_Spec_BuildStpCtl1(ST_Slot_Spec_Builder* pBuilder) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iHitCd, nHkmCnt, nMinPriority, nMaxPriority;
	ST_Slot_StpCtl1* pStpCtl1;
	const ST_Slot_HitChk1* pHitChk1;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 3; iOrder++) {
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 停止中リール */
		/* 停止中リールの各押下位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			pStpCtl1 = &pBuilder->TBL_StpCtl1[iOrder][aPictPos[iReel1]];
			/* 各条件装置について… */
			for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
				nMinPriority = nMaxPriority = 0;
				pStpCtl1->aHkmCnt[iHitCd] = 5;	/* 停止不可としておく。 */
				/* 最大引込駒数を取得する。 */
				nHkmCnt = (strstr(pInfo->TBL_HitCd[iHitCd].pName, "全小役") && (iReel1 == pInfo->CT_Reel)) ? 1 : 4;
				/* 各引込駒数について… */
				do {
					/* 1リール入賞予測データを取得する */
					switch(iReel1) {
					case 0: pHitChk1 = &pBuilder->TBL_HitChk1[0][Slot_Spec_GetPictPos_Hkm(aPictPos[0], nHkmCnt)]; break;
					case 1: pHitChk1 = &pBuilder->TBL_HitChk1[1][Slot_Spec_GetPictPos_Hkm(aPictPos[1], nHkmCnt)]; break;
					case 2: pHitChk1 = &pBuilder->TBL_HitChk1[2][Slot_Spec_GetPictPos_Hkm(aPictPos[2], nHkmCnt)]; break;
					default: DIE();
					}
					/* 停止可能ならば… */
					if(pHitChk1->aMinPriority[iHitCd]) {
						/* 引込駒数を選択する:
						 * ・最大優先度が大きければ、選択する。
						 * ・最大優先度が同じ,かつ,最小優先度が大きければ、選択する。
						 * ・最大優先度が同じ,かつ,最小優先度が同じならば、引込駒数が小さい方を選択する。即ち、ループの後方優先で上書きする。
						 */
						if((pHitChk1->aMaxPriority[iHitCd] >  nMaxPriority) ||
						  ((pHitChk1->aMaxPriority[iHitCd] == nMaxPriority) && (pHitChk1->aMinPriority[iHitCd] >= nMinPriority))) {
							nMinPriority = pHitChk1->aMinPriority[iHitCd];
							nMaxPriority = pHitChk1->aMaxPriority[iHitCd];
							pStpCtl1->aHkmCnt[iHitCd] = nHkmCnt;
						}
					}
				} while(--nHkmCnt >= 0);
				/* 全ての引込駒数で停止不可ならば、設計ミスである。 */
				if(pStpCtl1->aHkmCnt[iHitCd] == 5) { DIE(); }
				/* 実際に停止する停止位置に、停止可能をマークする。 */
				pBuilder->TBL_StpCtl1[iOrder][Slot_Spec_GetPictPos_Hkm(aPictPos[iReel1], pStpCtl1->aHkmCnt[iHitCd])].aStpFlg[iHitCd] = 1;
			}
		}
	}
}
/*--------------------------------------------------------------------------*/
/* 1リール停止制御データをHTML出力する。
 * [in]
 *	pBuilder	スペックデータビルダ
 *	fp		出力ストリーム
 * [out]
 *	無し
 */
static void Slot_Spec_PrintStpCtl1(ST_Slot_Spec_Builder* pBuilder, FILE* fp) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iHitCd;
	const ST_Slot_StpCtl1* pStpCtl1;
	const ST_Slot_Spec_Pict* pPict;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 3; iOrder++) {
		fprintf(fp, "<table>\n");
		fprintf(fp, "<caption>%s[%d]</caption>\n", "TBL_StpCtl1", iOrder);
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 停止中リール */
		/* 停止中リールの各押下位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			pStpCtl1 = &pBuilder->TBL_StpCtl1[iOrder][aPictPos[iReel1]];
			fprintf(fp, "<tr>");
			  fprintf(fp, "<td>");
			    fprintf(fp, "%2d", aPictPos[iReel1]);								//停止中リール押下位置
			    fprintf(fp, " ");
			    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel1], iReel1)];
			    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
			      fprintf(fp, "%s", pPict->pName);									//停止中リール押下絵柄
			    fprintf(fp, "</font>");
			  fprintf(fp, "</td>");
			  /* 各条件装置について… */
			  fprintf(fp, "<td>");
			    for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
			    	if(iHitCd) { fprintf(fp, " "); }
			    	fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[TBL_Slot_Spec_HkmCnt_Color[pStpCtl1->aHkmCnt[iHitCd]]]);
			    	  fprintf(fp, "%d", pStpCtl1->aHkmCnt[iHitCd]);							//引込駒数
			    	fprintf(fp, "</font>");
			    }
			  fprintf(fp, "</td>");
			fprintf(fp, "</tr>\n");
		}
		fprintf(fp, "</table>\n");
	}
}
/*--------------------------------------------------------------------------*
 *	2リール停止制御
 *--------------------------------------------------------------------------*/
/* 2リール停止制御データを作成する。
 * [in]
 *	pBuilder	スペックデータビルダ
 * [out]
 *	無し
 */
static void Slot_Spec_BuildStpCtl2(ST_Slot_Spec_Builder* pBuilder) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iReel2, iHitCd, nHkmCnt, nMinPriority, nMaxPriority;
	ST_Slot_StpCtl2* pStpCtl2;
	const ST_Slot_HitChk2* pHitChk2;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 6; iOrder++) {
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 停止済リール */
		iReel2 = Slot_GetOrderReel(iOrder, 1); /* 停止中リール */
		/* 停止済リールの各停止位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			/* 停止中リールの各押下位置について… */
			for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
				pStpCtl2 = &pBuilder->TBL_StpCtl2[iOrder][aPictPos[iReel1]][aPictPos[iReel2]];
				/* 各条件装置について… */
				for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
					nMinPriority = nMaxPriority = 0;
					pStpCtl2->aHkmCnt[iHitCd] = 5;	/* 停止不可としておく。 */
					/* 停止済リールの停止位置が、停止可能ならば… */
					if(pBuilder->TBL_StpCtl1[iReel1][aPictPos[iReel1]].aStpFlg[iHitCd]) {
						/* 最大引込駒数を取得する。 */
						nHkmCnt = (strstr(pInfo->TBL_HitCd[iHitCd].pName, "全小役") && (iReel2 == pInfo->CT_Reel)) ? 1 : 4;
						/* 各引込駒数について… */
						do {
							/* 2リール入賞予測データを取得する */
							switch(iReel1) {
							case 0:
								switch(iReel2) {
								case 1: pHitChk2 = &pBuilder->TBL_HitChk2[0][                         aPictPos[0]          ][Slot_Spec_GetPictPos_Hkm(aPictPos[1], nHkmCnt)]; break;
								case 2: pHitChk2 = &pBuilder->TBL_HitChk2[2][Slot_Spec_GetPictPos_Hkm(aPictPos[2], nHkmCnt)][                         aPictPos[0]          ]; break;
								default: DIE();
								}
								break;
							case 1:
								switch(iReel2) {
								case 2: pHitChk2 = &pBuilder->TBL_HitChk2[1][                         aPictPos[1]          ][Slot_Spec_GetPictPos_Hkm(aPictPos[2], nHkmCnt)]; break;
								case 0: pHitChk2 = &pBuilder->TBL_HitChk2[0][Slot_Spec_GetPictPos_Hkm(aPictPos[0], nHkmCnt)][                         aPictPos[1]          ]; break;
								default: DIE();
								}
								break;
							case 2:
								switch(iReel2) {
								case 0: pHitChk2 = &pBuilder->TBL_HitChk2[2][                         aPictPos[2]          ][Slot_Spec_GetPictPos_Hkm(aPictPos[0], nHkmCnt)]; break;
								case 1: pHitChk2 = &pBuilder->TBL_HitChk2[1][Slot_Spec_GetPictPos_Hkm(aPictPos[1], nHkmCnt)][                         aPictPos[2]          ]; break;
								default: DIE();
								}
								break;
							default:
								DIE();
							}
							/* 停止可能ならば… */
							if(pHitChk2->aMinPriority[iHitCd]) {
								/* 引込駒数を選択する:
								 * ・最大優先度が大きければ、選択する。
								 * ・最大優先度が同じ,かつ,最小優先度が大きければ、選択する。
								 * ・最大優先度が同じ,かつ,最小優先度が同じならば、引込駒数が小さい方を選択する。即ち、ループの後方優先で上書きする。
								 */
								if((pHitChk2->aMaxPriority[iHitCd] >  nMaxPriority) ||
								  ((pHitChk2->aMaxPriority[iHitCd] == nMaxPriority) && (pHitChk2->aMinPriority[iHitCd] >= nMinPriority))) {
									nMinPriority = pHitChk2->aMinPriority[iHitCd];
									nMaxPriority = pHitChk2->aMaxPriority[iHitCd];
									pStpCtl2->aHkmCnt[iHitCd] = nHkmCnt;
								}
							}
						} while(--nHkmCnt >= 0);
						/* 全ての引込駒数で停止不可ならば、設計ミスである。 */
						if(pStpCtl2->aHkmCnt[iHitCd] == 5) { DIE(); }
						/* 実際に停止する停止位置に、停止可能をマークする。 */
						pBuilder->TBL_StpCtl2[iOrder][aPictPos[iReel1]][Slot_Spec_GetPictPos_Hkm(aPictPos[iReel2], pStpCtl2->aHkmCnt[iHitCd])].aStpFlg[iHitCd] = 1;
					}
				}
			}
		}
	}
}
/*--------------------------------------------------------------------------*/
/* 2リール停止制御データをHTML出力する。
 * [in]
 *	pBuilder	スペックデータビルダ
 *	fp		出力ストリーム
 * [out]
 *	無し
 */
static void Slot_Spec_PrintStpCtl2(ST_Slot_Spec_Builder* pBuilder, FILE* fp) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iReel2, iHitCd;
	const ST_Slot_StpCtl2* pStpCtl2;
	const ST_Slot_Spec_Pict* pPict;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 6; iOrder++) {
		fprintf(fp, "<table>\n");
		fprintf(fp, "<caption>%s[%d]</caption>\n", "TBL_StpCtl2", iOrder);
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 停止済リール */
		iReel2 = Slot_GetOrderReel(iOrder, 1); /* 停止中リール */
		/* 停止済リールの各停止位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			/* 停止中リールの各押下位置について… */
			for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
				pStpCtl2 = &pBuilder->TBL_StpCtl2[iOrder][aPictPos[iReel1]][aPictPos[iReel2]];
				fprintf(fp, "<tr>");
				  fprintf(fp, "<td>");
				    fprintf(fp, "%2d", aPictPos[iReel1]);							//停止済リール停止位置
				    fprintf(fp, " ");
				    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel1], iReel1)];
				    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
				      fprintf(fp, "%s", pPict->pName);								//停止済リール停止絵柄
				    fprintf(fp, "</font>");
				    fprintf(fp, " ");
				    fprintf(fp, "%2d", aPictPos[iReel2]);							//停止中リール押下位置
				    fprintf(fp, " ");
				    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel2], iReel2)];
				    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
				      fprintf(fp, "%s", pPict->pName);								//停止中リール押下絵柄
				    fprintf(fp, "</font>");
				  fprintf(fp, "</td>");
				  /* 各条件装置について… */
				  fprintf(fp, "<td>");
				    for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
				    	if(iHitCd) { fprintf(fp, " "); }
				    	fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[TBL_Slot_Spec_HkmCnt_Color[pStpCtl2->aHkmCnt[iHitCd]]]);
				    	  fprintf(fp, "%d", pStpCtl2->aHkmCnt[iHitCd]);						//引込駒数
				    	fprintf(fp, "</font>");
				    }
				  fprintf(fp, "</td>");
				fprintf(fp, "</tr>\n");
			}
		}
		fprintf(fp, "</table>\n");
	}
}
/*--------------------------------------------------------------------------*
 *	3リール停止制御
 *--------------------------------------------------------------------------*/
/* 3リール停止制御データを作成する。
 * [in]
 *	pBuilder	スペックデータビルダ
 * [out]
 *	無し
 */
static void Slot_Spec_BuildStpCtl3(ST_Slot_Spec_Builder* pBuilder) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iReel2, iReel3, iHitCd, nHkmCnt, Priority;
	ST_Slot_StpCtl3* pStpCtl3;
	const ST_Slot_HitChk3* pHitChk3;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 6; iOrder++) {
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 停止済リール1 */
		iReel2 = Slot_GetOrderReel(iOrder, 1); /* 停止済リール2 */
		iReel3 = Slot_GetOrderReel(iOrder, 2); /* 停止中リール */
		/* 停止済リール1の各停止位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			/* 停止済リール2の各停止位置について… */
			for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
				/* 停止中リールの各押下位置について… */
				for(aPictPos[iReel3] = 0; aPictPos[iReel3] < 21; aPictPos[iReel3]++) {
					pStpCtl3 = &pBuilder->TBL_StpCtl3[iOrder][aPictPos[iReel1]][aPictPos[iReel2]][aPictPos[iReel3]];
					/* 各条件装置について… */
					for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
						Priority = 0;;
						pStpCtl3->aHkmCnt[iHitCd] = 5;	/* 停止不可としておく。 */
						/* 停止済リール1と停止済リール2の停止位置が、停止可能ならば… */
						if(pBuilder->TBL_StpCtl2[iOrder][aPictPos[iReel1]][aPictPos[iReel2]].aStpFlg[iHitCd]) {
							/* 最大引込駒数を取得する。 */
							nHkmCnt = (strstr(pInfo->TBL_HitCd[iHitCd].pName, "全小役") && (iReel3 == pInfo->CT_Reel)) ? 1 : 4;
							/* 各引込駒数について… */
							do {
								/* 3リール入賞判定データを取得する */
								switch(iReel3) {
								case 0: pHitChk3 = &pBuilder->TBL_HitChk3[Slot_Spec_GetPictPos_Hkm(aPictPos[0], nHkmCnt)][                         aPictPos[1]          ][                         aPictPos[2]          ]; break;
								case 1: pHitChk3 = &pBuilder->TBL_HitChk3[                         aPictPos[0]          ][Slot_Spec_GetPictPos_Hkm(aPictPos[1], nHkmCnt)][                         aPictPos[2]          ]; break;
								case 2: pHitChk3 = &pBuilder->TBL_HitChk3[                         aPictPos[0]          ][                         aPictPos[1]          ][Slot_Spec_GetPictPos_Hkm(aPictPos[2], nHkmCnt)]; break;
								default: DIE();
								}
								/* 停止可能ならば… */
								if(pHitChk3->aPriority[iHitCd]) {
									/* 引込駒数を選択する:
									 * ・優先度が大きければ、選択する。
									 * ・優先度が同じならば、引込駒数が小さい方を選択する。即ち、ループの後方優先で上書きする。
									 */
									if(pHitChk3->aPriority[iHitCd] >= Priority) {
										Priority = pHitChk3->aPriority[iHitCd];
										pStpCtl3->aHkmCnt[iHitCd] = nHkmCnt;
									}
								}
							} while(--nHkmCnt >= 0);
							/* 全ての引込駒数で停止不可ならば、設計ミスである。 */
							if(pStpCtl3->aHkmCnt[iHitCd] == 5) { DIE(); }
							/* 実際に停止する停止位置に、停止可能をマークする。 */
							pBuilder->TBL_StpCtl3[iOrder][aPictPos[iReel1]][aPictPos[iReel2]][Slot_Spec_GetPictPos_Hkm(aPictPos[iReel3], pStpCtl3->aHkmCnt[iHitCd])].aStpFlg[iHitCd] = 1;
						}
					}
				}
			}
		}
	}
}
/*--------------------------------------------------------------------------*/
/* 3リール停止制御データをHTML出力する。
 * [in]
 *	pBuilder	スペックデータビルダ
 *	fp		出力ストリーム
 * [out]
 *	無し
 */
static void Slot_Spec_PrintStpCtl3(ST_Slot_Spec_Builder* pBuilder, FILE* fp) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iReel2, iReel3, iHitCd;
	const ST_Slot_StpCtl3* pStpCtl3;
	const ST_Slot_Spec_Pict* pPict;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 6; iOrder++) {
		fprintf(fp, "<table>\n");
		fprintf(fp, "<caption>%s[%d]</caption>\n", "TBL_StpCtl3", iOrder);
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 停止済リール1 */
		iReel2 = Slot_GetOrderReel(iOrder, 1); /* 停止済リール2 */
		iReel3 = Slot_GetOrderReel(iOrder, 2); /* 停止中リール */
		/* 停止済リール1の各停止位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			/* 停止済リール2の各停止位置について… */
			for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
				/* 停止中リールの各押下位置について… */
				for(aPictPos[iReel3] = 0; aPictPos[iReel3] < 21; aPictPos[iReel3]++) {
					pStpCtl3 = &pBuilder->TBL_StpCtl3[iOrder][aPictPos[iReel1]][aPictPos[iReel2]][aPictPos[iReel3]];
					fprintf(fp, "<tr>");
					  fprintf(fp, "<td>");
					    fprintf(fp, "%2d", aPictPos[iReel1]);						//停止済リール1停止位置
					    fprintf(fp, " ");
					    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel1], iReel1)];
					    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
					      fprintf(fp, "%s", pPict->pName);							//停止済リール1停止絵柄
					    fprintf(fp, "</font>");
					    fprintf(fp, " ");
					    fprintf(fp, "%2d", aPictPos[iReel2]);						//停止済リール2停止位置
					    fprintf(fp, " ");
					    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel2], iReel2)];
					    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
					      fprintf(fp, "%s", pPict->pName);							//停止済リール2停止絵柄
					    fprintf(fp, "</font>");
					    fprintf(fp, " ");
					    fprintf(fp, "%2d", aPictPos[iReel3]);						//停止中リール停止位置
					    fprintf(fp, " ");
					    pPict = &pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[iReel3], iReel3)];
					    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pPict->iColor]);
					      fprintf(fp, "%s", pPict->pName);							//停止中リール停止絵柄
					    fprintf(fp, "</font>");
					  fprintf(fp, "</td>");
					  /* 各条件装置について… */
					  fprintf(fp, "<td>");
					    for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
					    	if(iHitCd) { fprintf(fp, " "); }
					    	fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[TBL_Slot_Spec_HkmCnt_Color[pStpCtl3->aHkmCnt[iHitCd]]]);
					    	  fprintf(fp, "%d", pStpCtl3->aHkmCnt[iHitCd]);					//引込駒数
					    	fprintf(fp, "</font>");
					    }
					  fprintf(fp, "</td>");
					fprintf(fp, "</tr>\n");
				}
			}
		}
		fprintf(fp, "</table>\n");
	}
}
/*--------------------------------------------------------------------------*
 *	停止制御テスト
 *--------------------------------------------------------------------------*/
/* 停止テストを実行する。
 * [in]
 *	pBuilder	スペックデータビルダ
 * [out]
 *	無し
 */
static void Slot_Spec_BuildStpTst(ST_Slot_Spec_Builder* pBuilder) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iReel2, iReel3, iHitCd, iOrder1, iOrder2, iOrder3, aStopPos[3];
	ST_Slot_StpTst* pStpTst;
	const ST_Slot_StpCtl1* pStpCtl1;
	const ST_Slot_StpCtl2* pStpCtl2;
	const ST_Slot_StpCtl3* pStpCtl3;
	const ST_Slot_HitChk3* pHitChk3;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 6; iOrder++) {
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 第1停止リール */
		iReel2 = Slot_GetOrderReel(iOrder, 1); /* 第2停止リール */
		iReel3 = Slot_GetOrderReel(iOrder, 2); /* 第3停止リール */
		/* 第1停止リールの各押下位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			/* 第2停止リールの各押下位置について… */
			for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
				/* 第3停止リールの各押下位置について… */
				for(aPictPos[iReel3] = 0; aPictPos[iReel3] < 21; aPictPos[iReel3]++) {
					pStpTst = &pBuilder->TBL_StpTst[iOrder][aPictPos[iReel1]][aPictPos[iReel2]][aPictPos[iReel3]];
					/* 各条件装置について… */
					for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
						/* 1リール停止制御データと2リール停止制御データと3リール停止制御データの押順番号を取得する。 */
						iOrder1 = iOrder % 3;	/* 0,1,2,0,1,2 */
						iOrder2 = iOrder;	/* 0,1,2,3,4,5 */
						iOrder3 = iOrder;	/* 0,1,2,3,4,5 */
						/* 第1停止リールの引込駒数を格納する。 */
						pStpCtl1 = &pBuilder->TBL_StpCtl1[iOrder1][aPictPos[iReel1]];
						pStpTst->aHkmCnt[iHitCd][iReel1] = pStpCtl1->aHkmCnt[iHitCd];
						if(pStpTst->aHkmCnt[iHitCd][iReel1] > 4) { DIE(); }
						aStopPos[iReel1] = Slot_Spec_GetPictPos_Hkm(aPictPos[iReel1], pStpTst->aHkmCnt[iHitCd][iReel1]);
						/* 第2停止リールの引込駒数を格納する。 */
						pStpCtl2 = &pBuilder->TBL_StpCtl2[iOrder2][aStopPos[iReel1]][aPictPos[iReel2]];
						pStpTst->aHkmCnt[iHitCd][iReel2] = pStpCtl2->aHkmCnt[iHitCd];
						if(pStpTst->aHkmCnt[iHitCd][iReel2] > 4) { DIE(); }
						aStopPos[iReel2] = Slot_Spec_GetPictPos_Hkm(aPictPos[iReel2], pStpTst->aHkmCnt[iHitCd][iReel2]);
						/* 第3停止リールの引込駒数を格納する。 */
						pStpCtl3 = &pBuilder->TBL_StpCtl3[iOrder3][aStopPos[iReel1]][aStopPos[iReel2]][aPictPos[iReel3]];
						pStpTst->aHkmCnt[iHitCd][iReel3] = pStpCtl3->aHkmCnt[iHitCd];
						if(pStpTst->aHkmCnt[iHitCd][iReel3] > 4) { DIE(); }
						aStopPos[iReel3] = Slot_Spec_GetPictPos_Hkm(aPictPos[iReel3], pStpTst->aHkmCnt[iHitCd][iReel3]);
						/* 3リール入賞判定データを取得する */
						pHitChk3 = &pBuilder->TBL_HitChk3[aStopPos[0]][aStopPos[1]][aStopPos[2]];
						/* 優先度を取得する。 */
						pStpTst->aPriority[iHitCd] = pHitChk3->aPriority[iHitCd];
						if(!pStpTst->aPriority[iHitCd]) { DIE(); }
					}
				}
			}
		}
	}
}
/*--------------------------------------------------------------------------*/
/* 停止テストの結果をHTML出力する。
 * [in]
 *	pBuilder	スペックデータビルダ
 *	fp		出力ストリーム
 * [out]
 *	無し
 */
static void Slot_Spec_PrintStpTst(ST_Slot_Spec_Builder* pBuilder, FILE* fp) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iReel2, iReel3, iHitCd;
	const ST_Slot_StpTst* pStpTst;
	/* 各押順について… */
	for(iOrder = 0; iOrder < 6; iOrder++) {
		fprintf(fp, "<table>\n");
		fprintf(fp, "<caption>%s[%d]</caption>\n", "TBL_StpTst", iOrder);
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 第1停止リール */
		iReel2 = Slot_GetOrderReel(iOrder, 1); /* 第2停止リール */
		iReel3 = Slot_GetOrderReel(iOrder, 2); /* 第3停止リール */
		/* 第1停止リールの各押下位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			/* 第2停止リールの各押下位置について… */
			for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
				/* 第3停止リールの各押下位置について… */
				for(aPictPos[iReel3] = 0; aPictPos[iReel3] < 21; aPictPos[iReel3]++) {
					pStpTst = &pBuilder->TBL_StpTst[iOrder][aPictPos[iReel1]][aPictPos[iReel2]][aPictPos[iReel3]];
					fprintf(fp, "<tr>");
					  fprintf(fp, "<td>%2d %2d %2d</td>", aPictPos[iReel1],					//第1停止リールの押下位置
					                                      aPictPos[iReel2],					//第2停止リールの押下位置
					                                      aPictPos[iReel3]);				//第3停止リールの押下位置
					  /* 各条件装置について… */
					  for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
					  	fprintf(fp, "<td>");
					  	  fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[0]);
					  	    fprintf(fp, "%d %d %d", pStpTst->aHkmCnt[iHitCd][iReel1],			//第1停止リールの引込駒数
					  	                            pStpTst->aHkmCnt[iHitCd][iReel2],			//第2停止リールの引込駒数
					  	                            pStpTst->aHkmCnt[iHitCd][iReel3]);			//第3停止リールの引込駒数
					  	  fprintf(fp, "</font>");
					  	  fprintf(fp, " ");
					  	  fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[1]);
					  	    fprintf(fp, "%d", pStpTst->aPriority[iHitCd]);				//優先度
					  	  fprintf(fp, "</font>");
					  	fprintf(fp, "</td>");
					  }
					fprintf(fp, "</tr>\n");
				}
			}
		}
		fprintf(fp, "</table>\n");
	}
}
/*--------------------------------------------------------------------------*
 *	絵柄組合せテスト
 *--------------------------------------------------------------------------*/
/* 絵柄組合せテストを実行する。
 * [in]
 *	pBuilder	スペックデータビルダ
 * [out]
 *	無し
 */
static void Slot_Spec_BuildCmbTst(ST_Slot_Spec_Builder* pBuilder) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int aPictPos[3], iOrder, iReel1, iReel2, iReel3, iHitCd, iHitFlg, iLine, nStpCntSum, aStopPos[3];
	ST_Slot_CmbTst* pCmbTst;
	const ST_Slot_StpTst* pStpTst;
	const ST_Slot_HitChk3* pHitChk3;
	const ST_Slot_Spec_HitFlg* pHitFlg;
	/* 左リールの各絵柄位置について… */
	for(aPictPos[0] = 0; aPictPos[0] < 21; aPictPos[0]++) {
		/* 中リールの各絵柄位置について… */
		for(aPictPos[1] = 0; aPictPos[1] < 21; aPictPos[1]++) {
			/* 右リールの各絵柄位置について… */
			for(aPictPos[2] = 0; aPictPos[2] < 21; aPictPos[2]++) {
				/* 絵柄組合せ番号を取得する。 */
				iHitFlg = Slot_Spec_FindHitFlg(pBuilder,
					Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[0], 0),
					Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[1], 1),
					Slot_GetReelPict(pInfo->TBL_Reel, aPictPos[2], 2));
				/* 絵柄組合せ個数を加算する。 */
				pCmbTst = &pBuilder->TBL_CmbTst[iHitFlg];
				pCmbTst->nCmbCnt++;
			}
		}
	}
	/* 各押順について… */
	for(iOrder = 0; iOrder < 6; iOrder++) {
		iReel1 = Slot_GetOrderReel(iOrder, 0); /* 第1停止リール */
		iReel2 = Slot_GetOrderReel(iOrder, 1); /* 第2停止リール */
		iReel3 = Slot_GetOrderReel(iOrder, 2); /* 第3停止リール */
		/* 第1停止リールの各押下位置について… */
		for(aPictPos[iReel1] = 0; aPictPos[iReel1] < 21; aPictPos[iReel1]++) {
			/* 第2停止リールの各押下位置について… */
			for(aPictPos[iReel2] = 0; aPictPos[iReel2] < 21; aPictPos[iReel2]++) {
				/* 第3停止リールの各押下位置について… */
				for(aPictPos[iReel3] = 0; aPictPos[iReel3] < 21; aPictPos[iReel3]++) {
					pStpTst = &pBuilder->TBL_StpTst[iOrder][aPictPos[iReel1]][aPictPos[iReel2]][aPictPos[iReel3]];
					/* 各条件装置について… */
					for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
						/* 第1停止リールの停止位置を取得する。 */
						if(pStpTst->aHkmCnt[iHitCd][iReel1] > 4) { DIE(); }
						aStopPos[iReel1] = Slot_Spec_GetPictPos_Hkm(aPictPos[iReel1], pStpTst->aHkmCnt[iHitCd][iReel1]);
						/* 第2停止リールの停止位置を取得する。 */
						if(pStpTst->aHkmCnt[iHitCd][iReel2] > 4) { DIE(); }
						aStopPos[iReel2] = Slot_Spec_GetPictPos_Hkm(aPictPos[iReel2], pStpTst->aHkmCnt[iHitCd][iReel2]);
						/* 第3停止リールの停止位置を取得する。 */
						if(pStpTst->aHkmCnt[iHitCd][iReel3] > 4) { DIE(); }
						aStopPos[iReel3] = Slot_Spec_GetPictPos_Hkm(aPictPos[iReel3], pStpTst->aHkmCnt[iHitCd][iReel3]);
						/* 3リール入賞判定データを取得する */
						pHitChk3 = &pBuilder->TBL_HitChk3[aStopPos[0]][aStopPos[1]][aStopPos[2]];
						/* 各ラインについて… */
						for(iLine = 0; iLine < 5; iLine++) {
							/* 絵柄組合せ表示回数を増やす。 */
							if((unsigned)pHitChk3->iHitFlg[iLine] >= (unsigned)pInfo->SIZE_HitFlg) { DIE(); }
							pCmbTst = &pBuilder->TBL_CmbTst[pHitChk3->iHitFlg[iLine]];
							pCmbTst->aStpCnt[iHitCd][iLine]++;
						}
					}
				}
			}
		}
	}
	/* 各絵柄組合せについて… */
	for(iHitFlg = 0; iHitFlg < pInfo->SIZE_HitFlg; iHitFlg++) {
		pCmbTst = &pBuilder->TBL_CmbTst[iHitFlg];	/* 絵柄組合せ個数 */
		pHitFlg = &pInfo->TBL_HitFlg[iHitFlg];		/* 絵柄組合せ表示回数 */
		/* 各条件装置について… */
		for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
			/* 各ラインについて… */
			nStpCntSum = 0;			/* 絵柄組合せ表示回数の合計 */
			for(iLine = 0; iLine < 5; iLine++) {
				/* 絵柄組合せ表示回数の合計を加算する。 */
				nStpCntSum += pCmbTst->aStpCnt[iHitCd][iLine];
			}
			/* この条件装置で、この絵柄組合せが表示されるならば… */
			if(nStpCntSum) {
				/* この条件装置に、この絵柄組合せが含まれるならば… */
				if(pHitFlg->aPriority[iHitCd]) {
					pCmbTst->aResult[iHitCd] = 0;	/* 正常 */
				/* この条件装置に、この絵柄組合せが含まれないならば… */
				} else {
					pCmbTst->aResult[iHitCd] = 1;	/* エラー:条件装置に含まれないのに表示された */
					fprintf(stderr, "###Slot_BuildCmbTst: 条件装置番号%d,絵柄組合せ番号%dにて「エラー:条件装置に含まれないのに表示された」が発生しました。\n", iHitCd, iHitFlg);
				}
			/* この条件装置で、この絵柄組合せが表示されないならば… */
			} else {
				/* この条件装置に、この絵柄組合せが含まれるならば… */
				if(pHitFlg->aPriority[iHitCd]) {
					pCmbTst->aResult[iHitCd] = 2;	/* 警告:条件装置に含まれるのに表示されなかった */
					if(iHitCd != (pInfo->SIZE_HitCd-1)/*全小役*/) { /* 条件装置が全小役ならば、厳密には条件装置に絵柄組合せは定義されないので、警告を表示しない。表示しても構わないが、警告表示が増えすぎる。 */
						fprintf(stderr, "###Slot_BuildCmbTst: 条件装置番号%d,絵柄組合せ番号%dにて「警告:条件装置に含まれるのに表示されなかった」が発生しました。\n", iHitCd, iHitFlg);
					}
				/* この条件装置に、この絵柄組合せが含まれないならば… */
				} else {
					pCmbTst->aResult[iHitCd] = 0;	/* 正常 */
				}
			}
		}
	}
}
/*--------------------------------------------------------------------------*/
/* 絵柄組合せテストの結果をHTML出力する。
 * [in]
 *	pBuilder	スペックデータビルダ
 *	fp		出力ストリーム
 * [out]
 *	無し
 */
static void Slot_Spec_PrintCmbTst(ST_Slot_Spec_Builder* pBuilder, FILE* fp) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int iHitFlg, iHitCd, iReel, iLine, aStpCntSum[5/*iLine*/], nCmbCntSum = 0;	/* 払出の有る小役の絵柄組合せ個数の合計 */
	const ST_Slot_CmbTst* pCmbTst;
	const ST_Slot_Spec_HitFlg* pHitFlg;
	fprintf(fp, "<table>\n");
	fprintf(fp, "<caption>%s</caption>\n", "TBL_CmbTst");
	/* 列ヘッダを表示する。 */
	fprintf(fp, "<tr>");
	  fprintf(fp, "<th></th>");
	  fprintf(fp, "<th></th>");
	  for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
	  	fprintf(fp, "<th>");
	  	  fprintf(fp, "%2d", iHitCd);											//条件装置番号
	  	  fprintf(fp, " ");
	  	  fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pInfo->TBL_HitCd[iHitCd].iColor]);
	  	    fprintf(fp, "%s",  pInfo->TBL_HitCd[iHitCd].pName);								//条件装置
	  	  fprintf(fp, "</font>");
	  	fprintf(fp, "</th>");
	  }
	  fprintf(fp, "<th align=center>合計</th>");
	fprintf(fp, "</tr>");
	/* 各絵柄組合せについて… */
	for(iHitFlg = 0; iHitFlg < pInfo->SIZE_HitFlg; iHitFlg++) {
		pCmbTst = &pBuilder->TBL_CmbTst[iHitFlg];
		pHitFlg = &pInfo->TBL_HitFlg[iHitFlg];
		fprintf(fp, "<tr>");
		  fprintf(fp, "<td>");
		    fprintf(fp, "%2d", iHitFlg);										//絵柄組合せ番号
		    for(iReel = 0; iReel < 3; iReel++) {
		    	fprintf(fp, " ");
		    	fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pInfo->TBL_Pict[pHitFlg->aPict[iReel]].iColor]);
		    	  fprintf(fp, "%s", pInfo->TBL_Pict[pHitFlg->aPict[iReel]].pName);					//絵柄組合せ
		    	fprintf(fp, "</font>");
		    }
		    fprintf(fp, " ");
		    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pHitFlg->nPay ? 7 : 0]);
		      fprintf(fp, "%2d", pHitFlg->nPay);									//払出枚数
		    fprintf(fp, "</font>");
		  fprintf(fp, "</td>");
		  //絵柄組合せ個数を表示する。
		  fprintf(fp, "<td>");
		    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pHitFlg->nPay ? 7 : 0]);
		      fprintf(fp, "%4d", pCmbTst->nCmbCnt);									//絵柄組合せ個数
		      if(pHitFlg->nPay) { nCmbCntSum += pCmbTst->nCmbCnt; }		/* 払出の有る小役の絵柄組合せ個数の合計を加算する。 */
		    fprintf(fp, "</font>");
		  fprintf(fp, "</td>");
		  /* 絵柄組合せ表示回数の合計をクリアする。 */
		  memset(aStpCntSum, 0, sizeof aStpCntSum);
		  /* 各条件装置について… */
		  for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
		  	fprintf(fp, "<td>");
		  	  fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[TBL_Slot_Spec_Result_Color[pCmbTst->aResult[iHitCd]]]);
		  	    fprintf(fp, "%s", TBL_Slot_Spec_Result_Mark[pCmbTst->aResult[iHitCd]]);				//検査結果
		  	  fprintf(fp, "</font>");
		  	  /* 各ラインについて… */
		  	  for(iLine = 0; iLine < 5; iLine++) {
		  	  	fprintf(fp, " ");
		  	  	fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[pCmbTst->aStpCnt[iHitCd][iLine] ? 7 : 0]);
		  	  	  fprintf(fp, "%5d", pCmbTst->aStpCnt[iHitCd][iLine]);						//絵柄組合せ表示回数
		  	  	fprintf(fp, "</font>");
		  	  	aStpCntSum[iLine] += pCmbTst->aStpCnt[iHitCd][iLine];	/* 絵柄組合せ表示回数の合計を加算する。 */
		  	  }
		  	fprintf(fp, "</td>");
		  }
		  /* 絵柄組合せ表示回数の合計を表示する。 */
		  fprintf(fp, "<td>");
		    for(iLine = 0; iLine < 5; iLine++) {
		    	if(iLine) { fprintf(fp, " "); }
		    	fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[aStpCntSum[iLine] ? 7 : 0]);
		    	  fprintf(fp, "%6d", aStpCntSum[iLine]);								//絵柄組合せ表示回数の合計
		    	fprintf(fp, "</font>");
		    }
		  fprintf(fp, "</td>");
		fprintf(fp, "</tr>\n");
	}
	/* 絵柄組合せ個数の合計を表示する。
	 * ■「遊技機の認定及び型式の検定等に関する規則 別表第5 回胴式遊技機に係る技術上の規格(1)性能に関する規格」から要約:
	 * □BBの絵柄組合わせ
	 * ・BBの払出枚数が360枚以下(≒CT搭載有り)の場合、BBの絵柄組合せが、(21^3)/(2/1500)以下であること。即ち、最大12通り。		(当機種には関係無い)
	 * ・BBの払出枚数が360枚超過(≒CT搭載無し)の場合、BBの絵柄組合せが、(21^3)/(1/1500)以下であること。即ち、最大 6通り。		(当機種には関係無い)
	 * □RB&JACの絵柄組合わせ
	 * ・BB搭載有りの場合、RBの絵柄組合せが、(21^3)*(1/500)以下であること。即ち、最大18通り。					(当機種には関係無い)
	 * 　BB搭載無しの場合、RBの絵柄組合せが、(21^3)*(3/500)以下であること。即ち、最大55通り。					(当機種には関係無い)
	 * ・RBがJACIN有りの場合、JACINの絵柄組合せが、(21^3)/(10/500)以下であること。即ち、最大185通り。				(当機種には関係無い)
	 * □CTの絵柄組合わせ
	 * ・CTの絵柄組合せには、制限が無い。
	 * □小役の絵柄組合せ
	 * ・払出の有る小役の絵柄組合せが、(21^3)/(11/100)超過,かつ,(21^3)/(40/100)以下であること。即ち、最小1019,最大3704通り。	←この点をテストする
	 * ・リプレイの絵柄組合わせには、制限が無い。
	 */
	fprintf(fp, "<tr>");
	  fprintf(fp, "<td align=center>1019≦合計≦3704</td>");
	  fprintf(fp, "<td>");
	    fprintf(fp, "<font color=%s>", TBL_Slot_Spec_Color[((nCmbCntSum >= 1019) && (nCmbCntSum <= 3704)) ? 7 : 1]);
	      fprintf(fp, "%4d", nCmbCntSum);											//払出の有る小役の絵柄組合せ個数の合計
	    fprintf(fp, "</font>");
	  fprintf(fp, "</td>");
	  fprintf(fp, "<td colspan=%d></td>", pInfo->SIZE_HitCd+1);
	fprintf(fp, "</tr>\n");
	fprintf(fp, "</table>\n");
}
/*--------------------------------------------------------------------------*
 *	データ作成
 *--------------------------------------------------------------------------*/
static void Slot_Spec_BuildData(ST_Slot_Spec_Builder* pBuilder) {
	static const struct {
		const char* HtmlFileName;
		void (*pfnBuild)(ST_Slot_Spec_Builder* pBuilder);
		void (*pfnPrint)(ST_Slot_Spec_Builder* pBuilder, FILE* fp);
	} tbl[]={
		/* データ作成準備 */
		{"HitChk3.html",&Slot_Spec_BuildHitChk3,&Slot_Spec_PrintHitChk3},	//3リール入賞判定
		{"HitChk2.html",&Slot_Spec_BuildHitChk2,&Slot_Spec_PrintHitChk2},	//2リール入賞予測
		{"HitChk1.html",&Slot_Spec_BuildHitChk1,&Slot_Spec_PrintHitChk1},	//1リール入賞予測
		/* データ作成 */
		{"StpCtl1.html",&Slot_Spec_BuildStpCtl1,&Slot_Spec_PrintStpCtl1},	//1リール停止制御
		{"StpCtl2.html",&Slot_Spec_BuildStpCtl2,&Slot_Spec_PrintStpCtl2},	//2リール停止制御
		{"StpCtl3.html",&Slot_Spec_BuildStpCtl3,&Slot_Spec_PrintStpCtl3},	//3リール停止制御
		/* テスト */
		{"StpTst.html",&Slot_Spec_BuildStpTst,&Slot_Spec_PrintStpTst},		//停止制御テスト
		{"CmbTst.html",&Slot_Spec_BuildCmbTst,&Slot_Spec_PrintCmbTst},		//絵柄組合せテスト
	};
	FILE* fp;
	int i;
	for(i = 0; i < ARRAY_SIZE(tbl); i++) {
		fp = fopen(tbl[i].HtmlFileName, "w");
		if(!fp) { DIE(); }
		/* データ作成準備・データ作成・テスト */
		(*tbl[i].pfnBuild)(pBuilder);
		/* HTMLヘッダ出力 */
		fprintf(fp, "<html>\n");
		fprintf(fp, "<head>\n");
		fprintf(fp, "  <style type=\"text/css\">\n");
		fprintf(fp, "    *{font-family:\"MS Mincho\";font-size:12px}\n");
		fprintf(fp, "    *{white-space:pre}\n");
		fprintf(fp, "    body{color:white;background-color:black}\n");
		fprintf(fp, "    table,caption,th,td{border-width:1px;border-style:solid;border-collapse:collapse}\n");
		fprintf(fp, "  </style>\n");
		fprintf(fp, "</head>\n");
		fprintf(fp, "<body>\n");
		/* HTMLボディ出力 */
		(*tbl[i].pfnPrint)(pBuilder, fp);
		/* HTMLフッタ出力 */
		fprintf(fp, "</body>\n");
		fprintf(fp, "</html>\n");
		fclose(fp);
	}
	/* HTMLインデクスページ出力 */
	fp = fopen("index.html", "w");
	if(!fp) { DIE(); }
	fprintf(fp, "<html>\n");
	fprintf(fp, "<body>\n");
	fprintf(fp, "<table>\n");
	for(i = 0; i < ARRAY_SIZE(tbl); i++) {
		struct stat st;
		if(stat(tbl[i].HtmlFileName, &st)) { DIE(); }
		fprintf(fp, "<tr><td><a href=\"%s\">%s</td><td align=right>%d</td></tr>\n", tbl[i].HtmlFileName, tbl[i].HtmlFileName, (int)st.st_size);
	}
	fprintf(fp, "</table>\n");
	fprintf(fp, "</body>\n");
	fprintf(fp, "</html>\n");
	fclose(fp);
}
/*--------------------------------------------------------------------------*
 *	データ出力
 *--------------------------------------------------------------------------*/
/* 絵柄 */
static void Slot_Spec_PrintData_Pict(ST_Slot_Spec_Builder* pBuilder, FILE* fpH, FILE* fpC) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	const ST_Slot_Spec_Pict* pPict;
	int iPict;
	for(iPict = 0; iPict < pInfo->SIZE_Pict; iPict++) {
		pPict = &pInfo->TBL_Pict[iPict];
		fprintf(fpH, "#define Pict_%s %2d//%s\n",
			pPict->pSym, iPict, pPict->pName);
	}
	fprintf(fpH, "#define Pict_Size %d\n", pInfo->SIZE_Pict);
	//
	fprintf(fpC, "#ifdef  USE_NAME\n");
	fprintf(fpH, "#ifdef  USE_NAME\n");
	fprintf(fpC, "const char* const TBL_Pict_Name[Pict_Size]={\n");
	for(iPict = 0; iPict < pInfo->SIZE_Pict; iPict++) {
		pPict = &pInfo->TBL_Pict[iPict];
		fprintf(fpC, "\"%s\",//%2d %s\n",
			pPict->pName,
			iPict, pPict->pSym);
	}
	fprintf(fpC, "};\n");
	fprintf(fpH, "extern const char* const TBL_Pict_Name[Pict_Size];\n");
	fprintf(fpC, "#endif//USE_NAME\n");
	fprintf(fpH, "#endif//USE_NAME\n");
}
/*--------------------------------------------------------------------------*/
/* リール配列 */
static void Slot_Spec_PrintData_Reel(ST_Slot_Spec_Builder* pBuilder, FILE* fpH, FILE* fpC) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	int iPictPos;
	fprintf(fpH, "#define Reel_CT %d\n", pInfo->CT_Reel);
	//
	fprintf(fpC, "const unsigned short TBL_Reel[21]={\n");
	for(iPictPos = 0; iPictPos < 21; iPictPos++) {
		fprintf(fpC, "%2d<<0|%2d<<4|%2d<<8,//%2d %s %s %s\n",
			Slot_GetReelPict(pInfo->TBL_Reel, iPictPos, 0),
			Slot_GetReelPict(pInfo->TBL_Reel, iPictPos, 1),
			Slot_GetReelPict(pInfo->TBL_Reel, iPictPos, 2),
			iPictPos,
			pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, iPictPos, 0)].pName,
			pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, iPictPos, 1)].pName,
			pInfo->TBL_Pict[Slot_GetReelPict(pInfo->TBL_Reel, iPictPos, 2)].pName);
	}
	fprintf(fpC, "};\n");
	fprintf(fpH, "extern const unsigned short TBL_Reel[21];\n");
}
/*--------------------------------------------------------------------------*/
/* 条件装置 */
static void Slot_Spec_PrintData_HitCd(ST_Slot_Spec_Builder* pBuilder, FILE* fpH, FILE* fpC) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	const ST_Slot_Spec_HitCd* pHitCd;
	int iHitCd;
	fprintf(fpC, "const unsigned short TBL_HitCd[HitCd_Size][6]={\n");
	for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
		pHitCd = &pInfo->TBL_HitCd[iHitCd];
		fprintf(fpH, "#define HitCd_%s %2d//%s\n",
			pHitCd->pSym, iHitCd, pHitCd->pName);
		fprintf(fpC, "{%5d,%5d,%5d,%5d,%5d,%5d},//%2d %s %s\n",
			pHitCd->aWeight[0], pHitCd->aWeight[1], pHitCd->aWeight[2], pHitCd->aWeight[3], pHitCd->aWeight[4], pHitCd->aWeight[5],
			iHitCd, pHitCd->pSym, pHitCd->pName);
	}
	fprintf(fpC, "};\n");
	fprintf(fpH, "#define HitCd_Size %d\n", pInfo->SIZE_HitCd);
	fprintf(fpH, "extern const unsigned short TBL_HitCd[HitCd_Size][6];\n");
	//
	fprintf(fpC, "#ifdef  USE_NAME\n");
	fprintf(fpH, "#ifdef  USE_NAME\n");
	fprintf(fpC, "const char* const TBL_HitCd_Name[HitCd_Size]={\n");
	for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
		pHitCd = &pInfo->TBL_HitCd[iHitCd];
		fprintf(fpC, "\"%s\",//%2d %s\n",
			pHitCd->pName,
			iHitCd, pHitCd->pSym);
	}
	fprintf(fpC, "};\n");
	fprintf(fpH, "extern const char* const TBL_HitCd_Name[HitCd_Size];\n");
	fprintf(fpC, "#endif//USE_NAME\n");
	fprintf(fpH, "#endif//USE_NAME\n");
}
/*--------------------------------------------------------------------------*/
/* 絵柄組合せ */
static void Slot_Spec_PrintData_HitFlg(ST_Slot_Spec_Builder* pBuilder, FILE* fpH, FILE* fpC) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	const ST_Slot_Spec_HitFlg* pHitFlg;
	int iHitFlg, nNameLen = strlen(pInfo->TBL_Pict[0].pName);
	fprintf(fpC, "const unsigned short TBL_HitFlg[HitFlg_Size]={\n");
	for(iHitFlg = 0; iHitFlg < pInfo->SIZE_HitFlg; iHitFlg++) {
		pHitFlg = &pInfo->TBL_HitFlg[iHitFlg];
		fprintf(fpH, "#define HitFlg_%s %2d//%s\n",
			pHitFlg->pSym, iHitFlg, pHitFlg->pName);
		fprintf(fpC, "%2d|%2d<<4|%2d<<8|%2d<<12,//%2d %s %s %-*s %-*s %-*s\n",
			pHitFlg->aPict[0],pHitFlg->aPict[1],pHitFlg->aPict[2],pHitFlg->nPay,
			iHitFlg, pHitFlg->pSym, pHitFlg->pName,
			nNameLen,pHitFlg->aPict[0]?pInfo->TBL_Pict[pHitFlg->aPict[0]].pName:"-",
			nNameLen,pHitFlg->aPict[1]?pInfo->TBL_Pict[pHitFlg->aPict[1]].pName:"-",
			nNameLen,pHitFlg->aPict[2]?pInfo->TBL_Pict[pHitFlg->aPict[2]].pName:"-");

	}
	fprintf(fpC, "};\n");
	fprintf(fpH, "#define HitFlg_Size %d\n", pInfo->SIZE_HitFlg);
	fprintf(fpH, "extern const unsigned short TBL_HitFlg[HitFlg_Size];\n");
	//
	fprintf(fpC, "#ifdef  USE_NAME\n");
	fprintf(fpH, "#ifdef  USE_NAME\n");
	fprintf(fpC, "const char* const TBL_HitFlg_Name[HitFlg_Size]={\n");
	for(iHitFlg = 0; iHitFlg < pInfo->SIZE_HitFlg; iHitFlg++) {
		pHitFlg = &pInfo->TBL_HitFlg[iHitFlg];
		fprintf(fpC, "\"%s\",//%2d %s\n",
			pHitFlg->pName,
			iHitFlg, pHitFlg->pSym);
	}
	fprintf(fpC, "};\n");
	fprintf(fpH, "extern const char* const TBL_HitFlg_Name[HitFlg_Size];\n");
	fprintf(fpC, "#endif//USE_NAME\n");
	fprintf(fpH, "#endif//USE_NAME\n");
}
/*--------------------------------------------------------------------------*/
/* 条件装置⇒絵柄組合せ */
static void Slot_Spec_PrintData_HitCd_HitFlg(ST_Slot_Spec_Builder* pBuilder, FILE* fpH, FILE* fpC) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	const ST_Slot_Spec_HitCd* pHitCd;
	int iHitCd, iHitFlg, x;
	fprintf(fpC, "const unsigned char TBL_HitCd_HitFlg[HitCd_Size][(HitFlg_Size+7)/8]={\n");
	for(iHitCd = 0; iHitCd < pInfo->SIZE_HitCd; iHitCd++) {
		pHitCd = &pInfo->TBL_HitCd[iHitCd];
		x = 0;
		fprintf(fpC, "{");
		for(iHitFlg = 0; iHitFlg < pInfo->SIZE_HitFlg; iHitFlg++) {
			if(pInfo->TBL_HitFlg[iHitFlg].aPriority[iHitCd]) { x |= (1<<(iHitFlg&7)); }
			if(((iHitFlg&7) == 7) || (iHitFlg == (pInfo->SIZE_HitFlg-1))) {
				fprintf(fpC, "%3d", x);
				x = 0;
				if(iHitFlg != (pInfo->SIZE_HitFlg-1)) { fprintf(fpC, ","); }
			}
		}
		fprintf(fpC, "},//%2d %s %s\n",
			iHitCd, pHitCd->pSym, pHitCd->pName);
	}
	fprintf(fpC, "};\n");
	fprintf(fpH, "extern const unsigned char TBL_HitCd_HitFlg[HitCd_Size][(HitFlg_Size+7)/8];\n");
}
/*--------------------------------------------------------------------------*/
/* 停止制御 */
static int Slot_Spec_PrintData_fnGetStpCtl1(void* pParam, int iHitCd, int iReel1, int iPushPos1) {
	ST_Slot_Spec_Builder* pBuilder = pParam;
	const ST_Slot_StpCtl1* pStpCtl1;
	int iOrder = iReel1;
	if((unsigned)iOrder    >= ARRAY_SIZE(pBuilder->TBL_StpCtl1   )) { DIE(); }
	if((unsigned)iPushPos1 >= ARRAY_SIZE(pBuilder->TBL_StpCtl1[0])) { DIE(); }
	pStpCtl1 = &pBuilder->TBL_StpCtl1[iOrder][iPushPos1];
	if((unsigned)pStpCtl1->aHkmCnt[iHitCd] > 4) { DIE(); }
	return pStpCtl1->aHkmCnt[iHitCd];
}
static int Slot_Spec_PrintData_fnGetStpCtl2(void* pParam, int iHitCd, int iReel1, int iReel2, int iStopPos1, int iPushPos2) {
	ST_Slot_Spec_Builder* pBuilder = pParam;
	const ST_Slot_StpCtl2* pStpCtl2;
	int iOrder = Slot_FindOrder(iReel1, iReel2);
	if((unsigned)iOrder    >= ARRAY_SIZE(pBuilder->TBL_StpCtl2      )) { DIE(); }
	if((unsigned)iStopPos1 >= ARRAY_SIZE(pBuilder->TBL_StpCtl2[0]   )) { DIE(); }
	if((unsigned)iPushPos2 >= ARRAY_SIZE(pBuilder->TBL_StpCtl2[0][0])) { DIE(); }
	pStpCtl2 = &pBuilder->TBL_StpCtl2[iOrder][iStopPos1][iPushPos2];
	if((unsigned)pStpCtl2->aHkmCnt[iHitCd] > 4) { DIE(); }
	return pStpCtl2->aHkmCnt[iHitCd];
}
static int Slot_Spec_PrintData_fnGetStpCtl3(void* pParam, int iHitCd, int iReel1, int iReel2, int iReel3, int iStopPos1, int iStopPos2, int iPushPos3) {
	ST_Slot_Spec_Builder* pBuilder = pParam;
	const ST_Slot_StpCtl3* pStpCtl3;
	int iOrder = Slot_FindOrder(iReel1, iReel2);
	if((unsigned)iOrder    >= ARRAY_SIZE(pBuilder->TBL_StpCtl3         )) { DIE(); }
	if((unsigned)iStopPos1 >= ARRAY_SIZE(pBuilder->TBL_StpCtl3[0]      )) { DIE(); }
	if((unsigned)iStopPos2 >= ARRAY_SIZE(pBuilder->TBL_StpCtl3[0][0]   )) { DIE(); }
	if((unsigned)iPushPos3 >= ARRAY_SIZE(pBuilder->TBL_StpCtl3[0][0][0])) { DIE(); }
	pStpCtl3 = &pBuilder->TBL_StpCtl3[iOrder][iStopPos1][iStopPos2][iPushPos3];
	if((unsigned)pStpCtl3->aHkmCnt[iHitCd] > 4) { DIE(); }
	return pStpCtl3->aHkmCnt[iHitCd];
}
static void Slot_Spec_PrintData_StpCtl(ST_Slot_Spec_Builder* pBuilder, FILE* fpH, FILE* fpC) {
	const ST_Slot_SpecInfo* pInfo = pBuilder->pInfo;
	ST_Slot_StpCtl_BuilderInfo stBuilderInfo;
	ST_Slot_StpCtl* pStpCtl;
	/* 停止制御データビルダ情報を設定する。 */
	memset(&stBuilderInfo, 0, sizeof stBuilderInfo);
	stBuilderInfo.HitCd_Size   = pInfo->SIZE_HitCd;
	stBuilderInfo.pParam       = pBuilder;
	stBuilderInfo.fnGetStpCtl1 = &Slot_Spec_PrintData_fnGetStpCtl1;
	stBuilderInfo.fnGetStpCtl2 = &Slot_Spec_PrintData_fnGetStpCtl2;
	stBuilderInfo.fnGetStpCtl3 = &Slot_Spec_PrintData_fnGetStpCtl3;
	/* 停止制御データを作成する。 */
	pStpCtl = Slot_BuildStpCtl(&stBuilderInfo);
	/* 停止制御データを出力する。 */
	Slot_PrintStpCtl(pStpCtl, fpH, fpC);
	/* 停止制御データを開放する。 */
	free(pStpCtl);
}
/*--------------------------------------------------------------------------*/
static void Slot_Spec_PrintData(ST_Slot_Spec_Builder* pBuilder) {
	static const struct {
		void (*pfnPrint)(ST_Slot_Spec_Builder* pBuilder, FILE* fpH, FILE* fpC);
	} tbl[]={
		{&Slot_Spec_PrintData_Pict},		//絵柄
		{&Slot_Spec_PrintData_Reel},		//リール配列
		{&Slot_Spec_PrintData_HitCd},		//条件装置
		{&Slot_Spec_PrintData_HitFlg},		//絵柄組合せ
		{&Slot_Spec_PrintData_HitCd_HitFlg},	//条件装置⇒絵柄組合せ
		{&Slot_Spec_PrintData_StpCtl},		//停止制御
	};
	FILE *fpH, *fpC;
	int i;
	if(!(fpH = fopen("SlotData.h", "w"))) { DIE(); }
	if(!(fpC = fopen("SlotData.c", "w"))) { DIE(); }
	fprintf(fpC, "#include <clip.h>\n");
	fprintf(fpC, "#include \"SlotData.h\"\n");
	fprintf(fpH, "#ifndef __SLOTDATA_H__\n");
	fprintf(fpH, "#define __SLOTDATA_H__\n");
	for(i = 0; i < ARRAY_SIZE(tbl); i++) {
		(*tbl[i].pfnPrint)(pBuilder, fpH, fpC);
	}
	fprintf(fpH, "#endif//__SLOTDATA_H__\n");
	fclose(fpH);
	fclose(fpC);
}
/*--------------------------------------------------------------------------*
 *	グローバル関数
 *--------------------------------------------------------------------------*/
void Slot_MakeSpec(const ST_Slot_SpecInfo* pInfo) {
	ST_Slot_Spec_Builder* pBuilder;
	/* スペック情報を検査する。 */
	if((pInfo->SIZE_Pict   < 1) || (pInfo->SIZE_Pict   >  10)) { DIE(); }
	if(                   (unsigned)pInfo->CT_Reel     >   2 ) { DIE(); }
	if((pInfo->SIZE_HitCd  < 1) || (pInfo->SIZE_HitCd  >  64)) { DIE(); }
	if((pInfo->SIZE_HitFlg < 1) || (pInfo->SIZE_HitFlg > 256)) { DIE(); }
	/* スペックデータビルダのメモリを確保する。 */
	pBuilder = calloc(1, sizeof(ST_Slot_Spec_Builder));
	if(!pBuilder) { DIE(); }
	/* スペック情報を格納する。 */
	pBuilder->pInfo = pInfo;
	/* データ作成 */
	Slot_Spec_BuildData(pBuilder);
	/* データ出力 */
	Slot_Spec_PrintData(pBuilder);
	/* スペックデータビルダのメモリを開放する。 */
	free(pBuilder);
}
#endif//WIN32	//PC上でスペックデータを作成する時に使用します。P/ECE上では使用しません。
