/*	
 *	clipprds.h
 *
 *	演出制御
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2015 Naoyuki Sawa
 *
 *	* Mon Jul 02 23:56:03 JST 2012 Naoyuki Sawa
 *	- 1stリリース。
 *	* Sat Nov 10 18:19:56 JST 2012 Naoyuki Sawa
 *	- PrdDev_CancelSetup()、PrdDev_GetPrdDat()を追加しました。
 *	* Tue Feb 05 11:35:37 JST 2013 Naoyuki Sawa
 *	- PrdCh_ClearWarrantCounter()、PrdCh_ClearWarrantCounterAll()を追加しました。
 *	* Wed Apr 03 18:05:33 JST 2013 Naoyuki Sawa
 *	- 暗黙のクリアトリガ送信仕様を追加しました。
 *	  変更した関数は、PrdSetList_Setup()のみです。
 *	* Wed Apr 10 18:39:31 JST 2013 Naoyuki Sawa
 *	- ワークエリアをST_Prd構造体の一か所にまとめるために、大幅なソース変更を行いました。
 *	  主な変更内容は、定義位置の変更であり、アルゴリズムはほぼ変更ありません。
 *	- ワークエリアをST_Prd構造体の一か所にまとめた目的は、今後、演出の途中状態をまるごとバックアップするためです。
 *	* Tue Apr 16 22:45:58 JST 2013 Naoyuki Sawa
 *	- クリティカルセクション内で、演出コマンドを個別にコピーして保持するのでなく、演出コマンドリストのまま保持するよう変更しました。
 *	  バッファのメモリ節約と、コピー時間の短縮のためです。
 *	- グローバル関数の定義には、変更ありません。
 *	  ただし、PrdCmdList_Setup()に指定する演出コマンドリストは、不変であること。(即ち、ROM,又は,実行されるまで変更しないRAM上にあること)
 *	  実際にはさほど厳密な制約ではなく、クリティカルセクションを抜けるまで不変であれば良いだけなので、余り気にする必要はありません。
 *	  演出デバイスのセットアップ関数内から、再帰的にPrdCmdList_Setup()を呼び出す場合にのみ、注意が必要です。
 *	  具体的には、セットアップ関数のスタック上に演出コマンドリストを作成してPrdCmdList_Setup()を呼び出したりすると、正しく動作しません。
 *	* Mon Jul 01 17:42:17 JST 2013 Naoyuki Sawa
 *	- 演出コマンドリスト,演出順序リスト,演出セットリストの、終端を示す方法を変更しました。
 *	  これまでは、特殊なフィールド値を持つ終端レコードによって示していました。今後は、最終レコードのEndフラグを用いて示すよう変更します。
 *	  この変更によって、終端レコードを配置することが不要になり、データ容量が節約できます。
 *	- これまでは、演出デバイス番号0を、終端レコードを表す特殊なフィールド値として使用していましたが、今回の変更によって不要になったため、
 *	  今後は、演出デバイス番号0も利用できるようになりました。即ち、演出デバイス番号は(1〜PrdDev_Max)でなく、(0〜PrdDev_Max)となります。
 *	* Fri Sep 13 20:13:42 JST 2013 Naoyuki Sawa
 *	- 同一トリガを二回以上セットアップしようとしたときに、二回目以降のセットアップを無視する仕様を削除しました。
 *	  当仕様を削除した理由は:
 *	  ・実際に使ってみて、効果的であるケースが少なかったこと。	//二回目以降のセットアップを自動的に無視することが、却って、バグを発見しづらくする原因になることもあった
 *	  ・この挙動が効果的なケースに対しても、アプリケーション側で比較的簡単に対応できること。
 *	  当仕様の削除に伴い、以下の変更を行いました:
 *	  ・同一トリガを二回以上セットアップするためのフラグであった、PrdSet_Flag_Multiが不要になり、削除しました。
 *	  ・ST_PrdCh.TriggerMaskフィールドが不要になり、削除しました。
 *	  ・トリガ番号の範囲が、変更前は最大31でしたが、変更後は最大255になりました。(ST_PrdCh.TriggerMaskのビット数の制限に囚われなくなったため)
 *	  ・トリガ番号の範囲変更に伴い、暗黙のクリアトリガのトリガ番号を、31⇒255に変更しました。
 *	- 演出セット構造体のフラグに、保障時間カウンタをクリアする機能である、PrdSet_Flag_Immediateを追加しました。
 *	  これまでは、アプリケーションが明示的にPrdCh_ClearWarrantCounter()等を呼び出して保障時間カウンタをクリアする必要が有り、データ化しづらい問題がありました。
 *	  今後も、PrdCh_ClearWarrantCounter()等でクリアすることもできますが、それに加えて、保障時間カウンタをクリアしたいトリガの演出セットにフラグ指定できるようになりました。
 *	* Sat Feb 08 14:57:06 JST 2014 Naoyuki Sawa
 *	- 演出デバイスのフィルタ関数とセットアップ関数の格納方法を変更しました。
 *	- これまでは、演出デバイス毎に、個別の関数ポインタを格納していましたが、
 *	  今後は、共通の関数とし、アプリケーション側で振り分けることにしました。
 *	- こう変更した理由は、演出デバイス毎に個別の、関数ポインタを格納するメモリを節約するためです。
 *	  これまで使用した限り、個別の関数が直接呼び出されることの利点は薄かったので、問題ありません。
 *	- 今回の変更に伴い、PrdDev_Install()の使用方法を変更しました。
 *	* Wed Aug 27 20:38:48 JST 2014 Naoyuki Sawa
 *	- ST_PrdSeq.env_PrdDev_CancelSetupを実体⇒ポインタに変更しました。
 *	* Wed Aug 27 20:38:48 JST 2014 Naoyuki Sawa
 *	- ST_PrdSeq.env_PrdDev_CancelSetupを実体⇒ポインタに変更しました。
 *	  理由1. これまでは、アプリケーションが、PrdCmdList_Setup()を経由せずに直接、演出デバイスのフィルタ関数,又は,セットアップ関数を呼出し、
 *	         演出デバイスのフィルタ関数,又は,セットアップ関数の中でPrdDev_CancelSetup()を呼出すと、予測できない不正な動作になっていました。
 *	         PrdCmd_Setup()でのenv_PrdDev_CancelSetupに対するsetjmp()が行われた後かを、PrdDev_CancelSetup()では判断できなかったからです。
 *	         今回の変更により、env_PrdDev_CancelSetupをポインタに変更したので、PrdDev_CancelSetup()で上記を判断できるようになりました。
 *	         今後は、上記のケースでPrdDev_CancelSetup()内でエラー停止するようになり、バグが見つけ易くなりました。
 *	  理由2. このジャンプバッファは、PrdCmd_Setup()の呼出し期間中のみ必要な変数であり、当構造体の中に静的に確保することはメモリの無駄です。
 *	         EPSONライブラリの場合、jmp_bufは16ワード(64バイト)の変数であり、64バイトの無駄となっていました。
 *	         今後は、env_PrdDev_CancelSetupの実体はPrdCmd_Setup()のスタック上に確保し、当構造体の中にはポインタ(4バイト)のみを確保します。
 *	         当構造体のサイズが、60バイト節約できました。
 *	* Wed Feb 04 21:16:57 JST 2015 Naoyuki Sawa
 *	- P/ECE以外で使用する時に、PrdDev_Max,PrdCh_Max,PrdSetCh_PrdSetBuffer_Sizeをアプリケーション側で定義出来るようにしました。
 *	  P/ECE以外で使用する時に、PrdDev_Maxを大幅に増やす場合が有るが、P/ECEには過大であり、大幅に増やした値に固定したくないための対策です。
 *	- 具体的には、clipprds.hをインクルードするよりも先にPrdDev_Maxを定義しておけば、clipprds.h内ではPrdDev_Maxを定義しないようにしました。
 *	  PrdCh_Max,PrdSetCh_PrdSetBuffer_Sizeについても同様に、clipprds.hよりも先に定義しておけば、先に定義した値が有効となります。
 *	- 上記はあくまで、P/ECE以外で当モジュールを単独で使用する場合であり、P/ECEで使用する場合は、clipprds.h内で定義している値に固定となることに注意してください。
 *	  なぜなら、P/ECEで使用する場合はCLiPライブラリの1モジュールとして予めコンパイルしておくので、アプリケーションへのリンク時に変更することは出来ないからです。
 *	* Sat Feb 07 00:00:00 JST 2015 Naoyuki Sawa
 *	- ST_PrdOrdCh.RepeatCounter,ST_PrdOrdCh.DelayCounterをint⇒unsigned shortに変更しました。元々unsigned shortで充分だったのでこの変更による挙動への影響は有りません。
 *	  厳密にはST_PrdOrdCh.RepeatCounterはunsigned charでも充分なのですがそうするとパディングが生じるだけなのでunsigned shortでもメモリ効率は同じです。
 *	- ST_PrdSetCh.WarrantCounterをint⇒unsigned shortに変更しました。元々unsigned shortで充分だったのでこの変更による挙動への影響は有りません。
 *	* Sat Feb 07 07:00:19 JST 2015 Naoyuki Sawa
 *	- PrdDef_AddressOffset(),ST_PrdSeq.AddressOffsetを追加しました。
 *	  演出制御データをアドレス0ベースでリンク,ROM化しておき、任意アドレスにロード(,又は,バイナリリンク)して使用できるようにするための機能です。
 *	- ST_PrdSeq.AddressOffsetのアドレスオフセット対象であることを示すために、PrdSet.pPrdOrdList,PrdOrd.pPrdCmdListのフィールド名の先頭に'_'を追加し、PrdSet._pPrdOrdList,PrdOrd._pPrdCmdListとしました。
 *	  他の同名のフィールドや変数に間違えてオフセット加算してしまう危険を低らすためです。
 *	- この機能を追加した理由は、演出制御データが大きい場合、プログラムとは別にコンパイル&リンクしておいて、プログラムをリビルドする時間を短く出来るようにするためです。
 *	  演出制御データがアドレス非依存だったならばこんな特殊処理は必要無いのですが、実際にはポインタを含んでいるため、こんな特殊処理が必要になりました。
 *	- 特殊処理が行われるタイミングは、当モジュールの内部処理でPrdSet._pPrdOrdList,及び,PrdOrd._pPrdCmdListを読み出した時だけであることに注意してください。
 *	  当モジュールの内部処理で、ROM上にバイナリリンクされた,又は,RAM上にロードされた、演出制御データのポインタフィールドを読み出す時にリロケートを行うイメージです。
 *	  アプリケーションが、PrdCmdList_Setup()やPrdSetList_Setup()を呼び出した場合、それらに引き渡したポインタには、アドレスオフセットは加算されません。
 *	- PrdDef_AddressOffset()を呼び出さないか,又は,0を設定すれば、これまでどおりの動作になります。
 *	  これまでどおり、演出制御データをアプリケーションプログラムに含めてコンパイル・リンクする場合は、PrdDef_AddressOffset()を呼び出さないか,又は,0を設定してください。
 */
#ifndef __CLIP_PRDS_H__
#define __CLIP_PRDS_H__

/****************************************************************************
 *	演出デバイス
 ****************************************************************************/

/* 演出デバイスの総数
 * - 演出デバイス番号として有効な値の範囲は、(0〜PrdDev_Max)です。			//{{2013/07/01:コメント変更}}
 */
#ifndef PrdDev_Max									//{{2015/02/04追加:P/ECE以外で使用する時に、PrdDev_Max,PrdCh_Max,PrdSetCh_PrdSetBuffer_Sizeをアプリケーション側で定義出来るようにしました。}}
#define PrdDev_Max	31	/* (0〜255)の範囲で、調整可能 */			//{{2013/07/01:コメント変更}}
#endif//PrdDev_Max									//{{2015/02/04追加:P/ECE以外で使用する時に、PrdDev_Max,PrdCh_Max,PrdSetCh_PrdSetBuffer_Sizeをアプリケーション側で定義出来るようにしました。}}

//{{2014/02/08:追加
/* 初期化情報 */
typedef struct _ST_PrdDevInfo {
	int (*fnFilter)(int PrdDev, int PrdDat);	/* フィルタ関数 */
	void (*fnSetup)(int PrdDev, int PrdDat);	/* セットアップ関数 */
} ST_PrdDevInfo;
//}}2014/02/08:追加

//{{2014/02/08:変更
//void PrdDev_Install(int iPrdDev, int (*pFilter)(int PrdDev, int PrdDat), void (*pSetup)(int PrdDev, int PrdDat));
//↓2014/02/08:変更
void PrdDev_Install(const ST_PrdDevInfo* pPrdDevInfo);
//}}2014/02/08:変更
void PrdDev_CancelSetup();								//{{2012/11/10:追加}}
int PrdDev_GetPrdDat(int iPrdDev);							//{{2012/11/10:追加}}

/****************************************************************************
 *	演出コマンド
 ****************************************************************************/

#define PrdCmd_Flag_NoReset	(1<<0)	/* 演出データが変化しなければ、セットアップしない */
#define PrdCmd_Flag_Reserved1	(1<<1)	/* (未使用) */
#define PrdCmd_Flag_Reserved2	(1<<2)	/* (未使用) */
#define PrdCmd_Flag_Reserved3	(1<<3)	/* (未使用) */
#define PrdCmd_Flag_Reserved4	(1<<4)	/* (未使用) */
#define PrdCmd_Flag_Reserved5	(1<<5)	/* (未使用) */
#define PrdCmd_Flag_Reserved6	(1<<6)	/* (未使用) */
#define PrdCmd_Flag_End	(1<<7)	/* これが最終レコードであることを示す */		//{{2013/07/01:変更}}

/* 演出コマンド構造体 */
typedef struct _PrdCmd {
	unsigned char Flag;		/* フラグ(PrdCmd_Flag_*の組み合わせ) */
	unsigned char iPrdDev;		/* 演出デバイス番号(0〜PrdDev_Max) */		//{{2013/07/01:コメント変更}}
	unsigned short PrdDat;		/* 演出データ(アプリケーション定義) */
} PrdCmd;

void PrdCmdList_Setup(const PrdCmd* pPrdCmdList);

/****************************************************************************
 *	演出順序
 ****************************************************************************/

#define PrdOrd_Flag_Ensure	(1<<0)	/* 停止時に未到達ならば、停止時にセットアップする */
#define PrdOrd_Flag_Reserved1	(1<<1)	/* (未使用) */
#define PrdOrd_Flag_Reserved2	(1<<2)	/* (未使用) */
#define PrdOrd_Flag_Reserved3	(1<<3)	/* (未使用) */
#define PrdOrd_Flag_Reserved4	(1<<4)	/* (未使用) */
#define PrdOrd_Flag_Reserved5	(1<<5)	/* (未使用) */
#define PrdOrd_Flag_Reserved6	(1<<6)	/* (未使用) */
#define PrdOrd_Flag_End	(1<<7)	/* これが最終レコードであることを示す */		//{{2013/07/01:変更}}

/* 演出順序構造体 */
typedef struct _PrdOrd {
	unsigned char Flag;		/* フラグ(PrdOrd_Flag_*の組み合わせ) */
	unsigned char Repeat;		/* 繰り返し回数(0=1回,1=2回,…,254=255回,255=無限) */
	unsigned short Delay;		/* 遅延時間(0=即時,1〜65534=遅延時間,65535=停止時) */	/* 【特例処理】65535(停止時)を指定すると、暗黙のPrdOrd_Flag_Ensureも指定されたものと見なす */
    //{{2015/02/07変更:ST_PrdSeq.AddressOffsetのアドレスオフセット対象であることを示すために、PrdSet.pPrdOrdList,PrdOrd.pPrdCmdListのフィールド名の先頭に'_'を追加し、PrdSet._pPrdOrdList,PrdOrd._pPrdCmdListとしました。他の同名のフィールドや変数に間違えてオフセット加算してしまう危険を低らすためです。
    //	const PrdCmd* pPrdCmdList;	/* 演出コマンドリスト(NULL=不可) */		//{{2013/07/01:コメント変更}}
    //↓2015/02/07変更:ST_PrdSeq.AddressOffsetのアドレスオフセット対象であることを示すために、PrdSet.pPrdOrdList,PrdOrd.pPrdCmdListのフィールド名の先頭に'_'を追加し、PrdSet._pPrdOrdList,PrdOrd._pPrdCmdListとしました。他の同名のフィールドや変数に間違えてオフセット加算してしまう危険を低らすためです。
	const PrdCmd* _pPrdCmdList;	/* 演出コマンドリスト(NULL=不可) */		//{{2013/07/01:コメント変更}}
    //}}2015/02/07変更:ST_PrdSeq.AddressOffsetのアドレスオフセット対象であることを示すために、PrdSet.pPrdOrdList,PrdOrd.pPrdCmdListのフィールド名の先頭に'_'を追加し、PrdSet._pPrdOrdList,PrdOrd._pPrdCmdListとしました。他の同名のフィールドや変数に間違えてオフセット加算してしまう危険を低らすためです。
} PrdOrd;

/****************************************************************************
 *	演出セット
 ****************************************************************************/

//#define PrdSet_Flag_Multi	(1<<0)	/* 同一のトリガを、二回以上セットアップ可能とする */	/* このフラグがセットされていなければ、同一のトリガの二回目以降の送信時はセットアップしない */	//{{2013/09/13:削除}}
#define PrdSet_Flag_Immediate	(1<<0)	/* 保障時間カウンタをクリアし、確実に即時実行する */	/* このフラグがセットされていなければ、保障時間カウンタがタイムアウトするのを待って実行する */	//{{2013/09/13:追加}}
#define PrdSet_Flag_Reserved1	(1<<1)	/* (未使用) */
#define PrdSet_Flag_Reserved2	(1<<2)	/* (未使用) */
#define PrdSet_Flag_Reserved3	(1<<3)	/* (未使用) */
#define PrdSet_Flag_Reserved4	(1<<4)	/* (未使用) */
#define PrdSet_Flag_Reserved5	(1<<5)	/* (未使用) */
#define PrdSet_Flag_Reserved6	(1<<6)	/* (未使用) */
#define PrdSet_Flag_End	(1<<7)	/* これが最終レコードであることを示す */		//{{2013/07/01:変更}}

/* 演出セット構造体 */
typedef struct _PrdSet {
	unsigned char Flag;		/* フラグ(PrdSet_Flag_*の組み合わせ) */
	unsigned char Trigger;		/* トリガ(0=セットアップ時,1〜254=アプリケーション定義,255=クリア時) */	//{{2013/04/03:コメント変更}}	//{{2013/09/13:コメント変更}}
	unsigned short Warrant;		/* 保証時間(0=保証時間無し,1〜65535=保証時間) */
    //{{2015/02/07変更:ST_PrdSeq.AddressOffsetのアドレスオフセット対象であることを示すために、PrdSet.pPrdOrdList,PrdOrd.pPrdCmdListのフィールド名の先頭に'_'を追加し、PrdSet._pPrdOrdList,PrdOrd._pPrdCmdListとしました。他の同名のフィールドや変数に間違えてオフセット加算してしまう危険を低らすためです。
    //	const PrdOrd* pPrdOrdList;	/* 演出順序リスト(NULL=不可) */			//{{2013/07/01:コメント変更}}
    //↓2015/02/07変更:ST_PrdSeq.AddressOffsetのアドレスオフセット対象であることを示すために、PrdSet.pPrdOrdList,PrdOrd.pPrdCmdListのフィールド名の先頭に'_'を追加し、PrdSet._pPrdOrdList,PrdOrd._pPrdCmdListとしました。他の同名のフィールドや変数に間違えてオフセット加算してしまう危険を低らすためです。
	const PrdOrd* _pPrdOrdList;	/* 演出順序リスト(NULL=不可) */			//{{2013/07/01:コメント変更}}
    //}}2015/02/07変更:ST_PrdSeq.AddressOffsetのアドレスオフセット対象であることを示すために、PrdSet.pPrdOrdList,PrdOrd.pPrdCmdListのフィールド名の先頭に'_'を追加し、PrdSet._pPrdOrdList,PrdOrd._pPrdCmdListとしました。他の同名のフィールドや変数に間違えてオフセット加算してしまう危険を低らすためです。
} PrdSet;

/****************************************************************************
 *	演出制御チャネル
 ****************************************************************************/

/* 演出制御チャネルの総数
 * - 演出制御チャネル番号として有効な値の範囲は、(0〜PrdCh_Max)です。
 */
#ifndef PrdCh_Max									//{{2015/02/04追加:P/ECE以外で使用する時に、PrdDev_Max,PrdCh_Max,PrdSetCh_PrdSetBuffer_Sizeをアプリケーション側で定義出来るようにしました。}}
#define PrdCh_Max	3	/* (0〜任意)の範囲で、調整可能 */
#endif//PrdCh_Max									//{{2015/02/04追加:P/ECE以外で使用する時に、PrdDev_Max,PrdCh_Max,PrdSetCh_PrdSetBuffer_Sizeをアプリケーション側で定義出来るようにしました。}}

void PrdCh_Exec(int iPrdCh);
void PrdCh_ExecAll();

void PrdCh_ClearWarrantCounter(int iPrdCh);
void PrdCh_ClearWarrantCounterAll();

void PrdCh_Reset(int iPrdCh);
void PrdCh_ResetAll();

void PrdCh_SendTrigger(int iPrdCh, int Trigger);
void PrdCh_SendTriggerAll(int Trigger);

void PrdSetList_Setup(const PrdSet* pPrdSetList, int iPrdCh);

/****************************************************************************
 *	演出制御データ
 ****************************************************************************/

//{{2015/02/07追加:PrdDef_AddressOffset(),ST_PrdSeq.AddressOffsetを追加しました。
void PrdDef_AddressOffset(int AddressOffset);
//}}2015/02/07追加:PrdDef_AddressOffset(),ST_PrdSeq.AddressOffsetを追加しました。

/****************************************************************************
 *	サンプル
 ****************************************************************************/

//	//演出デバイスのフィルタ関数の定義例
//	int PrdDev_Filter(int PrdDev, int PrdDat) {
//		switch(PrdDev) {
//		case 0:
//			switch(PrdDat) {
//			case 0x0000: /** no job **/    break;
//			case 0xFFFF: /** no job **/    break;
//			default:     PrdDat += 0x0203; break;
//			}
//			return PrdDat;
//		default:
//			DIE();
//		}
//	}
//	//演出デバイスのセットアップ関数の定義例
//	void PrdDev_Setup(int PrdDev, int PrdDat) {
//		switch(PrdDev) {
//		case 0:
//			switch(PrdDat) {
//			case 0x0000: surface_clear(&surface, 0);                                          break;
//			case 0xFFFF: render_rectangle(&render, 0, 0, DISP_X, DISP_Y, 3);                  break;
//			default:     render_printf(&render, (PrdDat&255)*10, (PrdDat>>8)*10, 0, 3, "○"); break;
//			}
//			return;
//		default:
//			DIE();
//		}
//	}
//	const ST_PrdDevInfo stPrdDevInfo = { PrdDev_Filter, PrdDev_Setup };
//	//初期化の例
//	void TestInit() {
//		pcePowerSetReport(PWR_RPTOFF);
//		PrdDev_Install(&stPrdDevInfo);
//	}
//	//演出コマンドリストの定義例
//	const PrdCmd cmd0[] = {{PrdCmd_Flag_End|0,0,0x0000}};
//	const PrdCmd cmd1[] = {{PrdCmd_Flag_End|0,0,0x0101}}, cmd2[] = {{PrdCmd_Flag_End|0,0,0x0102}}, cmd3[] = {{PrdCmd_Flag_End|0,0,0x0103}}, cmd4[] = {{PrdCmd_Flag_End|0,0,0x0104}}, cmd5[] = {{PrdCmd_Flag_End|0,0,0x0105}};
//	const PrdCmd cmd6[] = {{PrdCmd_Flag_End|0,0,0x0201}}, cmd7[] = {{PrdCmd_Flag_End|0,0,0x0202}}, cmd8[] = {{PrdCmd_Flag_End|0,0,0x0203}}, cmd9[] = {{PrdCmd_Flag_End|0,0,0x0204}}, cmdA[] = {{PrdCmd_Flag_End|0,0,0x0205}};
//	const PrdCmd cmdB[] = {{PrdCmd_Flag_End|0,0,0x0301}}, cmdC[] = {{PrdCmd_Flag_End|0,0,0x0302}}, cmdD[] = {{PrdCmd_Flag_End|0,0,0x0303}}, cmdE[] = {{PrdCmd_Flag_End|0,0,0x0304}}, cmdF[] = {{PrdCmd_Flag_End|0,0,0x0305}};
//	const PrdCmd cmdZ[] = {{PrdCmd_Flag_End|0,0,0xFFFF}};
//	//演出順序リストの定義例
//	const PrdOrd ord1[] = {{                1,0,SEC(0),cmd1},{1,0,SEC(1),cmd2},{1,0,SEC(1),cmd3},{1,0,SEC(1),cmd4},{PrdOrd_Flag_End|1,0,SEC(1),cmd5}};
//	const PrdOrd ord2[] = {{                1,0,SEC(0),cmd6},{1,0,SEC(1),cmd7},{1,0,SEC(1),cmd8},{1,0,SEC(1),cmd9},{PrdOrd_Flag_End|1,0,SEC(1),cmdA}};
//	const PrdOrd ord3[] = {{                1,0,SEC(0),cmdB},{1,0,SEC(1),cmdC},{1,0,SEC(1),cmdD},{1,0,SEC(1),cmdE},{PrdOrd_Flag_End|1,0,SEC(1),cmdF}};
//	const PrdOrd ordZ[] = {{PrdOrd_Flag_End|1,0,SEC(0),cmdZ}};
//	//演出セットリストの定義例
//	const PrdSet set1[] = {{0,0,SEC(2),ord1},{0,1,SEC(2),ord2},{0,2,SEC(2),ord3},{PrdSet_Flag_End|0,255,SEC(0),ordZ}};
//	//メインループの例
//	void TestExec() {
//		for(;;) {
//			schedule();
//			if(joy & TRG_SELECT) exit(0);
//			//演出セットリストのセットアップ例
//			if(joy & TRG_A) { PrdSetList_Setup(set1, 0); } //演出制御チャネルに、演出セットリストをセットアップ	既存の演出セットリストが有る場合は、差し替える前に暗黙のクリアトリガ(255)を送信。差し替えた後、暗黙のセットアップトリガ(0)を送信。
//			if(joy & TRG_B) { PrdSetList_Setup(NULL, 0); } //演出制御チャネルの、演出セットリストをクリア		既存の演出セットリストが有る場合は、クリアする前に暗黙のクリアトリガ(255)を送信。
//			//トリガの送信例
//			if(joy & TRG_LF) { PrdCh_SendTriggerAll(1); } //演出制御チャネルに、トリガを送信
//			if(joy & TRG_RI) { PrdCh_SendTriggerAll(2); } //演出制御チャネルに、トリガを送信
//			//演出コマンドリストのセットアップ例
//			if(joy & TRG_UP) { PrdCmdList_Setup(cmd0); } //演出デバイスに直接、演出コマンドリストをセットアップ
//			//演出制御チャネルのリセット例
//			if(joy & TRG_DN) { PrdCmdList_Setup(cmd0); PrdCh_ResetAll(); } //上に加えて演出制御チャネル0を停止
//			//演出制御チャネルの実行例
//			PrdCh_ExecAll();
//		}
//	}

//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
//■　　　　　　　　　これ以降は、モジュールのプライベート定義です。アプリケーションが参照してはいけません。　　　　　　　　　■
//■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

/*--- 演出デバイス ---*/

/* 演出デバイス構造体 */
typedef struct _ST_PrdDev {
//{{2014/02/08:変更
//	int PrdDat;				/* 最後にセットアップした演出データ */
//	int (*pFilter)(int PrdDev, int PrdDat);	/* 演出データフィルタ関数(NULL=無し) */
//	void (*pSetup)(int PrdDev, int PrdDat);	/* 演出データセットアップ関数(NULL=無し) */
//↓2014/02/08:変更
	unsigned short PrdDat;			/* 最後にセットアップした演出データ */
//}}2014/02/08:変更
} ST_PrdDev;

/*--- 演出コマンド ---*/

//{{2013/04/13:変更
///* 演出コマンドバッファサイズ
// * - 演出コマンドセットアップ処理のクリティカルセクション内で、演出コマンドを一時格納できる最大数を示します。
// *   必要な数はデータに依存しますが、概ね、演出デバイスと演出制御チャネルの数に比例すると考え、両者を掛けた数としました。
// *   (PrdCh_SendTriggerAll()内のクリティカルセクションが、もっとも多い演出コマンドをバッファする可能性があると考えたため)
// * - 実際のアプリケーションによっては、もっと多く必要だったり、もっと少なくても大丈夫だったりすると思います。
// *   実際のアプリケーションによって、調整してください。
// */
//#define PrdCmd_Buffer_Size	((PrdDev_Max+1)*(PrdCh_Max+1))	/* (1〜任意)の範囲で、調整可能 */
//↓2013/04/13:変更
/* 演出コマンドリストバッファサイズ
 * - 演出コマンドリストセットアップ処理のクリティカルセクション内で、演出コマンドリストを一時格納できる最大数を示します。
 *   必要な数はデータに依存しますが、概ね、演出制御チャネルの数に比例すると考え、『4』を掛けた数としました。
 *   PrdCh_SendTriggerAll()内のクリティカルセクションが、もっとも多い演出コマンドリストをバッファする可能性があります。
 * - 『4』を掛けた理由は、トリガ当りPrdOrd_Flag_Ensureがセットされている演出順序データ数が、『4』前後と考えたからです。
 *   演出の停止,又は,差し替えに時、残っているPrdOrd_Flag_Ensureがセットされている演出順序データをまとめて実行する時に、
 *   もっとも多い演出コマンドリストをバッファする可能性があります。
 * - 実際のアプリケーションによっては、もっと多く必要だったり、もっと少なくても大丈夫だったりすると思います。
 *   実際のアプリケーションによって、調整してください。
 */
#define PrdCmdList_Buffer_Size	((4)*(PrdCh_Max+1))	/* (1〜任意)の範囲で、調整可能 */
//}}2013/04/13:変更

/*--- 演出順序制御チャネル ---*/

/* 演出順序制御チャネルの総数
 * - 演出順序制御チャネル番号として有効な値の範囲は、(0〜PrdOrdCh_Max)です。
 */
#define PrdOrdCh_Max	PrdCh_Max

/* 演出順序制御チャネル構造体 */
typedef struct _ST_PrdOrdCh {
	const PrdOrd* pPrdOrdList;	/* 演出順序リスト(NULL=停止) */
    //{{2015/02/07変更:ST_PrdOrdCh.RepeatCounter,ST_PrdOrdCh.DelayCounterをint⇒unsigned shortに変更しました。元々unsigned shortで充分だったのでこの変更による挙動への影響は有りません。厳密にはST_PrdOrdCh.RepeatCounterはunsigned charでも充分なのですがそうするとパディングが生じるだけなのでunsigned shortでもメモリ効率は同じです。
    //	int RepeatCounter;		/* 繰り返し回数カウンタ(アップカウンタ) */
    //	int DelayCounter;		/* 遅延時間カウンタ(アップカウンタ) */
    //↓2015/02/07変更:ST_PrdOrdCh.RepeatCounter,ST_PrdOrdCh.DelayCounterをint⇒unsigned shortに変更しました。元々unsigned shortで充分だったのでこの変更による挙動への影響は有りません。厳密にはST_PrdOrdCh.RepeatCounterはunsigned charでも充分なのですがそうするとパディングが生じるだけなのでunsigned shortでもメモリ効率は同じです。
	unsigned short RepeatCounter;	/* 繰り返し回数カウンタ(アップカウンタ) */
	unsigned short DelayCounter;	/* 遅延時間カウンタ(アップカウンタ) */
    //}}2015/02/07変更:ST_PrdOrdCh.RepeatCounter,ST_PrdOrdCh.DelayCounterをint⇒unsigned shortに変更しました。元々unsigned shortで充分だったのでこの変更による挙動への影響は有りません。厳密にはST_PrdOrdCh.RepeatCounterはunsigned charでも充分なのですがそうするとパディングが生じるだけなのでunsigned shortでもメモリ効率は同じです。
} ST_PrdOrdCh;

/*--- 演出セット制御チャネル ---*/

/* 演出セット制御チャネルの総数-1
 * - 演出セット制御チャネル番号として有効な値の範囲は、(0〜PrdSetCh_Max)です。
 */
#define PrdSetCh_Max	PrdCh_Max

/* 演出セットバッファサイズ
 * - 先に開始した演出セットの保証時間到達前に、後続の演出セットを予約できる最大数を示します。
 *   1ならば後続の演出セットを1個，2ならば2個，…，NならばN個まで、予約できます。
 *   通常の用途ならば1(後続の演出セットを1個予約可能)でも充分です。
 */
#ifndef PrdSetCh_PrdSetBuffer_Size							//{{2015/02/04追加:P/ECE以外で使用する時に、PrdDev_Max,PrdCh_Max,PrdSetCh_PrdSetBuffer_Sizeをアプリケーション側で定義出来るようにしました。}}
#define PrdSetCh_PrdSetBuffer_Size	4	/* (1〜任意)の範囲で、調整可能 */
#endif//PrdSetCh_PrdSetBuffer_Size							//{{2015/02/04追加:P/ECE以外で使用する時に、PrdDev_Max,PrdCh_Max,PrdSetCh_PrdSetBuffer_Sizeをアプリケーション側で定義出来るようにしました。}}

/* 演出セット制御チャネル構造体 */
typedef struct _ST_PrdSetCh {
	const PrdSet* pPrdSetBuffer[PrdSetCh_PrdSetBuffer_Size];	/* 演出セットバッファ */
    //{{2015/02/07変更:ST_PrdSetCh.WarrantCounterをint⇒unsigned shortに変更しました。元々unsigned shortで充分だったのでこの変更による挙動への影響は有りません。
    //	int WarrantCounter;		/* 保証時間カウンタ(ダウンカウンタ) */
    //↓2015/02/07変更:ST_PrdSetCh.WarrantCounterをint⇒unsigned shortに変更しました。元々unsigned shortで充分だったのでこの変更による挙動への影響は有りません。
	unsigned short WarrantCounter;	/* 保証時間カウンタ(ダウンカウンタ) */
    //}}2015/02/27変更:ST_PrdSetCh.WarrantCounterをint⇒unsigned shortに変更しました。元々unsigned shortで充分だったのでこの変更による挙動への影響は有りません。
} ST_PrdSetCh;

/*--- 演出制御チャネル ---*/

/* 演出制御チャネル構造体 */
typedef struct _ST_PrdCh {
	const PrdSet* pPrdSetList;	/* 演出セットリスト(NULL=無し) */
//	int TriggerMask;		/* 送信済みトリガマスク */			//{{2013/09/13:削除}}
} ST_PrdCh;

/*--- 演出制御 ---*/

/* 演出制御構造体 */
typedef struct _ST_PrdSeq {

	/*--- 演出制御データ ---*/

//{{2015/02/07追加:PrdDef_AddressOffset(),ST_PrdSeq.AddressOffsetを追加しました。
	int AddressOffset;		/* 当モジュールの内部処理でPrdSet._pPrdOrdList,PrdOrd._pPrdCmdListを読み出した時に加算するアドレスオフセット。 */
//}}2015/02/07追加:PrdDef_AddressOffset(),ST_PrdSeq.AddressOffsetを追加しました。

	/*--- 演出デバイス ---*/

//{{2014/02/08:追加
	/* 初期化情報 */
	const ST_PrdDevInfo* pPrdDevInfo;
//}}2014/02/08:追加

	/* 演出デバイステーブル
	 * - TBL_PrdDev[0]          = (iPrdDev=0)          に対応			//{{2013/07/01:コメント変更}}
	 *   TBL_PrdDev[PrdDev_Max] = (iPrdDev=PrdDev_Max)に対応			//{{2013/07/01:コメント変更}}
	 */
	ST_PrdDev TBL_PrdDev[PrdDev_Max + 1];						//{{2013/07/01:変更}}

	/*--- 演出コマンド ---*/

//{{2013/04/13:変更
//	/* 演出コマンドバッファ
//	 * - 演出コマンドセットアップ処理のクリティカルセクション内で、演出コマンドを格納します。
//	 *   PrdCmd_SetupDirect()とPrdCmd_SetupBuffer()を参照してください。
//	 */
//	PrdCmd TBL_PrdCmd_Buffer[PrdCmd_Buffer_Size];
//↓2013/04/13:変更
	/* 演出コマンドリストバッファ
	 * - 演出コマンドリストセットアップ処理のクリティカルセクション内で、演出コマンドリストを格納します。
	 *   PrdCmdList_Setup()とPrdCmdList_Setup_LeaveCS()を参照してください。
	 */
	const PrdCmd* TBL_PrdCmdList_Buffer[PrdCmdList_Buffer_Size];
//}}2013/04/13:変更

//{{2013/04/13:変更
//	/* 演出コマンドセットアップ処理の、クリティカルセクションに入った回数 */
//	int PrdCmd_Setup_CountCS;
//↓2013/04/13:変更
	/* 演出コマンドリストセットアップ処理の、クリティカルセクションに入った回数 */
	int PrdCmdList_Setup_CountCS;
//}}2013/04/13:変更

//{{2013/04/13:変更
//	/* PrdDev_CancelSetup()、及び、PrdCmd_SetupDirect()から利用します。 */
//	jmp_buf env_PrdDev_CancelSetup;
//↓2013/04/13:変更
//	/* PrdDev_CancelSetup()、及び、PrdCmdList_Setup_LeaveCS()から利用します。 */
//	jmp_buf env_PrdDev_CancelSetup;
//↓2014/08/27:変更
	/* * Wed Aug 27 20:38:48 JST 2014 Naoyuki Sawa
	 * - ST_PrdSeq.env_PrdDev_CancelSetupを実体⇒ポインタに変更しました。
	 *   理由1. これまでは、アプリケーションが、PrdCmdList_Setup()を経由せずに直接、演出デバイスのフィルタ関数,又は,セットアップ関数を呼出し、
	 *          演出デバイスのフィルタ関数,又は,セットアップ関数の中でPrdDev_CancelSetup()を呼出すと、予測できない不正な動作になっていました。
	 *          PrdCmd_Setup()でのenv_PrdDev_CancelSetupに対するsetjmp()が行われた後かを、PrdDev_CancelSetup()では判断できなかったからです。
	 *          今回の変更により、env_PrdDev_CancelSetupをポインタに変更したので、PrdDev_CancelSetup()で上記を判断できるようになりました。
	 *          今後は、上記のケースでPrdDev_CancelSetup()内でエラー停止するようになり、バグが見つけ易くなりました。
	 *   理由2. このジャンプバッファは、PrdCmd_Setup()の呼出し期間中のみ必要な変数であり、当構造体の中に静的に確保することはメモリの無駄です。
	 *          EPSONライブラリの場合、jmp_bufは16ワード(64バイト)の変数であり、64バイトの無駄となっていました。
	 *          今後は、env_PrdDev_CancelSetupの実体はPrdCmd_Setup()のスタック上に確保し、当構造体の中にはポインタ(4バイト)のみを確保します。
	 *          当構造体のサイズが、60バイト節約できました。 */
	jmp_buf* env_PrdDev_CancelSetup;
//}}2014/08/27:変更

	/*--- 演出順序制御チャネル ---*/

	/* 演出順序制御チャネルテーブル
	 * - TBL_PrdOrdCh[0]            = (iPrdOrdCh=0)           に対応
	 *   TBL_PrdOrdCh[PrdOrdCh_Max] = (iPrdOrdCh=PrdOrdCh_Max)に対応
	 */
	ST_PrdOrdCh TBL_PrdOrdCh[PrdOrdCh_Max + 1];

	/*--- 演出セット制御チャネル ---*/

	/* 演出セット制御チャネルテーブル
	 * - TBL_PrdSetCh[0]            = (iPrdSetCh=0)           に対応
	 *   TBL_PrdSetCh[PrdSetCh_Max] = (iPrdSetCh=PrdSetCh_Max)に対応
	 */
	ST_PrdSetCh TBL_PrdSetCh[PrdSetCh_Max + 1];

	/*--- 演出制御チャネル ---*/

	/* 演出制御チャネルテーブル
	 * - TBL_PrdCh[0]         = (iPrdCh=0)        に対応
	 *   TBL_PrdCh[PrdCh_Max] = (iPrdCh=PrdCh_Max)に対応
	 */
	ST_PrdCh TBL_PrdCh[PrdCh_Max + 1];

} ST_PrdSeq;

#endif/*__CLIP_PRDS_H__*/
