
//ֽ

//ʼ汾: 201212 (ڹҼѧԺ ƽֲ)

//޸: 2013720 ӷЧ,֮ϿһСʱ

//޸: 2014629 ѲͨΪ̬ɨ, ֶ֧ͨ, ʽ

//޸: 20141125
//ʵƵ, һָŶͨ, һʼ뵽еͨϵͬһ, 
//ÿֽͨ(뵽), ǻǰĿǰĸֿͨ, Ȼڼһۺϵ,
//ͨĿ, Լͨͷ(Ҳ).
//Ŀǰʱ޷ڳָһΪ(ֻ泣), дһʱĺ,
//÷һ, ʵռͨͷһ, Ȼ󷵻.
//ǵһҲû!!!
//ǸͷѾֹ,  иڶ, ú׼...
//ղźȻͷԭ:
//ĳ:
//void play0( [int16*?] p )
//Ӧ:
//void play0( [->int16*?] p )

//ע: 201558
//һ, Ų, һž... Ҳԭ, 
// ϲ base code ֮, , ϸûⰡ.
//Ūһ, ȻоϤ! , Ƕջ!!! ǸϽ OS еĶջռ
// 200 Ϊ 300, һԻǲ! Ȼ侲, , ж϶ջ, ÿжϺ
//ջߴ̫С... ҵǸؼ, 100ĳ200, һOK!

//޸: 20161127
//°沥Э

unit music
{
	public const uint16 ID = 0;

	//[i] var_uint8 OS_time;
	uint8 OS_time;

	//[i] var_uint8 OS_EventFlag;
	public uint8 OS_EventFlag;
	//[i] event trig1_event;
	//[i] event trig2_event;

	//[i] var_int32 CurrentTone1;
	public int32 CurrentTone1;
	//[i] var_int32 CurrentTone2;
	public int32 CurrentTone2;
	
	const int8 NUMBER = 4;
	[bool*NUMBER] is_play;
	[uint8*NUMBER] breakTime;
	[bool*NUMBER] liaison;
	[int8*NUMBER] volume;
	[uint8*NUMBER] tick_ms_count;
	[uint8*NUMBER] tick_ms;
	[uint8*NUMBER] time;
	[uint16*NUMBER] index;
	[uint8*NUMBER] offset;
	[->[uint8*?]*NUMBER] music_list;
	
	//[i] linkinterface_tone tone;
	link unit tone {}
	
	int8 Index;
	bool Break;
	
	[uint8*NUMBER] last;
	
	//[i] var_bool isPause;
	bool isPause;
	//[i] var_bool isStop;
	bool isStop;
	
	//---------------------------------------------------
	//[i] function_void OS_init;
	void OS_init()
	{
		OS_time = 1;
		OS_EventFlag = 0;
		
		for( int8 i = 0; i < NUMBER; i + 1 ) {
			is_play[i] = false;
			tick_ms_count[i] = 0;
			tick_ms[i] = 20;
			index[i] = 0;
			time[i] = 0;
			volume[i] = 127;
			liaison[i] = false;
			breakTime[i] = 0;
			last[i] = 0;
			offset[i] = 60;
		}
		Index = 0;
		Break = false;
		
		isStop = true;
		isPause = false;
	}
	//---------------------------------------------------
	//[i] function_void play0 music;
	void play0( [uint8*?] p )
	{
		stop();
		uint16 n = p[0];
		n.8(uint8) = p[1];
		for( uint16 i = 0; i < n; i + 1 ) {
			uint16 sn = p[i*2+2];
			sn.8(uint8) = p[i*2+3];
			play( i, p, sn );
		}
		isPause = false;
		isStop = false;
	}
	//---------------------------------------------------
	//[i] function_void stop;
	void stop()
	{
		tone.stop( 0, 0 );
		tone.stop( 1, 0 );
		is_play[0] = false;
		is_play[1] = false;
		isPause = false;
		isStop = true;
	}
	//---------------------------------------------------
	//[i] function_void Pause;
	void Pause()
	{
		isPause = true;
	}
	//---------------------------------------------------
	//[i] function_void Continue;
	void Continue()
	{
		isPause = false;
	}
	//---------------------------------------------------
	void play( uint16 c, [uint8*?] p, uint16 sn )
	{
		volume[c] = 127;
		tick_ms_count[c] = 0;
		tick_ms[c] = 20;
		time[c] = 1;
		music_list[c] -> p;
		index[c] = sn;
		last[c] = 0;
		offset[c] = 60;
		is_play[c] = true;
	}
	//---------------------------------------------------
	//[i] function_void OS_run;
	void OS_run()
	{
		if( isPause ) return;
		
		if( Break ) { Break = false; goto B; }
		for( Index = 0; Index < NUMBER; Index + 1 ) {
			if( is_play[Index] ) {
				//Сʱֵʱ
				tick_ms_count[Index] + 1;
				if( tick_ms_count[Index] == tick_ms[Index] ) {
					tick_ms_count[Index] = 0;
					//ʱֵݼ,жʱֵǷ񵽴
					time[Index] - 1;
					
					//if( time[Index] == 1 ) {
					//	if( last[Index] & 0x80 == 0 ) {
					//		tone.stop( Index + 1, 0 );
					//	}
					//}
					
					if( time[Index] == 0 ) {
						B:
						if( tone.isBusy ) {
							Break = true;
							//tone.isNeed = true;
							return;
						}
						//tone.isNeed = false;
						is_play[Index] = decode(
							Index + 1,
							music_list[Index],
							index[Index],
							time[Index],
							tick_ms[Index],
							volume[Index],
							liaison[Index],
							breakTime[Index],
							last[Index],
							offset[Index]
						);
						isStop = !is_play[0] && !is_play[1];
					}
				}
			}
		}
	}
	//---------------------------------------------------
	//ݽ
	//ִָֺ
	bool decode(
		int8 c,
		[uint8*?] music_list0,
		uint16 index0*,
		uint8 time0*,
		uint8 tick_ms0*,
		int8 vol*,
		bool liaison0*,
		uint8 last0*,
		uint8 breakTime0*,
		uint8 offset0* )
	{
		bool is_play0 = true;
		forever {
			uint8 d = music_list0[index0];
			if( d == 255 ) {
				is_play0 = false;
				tone.stop( c, 0 );
				break;
			}
			if( d == 254 ) {
				index0 + 1;
				offset0 = music_list0[index0];
				index0 + 1;
				tick_ms0 = tone.switch_time( music_list0[index0] );
				index0 + 1;
				continue;
			}
			if( d == 253 ) {
				index0 + 2;
				continue;
			}
			if( d == 127 ) {
				index0 + 1;
				vol = (int)music_list0[index0];
				index0 + 1;
				continue;
			}
			if( d == 126 ) {
				index0 + 2;
				continue;
			}
			d = music_list0[index0];
			
			//ͬ,һʱ
			if( last0 == d ) {
				tone.stop( c, 0 );
				loop( 10000 ) {}
			}
			
			if( last0 & 0x80 == 0 || last0 & 0x7F != d & 0x7F ) {
				if( last0 & 0x7F != 0 ) {
					tone.stop( c, 0 );
				}
				if( d & 0x7F != 0 ) {
					tone.play( c, (int)((d & 0x7F) + offset0 - 60), vol );
					if( c == 1 ) {
						OS_EventFlag.0(bit) = 1;
						CurrentTone1 = (int)d;
					}
					if( c == 2 ) {
						OS_EventFlag.1(bit) = 1;
						CurrentTone2 = (int)d;
					}
				}
			}
			
			last0 = d;
			
			index0 + 1;
			d = music_list0[index0];
			time0 = d;
			index0 + 1;
			break;
		}
		return is_play0;
	}
}




