/*************************************************************************
*	"sndkey.cci" 
*************************************************************************/

/*************************************************************************
*	イベントテスト
*************************************************************************/

#include	"ccilib.h"

/*	パレットデータ（HEwin 配色）	*/
char	PltDat[3][16] =
{
	/* G R  B								*/
	{ 0, 0, 0},	/* C_BALCK, C_THROUGH		*/
	{ 0, 0, 0},	/* C_BLUE , C_MBLACK 		*/
	{ 7, 7, 8},	/* C_RED					*/
	{12,12,13},	/* C_MAGENTA				*/
	{ 6, 5, 7},	/* C_GREEN					*/
	{ 8, 7, 9},	/* C_CYAN					*/
	{10, 9,11},	/* C_YELLOW					*/
	{11,11,12},	/* C_WHITE					*/

	{ 5, 5, 6},	/* C_HBALCK					*/
	{ 0, 0,11},	/* C_HBLUE					*/
	{ 0,11, 0},	/* C_HRED					*/
	{ 0,11,11},	/* C_HMAGENTA				*/
	{11, 0, 0},	/* C_HGEEN					*/
	{11, 0,11},	/* C_HCYAN					*/
	{11,11, 0},	/* C_HYELLOW				*/
	{14,14,15}	/* C_HWHITE					*/
};

/*************************************************************************
*	初期化
*************************************************************************/

int		init()
{
	DSP_sysInit(0);			/* 表示システム初期化		*/
	KBF_sysInit();			/* キーボードシステム初期化	*/
	KBF_kan_off();
	FDL_sysInit();			/* ファイルダイアログ初期化	*/

	sdk_control(0);			/* サイドワーク起動禁止		*/

	DSP_writePage(0);		/* 書き込みページ			*/
	DSP_setPlt( PltDat );	/* パレット設定				*/
	DSP_boxf(0,24,639,463,PSET,COLMIX(5,6));

	DSP_writePage(1);		/* 書き込みページ			*/
	DSP_setPlt( PltDat );	/* パレット設定				*/
	DSP_title("Sand Key","1.00",15,7,0,0);
	evt_setDspTime( 1, 432, 4, 7, 0 );	/* 時刻表示アイドリング処理設定	*/
	SYL_clear();
}

char	*SndPtr=NULL;
char	*Bname[8];
int		Snd_init()
{
	int		est;
	if ( (SndPtr = calloc(16384,1))==NULL)
		exit(1);
	SND_init(SndPtr);
	SND_elevol_init();
	est=SND_get_elevol_mute();
	SND_elevol_mute(est | 3);
	return(0);
}	
	


/*************************************************************************
*	終了
*************************************************************************/

int		term()
{
	FDL_sysEnd();
	KBF_sysEnd();
	DSP_sysEnd();
	if (SndPtr)
	{
		SND_end();
		free(SndPtr);
		SndPtr=NULL;
	}
	
}

/*************************************************************************
*	SandKey
*************************************************************************/
int		DlgMvFunc(int evtNo, char *sbj)
{
	char	*dlg;
	short	 fr[4];	/* DLGBOX_T	*/

	dlg = EVT_getPtr(sbj);
	fr[0] = DLG_getFr(dlg,0);	/* x0	*/
	fr[1] = DLG_getFr(dlg,1);	/* y0	*/
	fr[2] = DLG_getFr(dlg,2);	/* xs	*/
	fr[3] = DLG_getFr(dlg,3);	/* ys	*/
	if ( DlgMove( fr ) )
	{	DLG_move( dlg, fr[0], fr[1] );
	}
	return	(EVT_BREAK);
}


/* 結構ひどいかもしんない・・・。*/
/* グローバルでぐろぐろ。*/
int		x0,y0;						/*窓枠の左上*/
int		oct=4;						/*オクターブ*/
int		key_flag=1;					/*現在の使用チャンネル*/
int		P_flag=0;					/*PCMモードの時は１、FMの時は０*/
int		inst=0;						/*現在の音色番号*/
char	*Iname[8];					/*音色名、定義の仕方が妙だけど*/
char	*Ibuf[128];					/*FM音源用バッファ*/
char	*MOJI[2] = {"FM..","PCM."};	/*なぜここにあるのかは秘密 ☆*/


int		fm_inst_print()
{
	int		c,i,in;

	for (i=0;i<5;i++)
	{
		if (inst+i-2<0)
			in=127+i+inst-1;
		else if (inst+i-2>127)
			in=inst+i-130;
		else
			in=inst+i-2;
		
		SND_inst_read(0,in,Ibuf);
		strcpy	(Iname,"");
		strncat	(Iname,Ibuf,8);
		
		if (i==2)
			c=C_HCYAN;
		else
			c=C_HBLACK;
		
		DSP_str(x0+110,y0+81+i*9,c,C_MBLACK,
				8,"%03d:%-8s",in,Iname);
	}
}

int		pcm_inst_print()
{
	int		c,i,in;

	for (i=0;i<5;i++)
	{
		if (inst+i-2<0)
			in=31+i+inst-1;
		else if (inst+i-2>31)
			in=inst+i-34;
		else
			in=inst+i-2;
		
		SND_inst_read(64,in,Ibuf);
		strcpy	(Iname,"");
		strncat	(Iname,Ibuf,8);
		
		if (i==2)
			c=C_HCYAN;
		else
			c=C_HBLACK;
		
		DSP_str(x0+110,y0+81+i*9,c,C_MBLACK,
				8,"%03d:%-8s",in,Iname);
	}
}

int		Inst_print()
{
	if	(P_flag==1)
	{
		pcm_inst_print();
		return(0);
	}

	else
	{
		fm_inst_print();
		return(0);
	}
}



int		Oct_print()
{
	DSP_str(x0+66,y0+87,C_WHITE,C_HBLACK,16,"O%d",oct);
}


int		fmbload(char *fn)
{
	int		i;
	P_flag=0;
	SND_fm_bank_load(fn,Bname);

	for (i=0;i<6;i++)
		SND_inst_change(i,inst);
	Inst_print();
}

int		pmbload(char *fn)
{
	int		i;
	P_flag=1;
	SND_pcm_bank_load(fn,Bname);
	
	if (inst>31)
		inst=0;
		
	for (i=0;i<8;i++)
		SND_inst_change(i+64,inst);
	Inst_print();
}

int		instload(int flag)
{

	char	*fdl;
	int		ret;
	char	*fn;
	char	*ext;
	
	
	if ( (fdl = FDL_open(0))==NULL )
		return (ERR);
	FDL_set_title(fdl,"Inst.LOAD");

	if (flag==0)
		FDL_set_wildcard(fdl,"*.fmb");
	else
		FDL_set_wildcard(fdl,"*.pmb");

	for(;;)
	{
		ret=FDL_start(fdl);
		if (ret!=NORMAL)
			break;
		fn=FDL_get_filename(fdl);
		if (*fn == '\0')
			continue;
		
		if (flag==1)
			pmbload(fn);
		else
			fmbload(fn);

		FDL_close(fdl);
		return(0);
	}
}



int		event()
{
	char	*evt;
	int		para[1];
	char	*dlg;
	char	*mosTk;
	int		ret;

	if ( (evt=EVT_alloc(NULL,50))==NULL)
		return(ERR);
	para[0]=evt;
	dlg=DLG_open(DLGPOS_MOS_SET_CENTER,DLGPOS_MOS_SET_CENTER,
			 252,130,C_HBLACK,"setDispFunc",para);
	
	if (dlg==NULL)
	{
		EVT_free(evt);
		return(ERR);
	}
	
	mosTk=MOS_push();
	DLG_dsp(dlg);

	
	while(1)	/*メインループ*/
	{
		MOS_CON();
		ret=EVT_chk(evt,0);
		if (ret==9999)
			break;
	}

	
	DLG_close(dlg);
	EVT_free(evt);
	MOS_pop(mosTk);
	return(0);
}


int 	setDispFunc(char *dlg)
{

	int		xs,ys,x,y;
	char	*evt;
	int		nowCol;
	int		evtNo;
	int		para[1];
	int		i,j;


	x0=DLG_getFr(dlg,0);
	y0=DLG_getFr(dlg,1);
	xs=DLG_getFr(dlg,2);
	ys=DLG_getFr(dlg,3);


	para=DLG_getPtr(dlg);
	evt=para[0];
	
	DSP_boxfHol(x0+2,y0+2,x0+252-1,y0+2+20-1,PSET,C_MBLACK,C_WHITE,C_BLACK);
	DSP_str(x0+4,y0+4,C_WHITE,C_MBLACK,16,"Sand Key");
	EVT_set_mos(evt,4,0,MOSEVT_NOT|MOSEVT_QUICK,BTN_LEFT,
				x0,y0,x0+252-1,y0+20-1+2,"DlgMvFunc",dlg);/*ドラッグ用(0)*/

	DSP_boxfHol(x0+214,y0+4,x0+248,y0+4+15,PSET,C_MBLACK,C_WHITE,C_HBLACK);
	DSP_str(x0+216,y0+5,C_HRED,C_MBLACK,14,"EXIT");
	EVT_set_mos(evt,0,9999,MOSEVT_BTN,BTN_LEFT,
				x0+214,y0+4,x0+248,y0+4+15,NULL,NULL); /*終了(少し大きい)*/

	for (i=0;i<2;i++)
	{
		DSP_boxfHol(x0+252-35,y0+107-i*20,x0+252-2,y0+124-i*20,PSET,
					C_HBLUE,C_WHITE,C_BLUE);
		DSP_str(x0+252-33,y0+108-i*20,C_HWHITE,C_HBLUE-i,16,MOJI[i]);
		EVT_set_mos(evt,1+i*45,i,MOSEVT_BTN,BTN_LEFT,	/*音色ロード(1,46)*/
					x0+252-35,y0+107-i*20,x0+252-2,y0+124-i*20,
					"instload",NULL);
	}
	
	
	for(i=0;i<2;i++)	/*音色変更 (2..+,3..-)*/
	{
		DSP_boxHol(x0+22,y0+91+i*18,x0+40,y0+106+i*18,PSET,
					C_MBLACK,C_BLACK);
		DSP_str(x0+23,y0+94+i*18,C_HWHITE,C_HBLACK
				,12,"%c%c",0x2d-i*2,0x2d-i*2);
		EVT_set_mos(evt,i+2,1-i,MOSEVT_BTN|MOSEVT_QUICK,BTN_LEFT,
					x0+22,y0+91+i*18,x0+40,y0+106+i*18,
					"InstChange",NULL);
	}

	for(i=0;i<2;i++)	/*音色変更 2 (44..+,45..-)*/
	{
		DSP_boxHol(x0+2,y0+91+i*18,x0+17,y0+106+i*18,PSET,
					C_MBLACK,C_BLACK);
		DSP_str(x0+5,y0+93+i*18,C_HWHITE,C_HBLACK,12,"%c",0x2d-i*2);
		EVT_set_mos(evt,i+44,1-i,MOSEVT_BTN,BTN_LEFT,
					x0+2,y0+91+i*18,x0+17,y0+106+i*18,
					"InstChange",NULL);

	}

						/*音色表示ウィンドウ*/
	DSP_boxfHol(x0+108,y0+79,x0+109+8*12,y0+125,PSET,
				C_HBLACK,C_MBLACK,C_MBLACK);

	

	for (i=0;i<2;i++)		/*オクターブ上げ／下げ(5...+,6...-)*/
	{
		DSP_boxfHol(x0+58+i*18,y0+106,x0+73+i*18,y0+110+11,PSET,
					C_WHITE,C_HWHITE,C_MBLACK);
		DSP_str(x0+62+i*18,y0+110,COLMIX(C_MBLACK,C_CYAN),C_WHITE
				,8,"%c",0x2d-i*2);
		EVT_set_mos(evt,i+5,1-i,MOSEVT_BTN,BTN_LEFT,
					x0+58+i*18,y0+106,x0+73+i*18,y0+110+11,"OctChange",NULL);
	}

	for (i=0;i<22;i++)		/*ド－3オクターブ高いド (22-43)*/
	{
		DSP_boxfHol(x0+16+i*10,y0+24,x0+24+i*10,y0+72,PSET
					,C_HWHITE,C_WHITE,C_BLACK);
		EVT_set_mos(evt,i+22,i,MOSEVT_BTN,BTN_LEFT,
					x0+16+i*10,y0+24,x0+24+i*10,y0+72,"WhiteKey",NULL);
	}

	for (j=0;j<3;j++)
	{
		for (i=0;i<2;i++)		/*黒鍵の左半分(7-20)*/
		{
			DSP_boxfHol(x0+21+i*10+j*70,y0+24,x0+27+i*10+j*70,y0+48,PSET,
						C_MBLACK,C_RED,C_BLACK);
			EVT_set_mos(evt,i+j*5+7,i+j*5,MOSEVT_BTN,BTN_LEFT,
						x0+21+i*10+j*70,y0+24,x0+27+i*10+j*70,y0+48,
						"BlackKey",NULL);
		}
		
		for (i=0;i<3;i++)		/*黒鍵の右半分*/
		{
			DSP_boxfHol(x0+51+i*10+j*70,y0+24,x0+57+i*10+j*70,y0+48,PSET,
						C_MBLACK,C_RED,C_HBLACK);
			EVT_set_mos(evt,i+j*5+9,i+j*5+2,MOSEVT_BTN,BTN_LEFT,
						x0+51+i*10+j*70,y0+24,x0+57+i*10+j*70,y0+48,
						"BlackKey",NULL);
		}
	}

		
	/* とどめ */
	Inst_print();
	Oct_print();

}

int		W_KEY[22] = {0,2,4,5,7,9,11,
					12,14,16,17,19,21,23,
					24,26,28,29,31,33,35,
					36};

int		B_KEY[15] = {1,3,6,8,10,13,15,18,20,22,
					25,27,30,32,34};


int		KeyOff()
{
	SND_key_off(key_flag+P_flag*64);
	key_flag++;
	if (key_flag>5)
		key_flag=0;
}

int		WhiteKey(int cl)
{
	KeyOff();
	SND_key_on(key_flag+P_flag*64,oct*12+W_KEY[cl],120);
}

int		BlackKey(int cl)
{
	KeyOff();
	SND_key_on(key_flag+P_flag*64,oct*12+B_KEY[cl],120);
}


int		OctChange(int cl)
{
	if (cl==0)
	{
		oct++;
		if (oct>6)
			oct=6;
	}
	else
	{
		oct--;
		if (oct<1)
			oct=1;
	}

	Oct_print();
}



int		Tone(int inst)
{
	int		i;
	for(i=0;i<6;i++)
		SND_inst_change(i+P_flag*64,inst);
}


int		InstChange(int cl)
{
	int		i;

	for (i=0;i<6;i++)
		SND_key_abort(P_flag*64+i);

	if (cl==0)
	{
		inst++;
		if (inst>127-P_flag*96)
		{
			inst=0;
		}
	}
	else
	{
		inst--;
		if (inst<0)
		{
			inst=127-P_flag*96;
		}
	}
	Tone(inst);

	Inst_print();
}

/*************************************************************************
*	MAIN
*************************************************************************/

int		main( int argc, char **argv )
{
	init();
	Snd_init();

	event();
	term();
	return (0);
}
