/*
 *	clipeffa.c
 *
 *	EFFect ANiMator
 *
 *	* Tue Jul 25 22:09:40 JST 2017 Naoyuki Sawa
 *	- 1st リリース。
 *	* Wed Aug 02 23:35:30 JST 2017 Naoyuki Sawa
 *	- EffAnm_RadBo1()を追加しました。
 *	* Thu Aug 03 22:28:50 JST 2017 Naoyuki Sawa
 *	- EffAnm_RadBo2()を追加しました。
 *	* Sat Aug 05 23:33:42 JST 2017 Naoyuki Sawa
 *	- EffAnm_RadSma()を追加しました。
 */
#include "clip.h"
//*****************************************************************************
//	グローバル関数
//*****************************************************************************
//ラジルギ(https://en.wikipedia.org/wiki/Radirgy)の、小型機を破壊した時のエフェクトに似たアニメーションを描画します。
//[in]
//	x,y			中心座標
//	t			現在時刻	0〜duration	┬時間の単位は任意です(フレーム単位でなくても構いません)。(t/duration)でアニメーション全体に対する進行度合いを判断するからです。
//	duration		全体尺				┘
//	screenSize		画面サイズ			生成するエフェクトの大きさの目安として使用する。縦サイズでも横サイズでも構わない。一般的には、大きい方を指定するのが良いだろう。
//	seed			乱数シード			エフェクトの個々のインスタンス毎に毎回同じ値を指定して下さい。特に気にしないならば常に0を指定して構わない。
//	fnRenderCircle		アプリケーション定義の塗りつぶした円描画関数
//	arg			アプリケーション定義の塗りつぶした円描画関数へ引き渡す任意のデータ
//[note]
//	- 関数名の'RadMed'は、'RADirgy MEDium-sized machine effect'の略です。
void EffAnm_RadSma(int   x,			//┬中心座標
                   int   y,			//┘
                   int   t,			//現在時刻	0〜duration	┬時間の単位は任意です(フレーム単位でなくても構いません)。(t/duration)でアニメーション全体に対する進行度合いを判断するからです。
                   int   duration,		//全体尺			┘
                   int   screenSize,		//画面サイズ			生成するエフェクトの大きさの目安として使用する。縦サイズでも横サイズでも構わない。一般的には、大きい方を指定するのが良いだろう。
                   int   seed,			//乱数シード			エフェクトの個々のインスタンス毎に毎回同じ値を指定して下さい。特に気にしないならば常に0を指定して構わない。
                   void (*fnRenderCircle)(int x, int y, int r, void* arg),	//アプリケーション定義の塗りつぶした円描画関数
                   void* arg) {							//アプリケーション定義の塗りつぶした円描画関数へ引き渡す任意のデータ
	int i, distanceMin, distanceMax, t1, duration1, t2, duration2;
	fixed angleOrg;
	if((unsigned)t > (unsigned)duration) { DIE(); }
	distanceMin = screenSize / 42/*調整可*/;	//┬例えばP/ECE環境で(screenSize=128)の場合に(半径=3〜6)になる調整です。
	distanceMax = screenSize / 21/*調整可*/;	//┘
	duration1   = duration >> 1/*調整可*/;
	t1          = t;
	duration2   = duration - duration1;
	t2          = t        - duration1;
	angleOrg    = fmul(frnd(&seed), PI);
	for(i = 0; i < 3/*調整可*/; i++) {						//┬ラジルギの小エフェクトは6個の円で構成されているが、当実装では見た目の判断で3個にした。元々、ラジルギの小エフェクトはベクターではなくスプライトだと思うので、厳密に真似する必要は無いだろう。
		fixed angle = fadd(angleOrg, fidiv(fimul(PI2, i), 3/*調整可*/));	//┘
		int distance, dx, dy, r;
		distance = RND32_RANGE(seed, distanceMin, distanceMax + 1);
		if(t2 < 0) {
			distance = easeOut_i(distance >> 2/*調整可*/, distance, t1, duration1);
			r        = distance;
		} else {
			r        = lerp_i(   distance,                       0, t2, duration2);
		}
		distance -= (distance >> 3/*調整可*/);	//(t2<0)の時に少し重ねて描画するために距離を少し戻して半径未満にする。
		dx = fst(fimul(fcos(angle), distance));
		dy = fst(fimul(fsin(angle), distance));
		(*fnRenderCircle)(
			x + dx,		//x
			y + dy,		//y
			r,		//r
			arg);		//arg
		fadd_(angle, fmul(frnd(&seed), PI));
	}
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if 0
//□EffAnm_RadMed()の使用例
#ifdef  PIECE
#if 1	//描画バックエンドに塗りつぶした円を描画する関数が有る場合は、その関数をそのまま使う。
static void fnRenderCircle(int x, int y, int r, void* arg) {
	int c = rnd8((int*)arg) & 1;	//0〜1					複数の色で描くためのシードです。単色で良い場合はこれは不要です。
	render_ellipse_fill(&render, x - (r - 1), y - (r - 1), (r * 2) - 1, (r * 2) - 1, c);
}
#else	//描画バックエンドに塗りつぶした円を描画する関数が無い場合は、ポリゴンで円を描画する。
static void fnRenderPolygon(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg) {
	VERTEX v[]={{xy[0][0],xy[0][1]},{xy[1][0],xy[1][1]},{xy[2][0],xy[2][1]},{xy[3][0],xy[3][1]}};
	render_polygon(&render, v, n, (intptr_t)arg);
}
static void fnRenderCircle(int x, int y, int r, void* arg) {
	int c = rnd8((int*)arg) & 1;	//0〜1					複数の色で描くためのシードです。単色で良い場合はこれは不要です。
	EffGen_DiaOva(x, y, r, r, 0, 16/*調整可*/, fnRenderPolygon, (void*)(intptr_t)c);
}
#endif
int app_main(int argc, char* argv[]) {
	const int duration = SEC(0.5);
	int x = 0, y = 0, t = 0, s = 0, tmp;
	for(;;) {
		schedule();
		surface_clear(&surface, 3);
		if(!t) {
			x = RND32_RANGE(seed, 0, DISP_X);
			y = RND32_RANGE(seed, 0, DISP_Y);
			s = seed;
		}
		tmp = s;
		EffAnm_RadSma(
			x,			//x
			y,			//y
			t,			//t
			duration,		//duration
			max(DISP_X,DISP_Y),	//screenSize
			s,			//seed
			fnRenderCircle,		//fnRenderCircle
			&tmp);			//arg			複数の色で描くためのシードです。単色で良い場合はこれは不要です。
		if(++t > duration) { t = 0; }
	}
	return 0;
}
#endif//PIECE
#ifdef  WIN32
#if 1	//描画バックエンドに塗りつぶした円を描画する関数が有る場合は、その関数をそのまま使う。
static void fnRenderCircle(int x, int y, int r, void* arg) {
	int c = rnd8((int*)arg) | 128;	//128〜255				複数の色で描くためのシードです。単色で良い場合はこれは不要です。
	draw_oval_fill(x - (r - 1), y - (r - 1), (r * 2) - 1, (r * 2) - 1, RGBA_MAKE(c, c, c, 255));
}
#else	//描画バックエンドに塗りつぶした円を描画する関数が無い場合は、ポリゴンで円を描画する。
static void fnRenderPolygon(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg) { draw_polygon_fill(xy, n, (intptr_t)arg); }
static void fnRenderCircle(int x, int y, int r, void* arg) {
	int c = rnd8((int*)arg) | 128;	//128〜255				複数の色で描くためのシードです。単色で良い場合はこれは不要です。
	EffGen_DiaOva(x, y, r, r, 0, 16/*調整可*/, fnRenderPolygon, (void*)(intptr_t)RGBA_MAKE(c, c, c, 255));
}
#endif
int cpp_main(int argc, char* argv[]) {
	if(RRS_i_job(pRRS) != (RRS_n_job(pRRS) - 1)) { DIE(); }	//最後のジョブがUIジョブである事を確認する。
	if(!setjmp(env_exit)) {
		const int duration = SEC(0.5);
		int x = 0, y = 0, t = 0, s = 0, tmp;
		for(;;) {
			schedule();
			if(!t) {
				x = RND32_RANGE(seed, 0, DISP_X);
				y = RND32_RANGE(seed, 0, DISP_Y);
				s = seed;
			}
			tmp = s;
			EffAnm_RadSma(
				x,			//x
				y,			//y
				t,			//t
				duration,		//duration
				max(DISP_X,DISP_Y),	//screenSize
				s,			//seed
				fnRenderCircle,		//fnRenderCircle
				&tmp);			//arg			複数の色で描くためのシードです。単色で良い場合はこれは不要です。
			if(++t > duration) { t = 0; }
		}
	}
	return 0;
}
#endif//WIN32
#endif
//-----------------------------------------------------------------------------
//ラジルギ(https://en.wikipedia.org/wiki/Radirgy)の、中型機を破壊した時のエフェクトに似たアニメーションを描画します。
//[in]
//	x,y			中心座標
//	t			現在時刻	0〜duration	┬時間の単位は任意です(フレーム単位でなくても構いません)。(t/duration)でアニメーション全体に対する進行度合いを判断するからです。
//	duration		全体尺				┘
//	screenSize		画面サイズ			生成するエフェクトの大きさの目安として使用する。縦サイズでも横サイズでも構わない。一般的には、大きい方を指定するのが良いだろう。
//	seed			乱数シード			エフェクトの個々のインスタンス毎に毎回同じ値を指定して下さい。特に気にしないならば常に0を指定して構わない。
//	fnRenderPolygon		アプリケーション定義のポリゴン描画関数
//	arg			アプリケーション定義のポリゴン描画関数へ引き渡す任意のデータ
//[note]
//	- 関数名の'RadMed'は、'RADirgy MEDium-sized machine effect'の略です。
void EffAnm_RadMed(int   x,			//┬中心座標
                   int   y,			//┘
                   int   t,			//現在時刻	0〜duration	┬時間の単位は任意です(フレーム単位でなくても構いません)。(t/duration)でアニメーション全体に対する進行度合いを判断するからです。
                   int   duration,		//全体尺			┘
                   int   screenSize,		//画面サイズ			生成するエフェクトの大きさの目安として使用する。縦サイズでも横サイズでも構わない。一般的には、大きい方を指定するのが良いだろう。
                   int   seed,			//乱数シード			エフェクトの個々のインスタンス毎に毎回同じ値を指定して下さい。特に気にしないならば常に0を指定して構わない。
                   void (*fnRenderPolygon)(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg),	//アプリケーション定義のポリゴン描画関数
                   void* arg) {										//アプリケーション定義のポリゴン描画関数へ引き渡す任意のデータ
	int i, radiusCircleInner, radiusCircleOuter, radiusSunkenInner, radiusSunkenOuter, radiusSunkenFluct, radiusRaisedInner, radiusRaisedOuter, radiusRaisedFluct, radiusTaper;
	fixed angle;
	if((unsigned)t > (unsigned)duration) { DIE(); }
#if 0
	//□実数演算バージョン。パラメータ調整用です。遅いので開発中以外には使用しないで下さい。
	{
		double d          = (double)t / (double)duration;
		radiusCircleInner =    lerp(screenSize / 32.0/*調整可*/, screenSize /  2.0/*調整可*/, d);
		radiusCircleOuter =    lerp(screenSize / 16.0/*調整可*/, screenSize /  2.0/*調整可*/, d);
		radiusSunkenInner =    lerp(screenSize / 64.0/*調整可*/, screenSize /  4.0/*調整可*/, d);
		radiusSunkenOuter = easeOut(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d);
		radiusSunkenFluct =    lerp(              0.0/*調整可*/, screenSize / 16.0/*調整可*/, d);
		radiusRaisedInner =    lerp(screenSize / 64.0/*調整可*/, screenSize /  3.0/*調整可*/, d);
		radiusRaisedOuter = easeOut(screenSize /  8.0/*調整可*/, screenSize /  3.0/*調整可*/, d);
		radiusRaisedFluct =    lerp(              0.0/*調整可*/, screenSize / 16.0/*調整可*/, d);
		radiusTaper       = radiusSunkenInner  /  2.0/*調整可*/;
	}
#else
	//□整数演算バージョン。描画結果は実数演算バージョンと同じになるはずです。
	{
		int t2            = (duration - t) * (duration - t);					//┬((d-t)*(d-t))/(d*d) == (1-t/d)*(1-t/d)
		int duration2     =  duration      *  duration;						//┘
		int screenSize_2  = screenSize >> 1;							//                                     screenSize /  2.0/*調整可*/
		int screenSize_3  = screenSize /  3;							//                                     screenSize /  3.0/*調整可*/
		int screenSize_4  = screenSize >> 2;							//                                     screenSize /  4.0/*調整可*/
		int screenSize_8  = screenSize >> 3;							//                                     screenSize /  8.0/*調整可*/
		int screenSize_16 = screenSize >> 4;							//        screenSize / 16.0/*調整可*/
		int screenSize_32 = screenSize >> 5;							//        screenSize / 32.0/*調整可*/
		int screenSize_64 = screenSize >> 6;							//        screenSize / 64.0/*調整可*/
		int lerp_16       =                   screenSize_16                 * t  / duration;	//   lerp(              0.0/*調整可*/, screenSize / 16.0/*調整可*/, d)
		int lerp_16_2     = screenSize_16 + ((screenSize_2 - screenSize_16) * t  / duration);	//   lerp(screenSize / 16.0/*調整可*/, screenSize /  2.0/*調整可*/, d)
		int lerp_32_2     = screenSize_32 + ((screenSize_2 - screenSize_32) * t  / duration);	//   lerp(screenSize / 32.0/*調整可*/, screenSize /  2.0/*調整可*/, d)
		int lerp_64_3     = screenSize_64 + ((screenSize_3 - screenSize_64) * t  / duration);	//   lerp(screenSize / 64.0/*調整可*/, screenSize /  3.0/*調整可*/, d)
		int lerp_64_4     = screenSize_64 + ((screenSize_4 - screenSize_64) * t  / duration);	//   lerp(screenSize / 64.0/*調整可*/, screenSize /  4.0/*調整可*/, d)
		int easeOut_8_3   = screenSize_3  - ((screenSize_3 - screenSize_8 ) * t2 / duration2);	//easeOut(screenSize /  8.0/*調整可*/, screenSize /  3.0/*調整可*/, d)
		int easeOut_16_4  = screenSize_4  - ((screenSize_4 - screenSize_16) * t2 / duration2);	//easeOut(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d)
		radiusCircleInner = lerp_32_2;								//   lerp(screenSize / 32.0/*調整可*/, screenSize /  2.0/*調整可*/, d)
		radiusCircleOuter = lerp_16_2;								//   lerp(screenSize / 16.0/*調整可*/, screenSize /  2.0/*調整可*/, d)
		radiusSunkenInner = lerp_64_4;								//   lerp(screenSize / 64.0/*調整可*/, screenSize /  4.0/*調整可*/, d)
		radiusSunkenOuter = easeOut_16_4;							//easeOut(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d)
		radiusSunkenFluct = lerp_16;								//   lerp(              0.0/*調整可*/, screenSize / 16.0/*調整可*/, d)
		radiusRaisedInner = lerp_64_3;								//   lerp(screenSize / 64.0/*調整可*/, screenSize /  3.0/*調整可*/, d)
		radiusRaisedOuter = easeOut_8_3;							//easeOut(screenSize /  8.0/*調整可*/, screenSize /  3.0/*調整可*/, d)
		radiusRaisedFluct = lerp_16;								//   lerp(              0.0/*調整可*/, screenSize / 16.0/*調整可*/, d)
		radiusTaper       = radiusSunkenInner >> 1;						//radiusSunkenInner  /  2.0/*調整可*/
	}
#endif
	EffGen_Circle(
		x,			//x
		y,			//y
		radiusCircleInner,	//radiusInner
		radiusCircleOuter,	//radiusOuter
		 0/*調整可*/,		//angleOrg
		24/*調整可*/,		//nDiv
		fnRenderPolygon,	//fnRenderPolygon
		arg);			//arg
	angle = fmul(frnd(&seed), PI);
	for(i = 0; i < 2; i++) {
		EffGen_SawArc(
			x,					//x
			y,					//y
			radiusSunkenInner,			//radiusSunkenInner
			radiusSunkenOuter,			//radiusSunkenOuter
			radiusSunkenFluct,			//radiusSunkenFluct
			radiusRaisedInner,			//radiusRaisedInner
			radiusRaisedOuter,			//radiusRaisedOuter
			radiusRaisedFluct,			//radiusRaisedFluct
			radiusTaper,				//radiusTaper
			fsub(angle, fidiv(PI, 4/*調整可*/)),	//angleMin
			fadd(angle, fidiv(PI, 4/*調整可*/)),	//angleMax
			12/*調整可*/,				//nDiv
			seed,					//seed
			fnRenderPolygon,			//fnRenderPolygon
			arg);					//arg
		fadd_(angle, PI);
	}
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if 0
//□EffAnm_RadMed()の使用例
#ifdef  PIECE
static void fnRenderPolygon(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg) {
	VERTEX v[]={{xy[0][0],xy[0][1]},{xy[1][0],xy[1][1]},{xy[2][0],xy[2][1]},{xy[3][0],xy[3][1]}};
	render_polygon(&render, v, n, 0);
}
int app_main(int argc, char* argv[]) {
	const int duration = SEC(0.5);
	int x = 0, y = 0, t = 0, s = 0;
	for(;;) {
		schedule();
		surface_clear(&surface, 3);
		if(!t) {
			x = RND32_RANGE(seed, 0, DISP_X);
			y = RND32_RANGE(seed, 0, DISP_Y);
			s = seed;
		}
		EffAnm_RadMed(
			x,			//x
			y,			//y
			t,			//t
			duration,		//duration
			max(DISP_X,DISP_Y),	//screenSize
			s,			//seed
			fnRenderPolygon,	//fnRenderPolygon
			NULL);			//arg
		if(++t > duration) { t = 0; }
	}
	return 0;
}
#endif//PIECE
#ifdef  WIN32
static void fnRenderPolygon(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg) { draw_polygon_fill(xy, n); }
int cpp_main(int argc, char* argv[]) {
	if(RRS_i_job(pRRS) != (RRS_n_job(pRRS) - 1)) { DIE(); }	//最後のジョブがUIジョブである事を確認する。
	if(!setjmp(env_exit)) {
		const int duration = SEC(0.5);
		int x = 0, y = 0, t = 0, s = 0;
		for(;;) {
			schedule();
			if(!t) {
				x = RND32_RANGE(seed, 0, DISP_X);
				y = RND32_RANGE(seed, 0, DISP_Y);
				s = seed;
			}
			EffAnm_RadMed(
				x,			//x
				y,			//y
				t,			//t
				duration,		//duration
				max(DISP_X,DISP_Y),	//screenSize
				s,			//seed
				fnRenderPolygon,	//fnRenderPolygon
				NULL);			//arg
			if(++t > duration) { t = 0; }
		}
	}
	return 0;
}
#endif//WIN32
#endif
//-----------------------------------------------------------------------------
//ラジルギ(https://en.wikipedia.org/wiki/Radirgy)の、大型機を破壊した時のエフェクトに似たアニメーションを描画します。
//[in]
//	x,y			中心座標
//	t			現在時刻	0〜duration	┬時間の単位は任意です(フレーム単位でなくても構いません)。(t/duration)でアニメーション全体に対する進行度合いを判断するからです。
//	duration		全体尺				┘
//	screenSize		画面サイズ			生成するエフェクトの大きさの目安として使用する。縦サイズでも横サイズでも構わない。一般的には、大きい方を指定するのが良いだろう。
//	seed			乱数シード			エフェクトの個々のインスタンス毎に毎回同じ値を指定して下さい。特に気にしないならば常に0を指定して構わない。
//	fnRenderPolygon		アプリケーション定義のポリゴン描画関数
//	arg			アプリケーション定義のポリゴン描画関数へ引き渡す任意のデータ
//[note]
//	- 関数名の'RadLar'は、'RADirgy LARge-sized machine effect'の略です。
void EffAnm_RadLar(int   x,			//┬中心座標
                   int   y,			//┘
                   int   t,			//現在時刻	0〜duration	┬時間の単位は任意です(フレーム単位でなくても構いません)。(t/duration)でアニメーション全体に対する進行度合いを判断するからです。
                   int   duration,		//全体尺			┘
                   int   screenSize,		//画面サイズ			生成するエフェクトの大きさの目安として使用する。縦サイズでも横サイズでも構わない。一般的には、大きい方を指定するのが良いだろう。
                   int   seed,			//乱数シード			エフェクトの個々のインスタンス毎に毎回同じ値を指定して下さい。特に気にしないならば常に0を指定して構わない。
                   void (*fnRenderPolygon)(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg),	//アプリケーション定義のポリゴン描画関数
                   void* arg) {										//アプリケーション定義のポリゴン描画関数へ引き渡す任意のデータ
	int radiusSunkenInner, radiusSunkenOuter, radiusSunkenFluct, radiusRaisedInner, radiusRaisedOuter, radiusRaisedFluct;
	if((unsigned)t > (unsigned)duration) { DIE(); }
#if 0
	//□実数演算バージョン。パラメータ調整用です。遅いので開発中以外には使用しないで下さい。
	{
		double d          = (double)(t * 2.0/*調整可*/) / (double)duration;
		radiusSunkenInner =                     lerp(              0.0/*調整可*/, screenSize /  2.0/*調整可*/, d);
		radiusSunkenOuter = radiusSunkenInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d);
		radiusSunkenFluct =                     lerp(              0.0/*調整可*/, screenSize /  4.0/*調整可*/, d);
		radiusRaisedInner = radiusSunkenInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  2.0/*調整可*/, d);
		radiusRaisedOuter = radiusRaisedInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d);
		radiusRaisedFluct =                     lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d);
	}
#else
	//□整数演算バージョン。描画結果は実数演算バージョンと同じになるはずです。
	{
		int t2            = t << 1;								//t * 2.0/*調整可*/
		int screenSize_2  = screenSize >> 1;							//                                                      screenSize /  2.0/*調整可*/
		int screenSize_4  = screenSize >> 2;							//                                                      screenSize /  4.0/*調整可*/
		int screenSize_16 = screenSize >> 4;							//                         screenSize / 16.0/*調整可*/
		int lerp_2        =                   screenSize_2                  * t2 / duration;	//                    lerp(              0.0/*調整可*/, screenSize /  2.0/*調整可*/, d)
		int lerp_4        =                   screenSize_4                  * t2 / duration;	//                    lerp(              0.0/*調整可*/, screenSize /  4.0/*調整可*/, d)
		int lerp_16_2     = screenSize_16 + ((screenSize_2 - screenSize_16) * t2 / duration);	//                    lerp(screenSize / 16.0/*調整可*/, screenSize /  2.0/*調整可*/, d)
		int lerp_16_4     = screenSize_16 + ((screenSize_4 - screenSize_16) * t2 / duration);	//                    lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d)
		radiusSunkenInner =                     lerp_2;						//                    lerp(              0.0/*調整可*/, screenSize /  2.0/*調整可*/, d)
		radiusSunkenOuter = radiusSunkenInner + lerp_16_4;					//radiusSunkenInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d)
		radiusSunkenFluct =                     lerp_4;						//                    lerp(              0.0/*調整可*/, screenSize /  4.0/*調整可*/, d)
		radiusRaisedInner = radiusSunkenInner + lerp_16_2;					//radiusSunkenInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  2.0/*調整可*/, d)
		radiusRaisedOuter = radiusRaisedInner + lerp_16_4;					//radiusRaisedInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d)
		radiusRaisedFluct =                     lerp_16_4;					//                    lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d)
	}
#endif
	EffGen_SawCir(
		x,			//x
		y,			//y
		radiusSunkenInner,	//radiusSunkenInner
		radiusSunkenOuter,	//radiusSunkenOuter
		radiusSunkenFluct,	//radiusSunkenFluct
		radiusRaisedInner,	//radiusRaisedInner
		radiusRaisedOuter,	//radiusRaisedOuter
		radiusRaisedFluct,	//radiusRaisedFluct
		 0/*調整可*/,		//angleOrg
#ifdef  PIECE
		32/*調整可*/,		//nDiv			P/ECE		画面解像度も描画性能も低いので、分割数を少なめにしました。
#else //PIECE
		64/*調整可*/,		//nDiv			Win32,汎用	画面解像度も描画性能も高いので、分割数を多めにしました。
#endif//PIECE
		seed,			//seed
		fnRenderPolygon,	//fnRenderPolygon
		arg);			//arg
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if 0
//□EffAnm_RadLar()の使用例
#ifdef  PIECE
static void fnRenderPolygon(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg) {
	VERTEX v[]={{xy[0][0],xy[0][1]},{xy[1][0],xy[1][1]},{xy[2][0],xy[2][1]},{xy[3][0],xy[3][1]}};
	render_polygon(&render, v, n, 0);
}
int app_main(int argc, char* argv[]) {
	const int duration = SEC(0.5);
	int x = 0, y = 0, t = 0, s = 0;
	for(;;) {
		schedule();
		surface_clear(&surface, 3);
		if(!t) {
			x = RND32_RANGE(seed, 0, DISP_X);
			y = RND32_RANGE(seed, 0, DISP_Y);
			s = seed;
		}
		EffAnm_RadLar(
			x,			//x
			y,			//y
			t,			//t
			duration,		//duration
			max(DISP_X,DISP_Y),	//screenSize
			s,			//seed
			fnRenderPolygon,	//fnRenderPolygon
			NULL);			//arg
		if(++t > duration) { t = 0; }
	}
	return 0;
}
#endif//PIECE
#ifdef  WIN32
static void fnRenderPolygon(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg) { draw_polygon_fill(xy, n); }
int cpp_main(int argc, char* argv[]) {
	if(RRS_i_job(pRRS) != (RRS_n_job(pRRS) - 1)) { DIE(); }	//最後のジョブがUIジョブである事を確認する。
	if(!setjmp(env_exit)) {
		const int duration = SEC(0.5);
		int x = 0, y = 0, t = 0, s = 0;
		for(;;) {
			schedule();
			if(!t) {
				x = RND32_RANGE(seed, 0, DISP_X);
				y = RND32_RANGE(seed, 0, DISP_Y);
				s = seed;
			}
			EffAnm_RadLar(
				x,			//x
				y,			//y
				t,			//t
				duration,		//duration
				max(DISP_X,DISP_Y),	//screenSize
				s,			//seed
				fnRenderPolygon,	//fnRenderPolygon
				NULL);			//arg
			if(++t > duration) { t = 0; }
		}
	}
	return 0;
}
#endif//WIN32
#endif
//-----------------------------------------------------------------------------
//ラジルギ(https://en.wikipedia.org/wiki/Radirgy)の、ボスを破壊した時の、「円が広がるフェクトと塗りつぶした円が楕円に変化するフェクトが発生し、少し遅れて円弧ギザギザエフェクトが発生する」エフェクトに似たアニメーションを描画します。
//[in]
//	x,y			中心座標
//	t			現在時刻	0〜duration	┬時間の単位は任意です(フレーム単位でなくても構いません)。(t/duration)でアニメーション全体に対する進行度合いを判断するからです。
//	duration		全体尺				┘
//	screenSize		画面サイズ			生成するエフェクトの大きさの目安として使用する。縦サイズでも横サイズでも構わない。一般的には、大きい方を指定するのが良いだろう。
//	seed			乱数シード			エフェクトの個々のインスタンス毎に毎回同じ値を指定して下さい。特に気にしないならば常に0を指定して構わない。
//	fnRenderPolygon		アプリケーション定義のポリゴン描画関数
//	arg			アプリケーション定義のポリゴン描画関数へ引き渡す任意のデータ
//[note]
//	- 関数名の'RadBo1'は、'RADirgy Boss effect 1'の略です。
void EffAnm_RadBo1(int   x,			//┬中心座標
                   int   y,			//┘
                   int   t,			//現在時刻	0〜duration	┬時間の単位は任意です(フレーム単位でなくても構いません)。(t/duration)でアニメーション全体に対する進行度合いを判断するからです。
                   int   duration,		//全体尺			┘
                   int   screenSize,		//画面サイズ			生成するエフェクトの大きさの目安として使用する。縦サイズでも横サイズでも構わない。一般的には、大きい方を指定するのが良いだろう。
                   int   seed,			//乱数シード			エフェクトの個々のインスタンス毎に毎回同じ値を指定して下さい。特に気にしないならば常に0を指定して構わない。
                   void (*fnRenderPolygon)(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg),	//アプリケーション定義のポリゴン描画関数
                   void* arg) {										//アプリケーション定義のポリゴン描画関数へ引き渡す任意のデータ
	int i, t2, duration2, radiusCircleInner, radiusCircleOuter, radiusSunkenInner, radiusSunkenOuter, radiusSunkenFluct, radiusRaisedInner, radiusRaisedOuter, radiusRaisedFluct, radiusTaper;
	int radiusOvalShort, radiusOvalLong;
	fixed angle;
	if((unsigned)t > (unsigned)duration) { DIE(); }
	t2        = t        - (duration >> 1/*調整可*/);
	duration2 = duration - (duration >> 1/*調整可*/);
#if 0
	//□実数演算バージョン。パラメータ調整用です。遅いので開発中以外には使用しないで下さい。
	{
		double d1         = (double)t  / (double)duration;
		radiusOvalShort   = easeOut(screenSize /  32.0/*調整可*/,                0.0/*調整可*/, d1);
		radiusOvalLong    = easeOut(screenSize /  32.0/*調整可*/, screenSize /   3.0/*調整可*/, d1);
		angle             = (fixed)(int)lerp(      0.0/*調整可*/,        _PI /   3.0/*調整可*/, d1);
		radiusCircleInner =    lerp(screenSize /  32.0/*調整可*/, screenSize /   2.0/*調整可*/, d1);
		radiusCircleOuter =    lerp(screenSize /  16.0/*調整可*/, screenSize /   2.0/*調整可*/, d1);
	    if(t2 >= 0) {
		double d2         = (double)t2 / (double)duration2;
		radiusSunkenInner =    lerp(screenSize / 128.0/*調整可*/, screenSize /   4.0/*調整可*/, d2);
		radiusSunkenOuter = easeOut(screenSize /  32.0/*調整可*/, screenSize /   4.0/*調整可*/, d2);
		radiusSunkenFluct =    lerp(               0.0/*調整可*/, screenSize /  16.0/*調整可*/, d2);
		radiusRaisedInner =    lerp(screenSize / 128.0/*調整可*/, screenSize /   3.0/*調整可*/, d2);
		radiusRaisedOuter = easeOut(screenSize /  16.0/*調整可*/, screenSize /   3.0/*調整可*/, d2);
		radiusRaisedFluct =    lerp(               0.0/*調整可*/, screenSize /  16.0/*調整可*/, d2);
		radiusTaper       = radiusSunkenInner  /   2.0/*調整可*/;
	    }
	}
#else
	//□整数演算バージョン。描画結果は実数演算バージョンと同じになるはずです。
	{
		int _t              = (duration - t ) * (duration - t );					//┬((d -t )*(d -t ))/(d *d ) == (1-t /d )*(1-t /d )
		int _duration       =  duration       *  duration;						//┘
		int screenSize_2    = screenSize >> 1;								//                                      screenSize /   2.0/*調整可*/
		int screenSize_3    = screenSize /  3;								//                                      screenSize /   3.0/*調整可*/
		int screenSize_16   = screenSize >> 4;								//        screenSize /  16.0/*調整可*/
		int screenSize_32   = screenSize >> 5;								//        screenSize /  32.0/*調整可*/
		int lerp_0_PI_3_d1  =                                          (_PI / 3) *  t  /  duration;	//(fixed)(int)lerp(      0.0/*調整可*/,        _PI /   3.0/*調整可*/, d1)
		int lerp_16_2_d1    = screenSize_16  + ((screenSize_2  - screenSize_16 ) *  t  /  duration);	//   lerp(screenSize /  16.0/*調整可*/, screenSize /   2.0/*調整可*/, d1)
		int lerp_32_2_d1    = screenSize_32  + ((screenSize_2  - screenSize_32 ) *  t  /  duration);	//   lerp(screenSize /  32.0/*調整可*/, screenSize /   2.0/*調整可*/, d1)
		int easeOut_32_0_d1 =                                    screenSize_32   * _t  / _duration;	//easeOut(screenSize /  32.0/*調整可*/,                0.0/*調整可*/, d1)
		int easeOut_32_3_d1 = screenSize_3   - ((screenSize_3  - screenSize_32 ) * _t  / _duration);	//easeOut(screenSize /  32.0/*調整可*/, screenSize /   4.0/*調整可*/, d1)
		radiusOvalShort     = easeOut_32_0_d1;								//easeOut(screenSize /  32.0/*調整可*/,                0.0/*調整可*/, d1)
		radiusOvalLong      = easeOut_32_3_d1;								//easeOut(screenSize /  32.0/*調整可*/, screenSize /   3.0/*調整可*/, d1)
		angle               = (fixed)lerp_0_PI_3_d1;							//(fixed)(int)lerp(      0.0/*調整可*/,        _PI /   3.0/*調整可*/, d1)
		radiusCircleInner   = lerp_32_2_d1;								//   lerp(screenSize /  32.0/*調整可*/, screenSize /   2.0/*調整可*/, d1)
		radiusCircleOuter   = lerp_16_2_d1;								//   lerp(screenSize /  16.0/*調整可*/, screenSize /   2.0/*調整可*/, d1)
	    if(t2 >= 0) {
		int _t2             = (duration2 - t2) * (duration2 - t2);					//┬((d2-t2)*(d2-t2))/(d2*d2) == (1-t2/d2)*(1-t2/d2)
		int _duration2      =  duration2       *  duration2;						//┘
		int screenSize_4    = screenSize >> 2;								//                                      screenSize /   4.0/*調整可*/
		int screenSize_128  = screenSize >> 7;								//        screenSize / 128.0/*調整可*/
		int lerp_0_16_d2    =                    screenSize_16                   *  t2 /  duration2;	//   lerp(               0.0/*調整可*/, screenSize /  16.0/*調整可*/, d2)
		int lerp_128_3_d2   = screenSize_128 + ((screenSize_3  - screenSize_128) *  t2 /  duration2);	//   lerp(screenSize / 128.0/*調整可*/, screenSize /   3.0/*調整可*/, d2)
		int lerp_128_4_d2   = screenSize_128 + ((screenSize_4  - screenSize_128) *  t2 /  duration2);	//   lerp(screenSize / 128.0/*調整可*/, screenSize /   4.0/*調整可*/, d2)
		int easeOut_16_3_d2 = screenSize_3   - ((screenSize_3  - screenSize_16 ) * _t2 / _duration2);	//easeOut(screenSize /  16.0/*調整可*/, screenSize /   3.0/*調整可*/, d2)
		int easeOut_32_4_d2 = screenSize_4   - ((screenSize_4  - screenSize_32 ) * _t2 / _duration2);	//easeOut(screenSize /  32.0/*調整可*/, screenSize /   4.0/*調整可*/, d2)
		radiusSunkenInner   = lerp_128_4_d2;								//   lerp(screenSize / 128.0/*調整可*/, screenSize /   4.0/*調整可*/, d2)
		radiusSunkenOuter   = easeOut_32_4_d2;								//easeOut(screenSize /  32.0/*調整可*/, screenSize /   4.0/*調整可*/, d2)
		radiusSunkenFluct   = lerp_0_16_d2;								//   lerp(               0.0/*調整可*/, screenSize /  16.0/*調整可*/, d2)
		radiusRaisedInner   = lerp_128_3_d2;								//   lerp(screenSize / 128.0/*調整可*/, screenSize /   3.0/*調整可*/, d2)
		radiusRaisedOuter   = easeOut_16_3_d2;								//easeOut(screenSize /  16.0/*調整可*/, screenSize /   3.0/*調整可*/, d2)
		radiusRaisedFluct   = lerp_0_16_d2;								//   lerp(               0.0/*調整可*/, screenSize /  16.0/*調整可*/, d2)
		radiusTaper         = radiusSunkenInner >> 1;							//radiusSunkenInner  /   2.0/*調整可*/
	#ifdef  __GNUC__
	    } else {
		radiusSunkenInner   = 0/*警告抑制*/;
		radiusSunkenOuter   = 0/*警告抑制*/;
		radiusSunkenFluct   = 0/*警告抑制*/;
		radiusRaisedInner   = 0/*警告抑制*/;
		radiusRaisedOuter   = 0/*警告抑制*/;
		radiusRaisedFluct   = 0/*警告抑制*/;
		radiusTaper         = 0/*警告抑制*/;
	#endif//__GNUC__
	    }
	}
#endif
	fadd_(angle, fmul(frnd(&seed), PI));
	EffGen_DiaOva(
		x,			//x
		y,			//y
		radiusOvalShort,	//radiusShort
		radiusOvalLong,		//radiusLong
		angle,			//angleRot
		16/*調整可*/,		//nDiv
		fnRenderPolygon,	//fnRenderPolygon
		arg);			//arg
	EffGen_Circle(
		x,			//x
		y,			//y
		radiusCircleInner,	//radiusInner
		radiusCircleOuter,	//radiusOuter
		 0/*調整可*/,		//angleOrg
		24/*調整可*/,		//nDiv
		fnRenderPolygon,	//fnRenderPolygon
		arg);			//arg
	if(t2 >= 0) {
		angle = fmul(frnd(&seed), PI);
		for(i = 0; i < 2; i++) {
			EffGen_SawArc(
				x,					//x
				y,					//y
				radiusSunkenInner,			//radiusSunkenInner
				radiusSunkenOuter,			//radiusSunkenOuter
				radiusSunkenFluct,			//radiusSunkenFluct
				radiusRaisedInner,			//radiusRaisedInner
				radiusRaisedOuter,			//radiusRaisedOuter
				radiusRaisedFluct,			//radiusRaisedFluct
				radiusTaper,				//radiusTaper
				fsub(angle, fidiv(PI, 3/*調整可*/)),	//angleMin
				fadd(angle, fidiv(PI, 3/*調整可*/)),	//angleMax
				12/*調整可*/,				//nDiv
				seed,					//seed
				fnRenderPolygon,			//fnRenderPolygon
				arg);					//arg
			fadd_(angle, PI);
		}
	}
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if 0
//□EffAnm_RadBo1()の使用例
#ifdef  PIECE
static void fnRenderPolygon(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg) {
	VERTEX v[]={{xy[0][0],xy[0][1]},{xy[1][0],xy[1][1]},{xy[2][0],xy[2][1]},{xy[3][0],xy[3][1]}};
	render_polygon(&render, v, n, 0);
}
int app_main(int argc, char* argv[]) {
	const int duration = SEC(0.5);
	int x = 0, y = 0, t = 0, s = 0;
	for(;;) {
		schedule();
		surface_clear(&surface, 3);
		if(!t) {
			x = RND32_RANGE(seed, 0, DISP_X);
			y = RND32_RANGE(seed, 0, DISP_Y);
			s = seed;
		}
		EffAnm_RadBo1(
			x,			//x
			y,			//y
			t,			//t
			duration,		//duration
			max(DISP_X,DISP_Y),	//screenSize
			s,			//seed
			fnRenderPolygon,	//fnRenderPolygon
			NULL);			//arg
		if(++t > duration) { t = 0; }
	}
	return 0;
}
#endif//PIECE
#ifdef  WIN32
static void fnRenderPolygon(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg) { draw_polygon_fill(xy, n); }
int cpp_main(int argc, char* argv[]) {
	if(RRS_i_job(pRRS) != (RRS_n_job(pRRS) - 1)) { DIE(); }	//最後のジョブがUIジョブである事を確認する。
	if(!setjmp(env_exit)) {
		const int duration = SEC(0.5);
		int x = 0, y = 0, t = 0, s = 0;
		for(;;) {
			schedule();
			if(!t) {
				x = RND32_RANGE(seed, 0, DISP_X);
				y = RND32_RANGE(seed, 0, DISP_Y);
				s = seed;
			}
			EffAnm_RadBo1(
				x,			//x
				y,			//y
				t,			//t
				duration,		//duration
				max(DISP_X,DISP_Y),	//screenSize
				s,			//seed
				fnRenderPolygon,	//fnRenderPolygon
				NULL);			//arg
			if(++t > duration) { t = 0; }
		}
	}
	return 0;
}
#endif//WIN32
#endif
//-----------------------------------------------------------------------------
//ラジルギ(https://en.wikipedia.org/wiki/Radirgy)の、ボスを破壊した時の、「円が広がるフェクトと塗りつぶした円が楕円に変化するフェクトと全円ギザギザエフェクトが発生する」エフェクトに似たアニメーションを描画します。
//[in]
//	x,y			中心座標
//	t			現在時刻	0〜duration	┬時間の単位は任意です(フレーム単位でなくても構いません)。(t/duration)でアニメーション全体に対する進行度合いを判断するからです。
//	duration		全体尺				┘
//	screenSize		画面サイズ			生成するエフェクトの大きさの目安として使用する。縦サイズでも横サイズでも構わない。一般的には、大きい方を指定するのが良いだろう。
//	seed			乱数シード			エフェクトの個々のインスタンス毎に毎回同じ値を指定して下さい。特に気にしないならば常に0を指定して構わない。
//	fnRenderPolygon		アプリケーション定義のポリゴン描画関数
//	arg			アプリケーション定義のポリゴン描画関数へ引き渡す任意のデータ
//[note]
//	- 関数名の'RadBo2'は、'RADirgy Boss effect 2'の略です。
void EffAnm_RadBo2(int   x,			//┬中心座標
                   int   y,			//┘
                   int   t,			//現在時刻	0〜duration	┬時間の単位は任意です(フレーム単位でなくても構いません)。(t/duration)でアニメーション全体に対する進行度合いを判断するからです。
                   int   duration,		//全体尺			┘
                   int   screenSize,		//画面サイズ			生成するエフェクトの大きさの目安として使用する。縦サイズでも横サイズでも構わない。一般的には、大きい方を指定するのが良いだろう。
                   int   seed,			//乱数シード			エフェクトの個々のインスタンス毎に毎回同じ値を指定して下さい。特に気にしないならば常に0を指定して構わない。
                   void (*fnRenderPolygon)(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg),	//アプリケーション定義のポリゴン描画関数
                   void* arg) {										//アプリケーション定義のポリゴン描画関数へ引き渡す任意のデータ
	int radiusOvalShort, radiusOvalLong, radiusSunkenInner, radiusSunkenOuter, radiusSunkenFluct, radiusRaisedInner, radiusRaisedOuter, radiusRaisedFluct, radiusCircleInner, radiusCircleOuter;
	fixed angle;
	if((unsigned)t > (unsigned)duration) { DIE(); }
#if 0
	//□実数演算バージョン。パラメータ調整用です。遅いので開発中以外には使用しないで下さい。
	{
		double d1         = (double) t                  / (double)duration;
		double d2         = (double)(t * 2.0/*調整可*/) / (double)duration;
		radiusOvalShort   =                   easeOut(screenSize / 32.0/*調整可*/,               0.0/*調整可*/, d1);
		radiusOvalLong    =                   easeOut(screenSize / 32.0/*調整可*/, screenSize /  3.0/*調整可*/, d1);
		angle             =          (fixed)(int)lerp(              0.0/*調整可*/,        _PI /  3.0/*調整可*/, d1);
		radiusSunkenInner =                      lerp(              0.0/*調整可*/, screenSize /  2.0/*調整可*/, d2);
		radiusSunkenOuter =  radiusSunkenInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d2);
		radiusSunkenFluct =                      lerp(              0.0/*調整可*/, screenSize /  4.0/*調整可*/, d2);
		radiusRaisedInner =  radiusSunkenInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  2.0/*調整可*/, d2);
		radiusRaisedOuter =  radiusRaisedInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d2);
		radiusRaisedFluct =                      lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d2);
		radiusCircleInner = (radiusSunkenInner + radiusRaisedOuter) >> 1;
		radiusCircleOuter =  radiusCircleInner +     (screenSize / 32.0/*調整可*/);
	}
#else
	//□整数演算バージョン。描画結果は実数演算バージョンと同じになるはずです。
	{
		int  t2             = t << 1;									//t * 2.0/*調整可*/
		int _t              = (duration - t) * (duration - t);						//┬((d-t)*(d-t))/(d*d) == (1-t/d)*(1-t/d)
		int _duration       =  duration      *  duration;						//┘
		int screenSize_2    = screenSize >> 1;								//                                                       screenSize /  2.0/*調整可*/
		int screenSize_3    = screenSize /  3;								//                                                       screenSize /  3.0/*調整可*/
		int screenSize_4    = screenSize >> 2;								//                                                       screenSize /  4.0/*調整可*/
		int screenSize_16   = screenSize >> 4;								//                          screenSize / 16.0/*調整可*/
		int screenSize_32   = screenSize >> 5;								//                          screenSize / 32.0/*調整可*/
		int lerp_0_PI_3_d1  =                                       (_PI / 3) *  t  /  duration;	//         (fixed)(int)lerp(              0.0/*調整可*/,        _PI /  3.0/*調整可*/, d1)
		int lerp_0_2_d2     =                   screenSize_2                  *  t2 /  duration;	//                     lerp(              0.0/*調整可*/, screenSize /  2.0/*調整可*/, d2)
		int lerp_0_4_d2     =                   screenSize_4                  *  t2 /  duration;	//                     lerp(              0.0/*調整可*/, screenSize /  4.0/*調整可*/, d2)
		int lerp_16_2_d2    = screenSize_16 + ((screenSize_2 - screenSize_16) *  t2 /  duration);	//                     lerp(screenSize / 16.0/*調整可*/, screenSize /  2.0/*調整可*/, d2)
		int lerp_16_4_d2    = screenSize_16 + ((screenSize_4 - screenSize_16) *  t2 /  duration);	//                     lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d2)
		int easeOut_32_0_d1 =                                  screenSize_32  * _t  / _duration;	//                  easeOut(screenSize / 32.0/*調整可*/,               0.0/*調整可*/, d1)
		int easeOut_32_3_d1 = screenSize_3  - ((screenSize_3 - screenSize_32) * _t  / _duration);	//                  easeOut(screenSize / 32.0/*調整可*/, screenSize /  4.0/*調整可*/, d1)
		radiusOvalShort     =                      easeOut_32_0_d1;					//                  easeOut(screenSize / 32.0/*調整可*/,               0.0/*調整可*/, d1)
		radiusOvalLong      =                      easeOut_32_3_d1;					//                  easeOut(screenSize / 32.0/*調整可*/, screenSize /  3.0/*調整可*/, d1)
		angle               =               (fixed)lerp_0_PI_3_d1;					//         (fixed)(int)lerp(              0.0/*調整可*/,        _PI /  3.0/*調整可*/, d1)
		radiusSunkenInner   =                      lerp_0_2_d2;						//                     lerp(              0.0/*調整可*/, screenSize /  2.0/*調整可*/, d2)
		radiusSunkenOuter   =  radiusSunkenInner + lerp_16_4_d2;					// radiusSunkenInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d2)
		radiusSunkenFluct   =                      lerp_0_4_d2;						//                     lerp(              0.0/*調整可*/, screenSize /  4.0/*調整可*/, d2)
		radiusRaisedInner   =  radiusSunkenInner + lerp_16_2_d2;					// radiusSunkenInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  2.0/*調整可*/, d2)
		radiusRaisedOuter   =  radiusRaisedInner + lerp_16_4_d2;					// radiusRaisedInner + lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d2)
		radiusRaisedFluct   =                      lerp_16_4_d2;					//                     lerp(screenSize / 16.0/*調整可*/, screenSize /  4.0/*調整可*/, d2)
		radiusCircleInner   = (radiusSunkenInner + radiusRaisedOuter) >> 1;				//(radiusSunkenInner + radiusRaisedOuter) >> 1;
		radiusCircleOuter   =  radiusCircleInner + screenSize_32;					// radiusCircleInner +     (screenSize / 32.0/*調整可*/);
	}
#endif
	fadd_(angle, fmul(frnd(&seed), PI));
	EffGen_DiaOva(
		x,			//x
		y,			//y
		radiusOvalShort,	//radiusShort
		radiusOvalLong,		//radiusLong
		angle,			//angleRot
		16/*調整可*/,		//nDiv
		fnRenderPolygon,	//fnRenderPolygon
		arg);			//arg
	EffGen_SawCir(
		x,			//x
		y,			//y
		radiusSunkenInner,	//radiusSunkenInner
		radiusSunkenOuter,	//radiusSunkenOuter
		radiusSunkenFluct,	//radiusSunkenFluct
		radiusRaisedInner,	//radiusRaisedInner
		radiusRaisedOuter,	//radiusRaisedOuter
		radiusRaisedFluct,	//radiusRaisedFluct
		 0/*調整可*/,		//angleOrg
#ifdef  PIECE
		32/*調整可*/,		//nDiv			P/ECE		画面解像度も描画性能も低いので、分割数を少なめにしました。
#else //PIECE
		64/*調整可*/,		//nDiv			Win32,汎用	画面解像度も描画性能も高いので、分割数を多めにしました。
#endif//PIECE
		seed,			//seed
		fnRenderPolygon,	//fnRenderPolygon
		arg);			//arg
	EffGen_Circle(
		x,			//x
		y,			//y
		radiusCircleInner,	//radiusInner
		radiusCircleOuter,	//radiusOuter
		 0/*調整可*/,		//angleOrg
		24/*調整可*/,		//nDiv
		fnRenderPolygon,	//fnRenderPolygon
		arg);			//arg
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if 0
//□EffAnm_RadBo2()の使用例
#ifdef  PIECE
static void fnRenderPolygon(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg) {
	VERTEX v[]={{xy[0][0],xy[0][1]},{xy[1][0],xy[1][1]},{xy[2][0],xy[2][1]},{xy[3][0],xy[3][1]}};
	render_polygon(&render, v, n, 0);
}
int app_main(int argc, char* argv[]) {
	const int duration = SEC(0.5);
	int x = 0, y = 0, t = 0, s = 0;
	for(;;) {
		schedule();
		surface_clear(&surface, 3);
		if(!t) {
			x = RND32_RANGE(seed, 0, DISP_X);
			y = RND32_RANGE(seed, 0, DISP_Y);
			s = seed;
		}
		EffAnm_RadBo2(
			x,			//x
			y,			//y
			t,			//t
			duration,		//duration
			max(DISP_X,DISP_Y),	//screenSize
			s,			//seed
			fnRenderPolygon,	//fnRenderPolygon
			NULL);			//arg
		if(++t > duration) { t = 0; }
	}
	return 0;
}
#endif//PIECE
#ifdef  WIN32
static void fnRenderPolygon(const int xy[/*n*/][2/*x,y*/], int n/*3or4*/, void* arg) { draw_polygon_fill(xy, n); }
int cpp_main(int argc, char* argv[]) {
	if(RRS_i_job(pRRS) != (RRS_n_job(pRRS) - 1)) { DIE(); }	//最後のジョブがUIジョブである事を確認する。
	if(!setjmp(env_exit)) {
		const int duration = SEC(0.5);
		int x = 0, y = 0, t = 0, s = 0;
		for(;;) {
			schedule();
			if(!t) {
				x = RND32_RANGE(seed, 0, DISP_X);
				y = RND32_RANGE(seed, 0, DISP_Y);
				s = seed;
			}
			EffAnm_RadBo2(
				x,			//x
				y,			//y
				t,			//t
				duration,		//duration
				max(DISP_X,DISP_Y),	//screenSize
				s,			//seed
				fnRenderPolygon,	//fnRenderPolygon
				NULL);			//arg
			if(++t > duration) { t = 0; }
		}
	}
	return 0;
}
#endif//WIN32
#endif
