/*
	＜スワンで演奏＞
	わんだーりこーだー・WWGP2001応募作品
		(c)2001,Effect(effect@msa.biglobe.ne.jp)

	Ver1.00  2001/01/31
*/

#include <sys/bios.h>

/*周波数データ．A-〜>G<を0〜11、半音刻み*/
int c_freq[] = {
	1861,	1756,	1658,	1565,
	1477,	1394,	1316,	1242,
	1172,	1106,	1044,	986
};

/*音符データ．X3から反時計周りに8つ．C＝4*/
int c_note[] = {
	4,	6,	8,	9,
	11,	-1,	1,	3
};

/*波形データ．50％矩形*/
char c_wave[] = {
	0xff,	0xff,	0xff,	0xff,
	0xff,	0xff,	0xff,	0xff,
	0x00,	0x00,	0x00,	0x00,
	0x00,	0x00,	0x00,	0x00
};

/*フォントデータ*/
unsigned char c_font[][8] = {
	0x00,	0x70,	0x78,	0x24,	0x22,	0x7e,	0x7e,	0x00,	/*A*/
	0x00,	0x7e,	0x7e,	0x4a,	0x4a,	0x7e,	0x34,	0x00,	/*B*/
	0x00,	0x3c,	0x7e,	0x42,	0x42,	0x42,	0x42,	0x00,	/*C*/
	0x00,	0x7e,	0x7e,	0x42,	0x42,	0x7e,	0x3c,	0x00,	/*D*/
	0x00,	0x7e,	0x7e,	0x4a,	0x4a,	0x4a,	0x4a,	0x00,	/*E*/
	0x00,	0x7e,	0x7e,	0x12,	0x12,	0x12,	0x12,	0x00,	/*F*/
	0x00,	0x3c,	0x7e,	0x42,	0x4a,	0x7a,	0x7a,	0x00,	/*G*/
	0x00,	0x4e,	0x4a,	0x7a,	0x02,	0x7e,	0x02,	0x00,	/*ST*/
	0x00,	0x42,	0x66,	0x38,	0x1c,	0x66,	0x42,	0x00,	/*X*/
	0x00,	0x06,	0x0e,	0x78,	0x78,	0x0e,	0x06,	0x00,	/*Y*/
	0x00,	0x48,	0xfe,	0x24,	0x24,	0x7f,	0x12,	0x00,	/*#*/
	0x00,	0x00,	0x7f,	0x48,	0x44,	0x24,	0x18,	0x00,	/*b*/
	0x04,	0x04,	0x1c,	0x1c,	0x1c,	0x1c,	0x04,	0x04,	/*r*/
	0x7e,	0x0a,	0x00,	0x7a,	0x00,	0x78,	0x08,	0x70	/*Fin*/
};



/*音符→周波数*/
int note_freq(int in_oct, int in_note)
{
	int the_note = in_note + in_oct * 12;	/*音階を番号に*/
	int out_freq = c_freq[the_note % 12];	/*出力*/

	out_freq >>= (the_note / 12);	/*2のn乗倍*/
	return out_freq;
}



/*キー入力→数字．Xボタンを8方向で出力．X3が0で反時計まわり*/
int get_key(int in_key)
{
	int the_key;	/*キー入力*/
	int out_keyx = -1;	/*出力*/

	/*Xボタンを取り出す*/
	the_key = in_key & (KEY_X1 | KEY_X2 | KEY_X3 | KEY_X4);

	if(the_key & KEY_X3){	/*右を優先*/
		the_key &= (~KEY_X1);
	}
	if(the_key & KEY_X2){	/*上を優先*/
		the_key &= (~KEY_X4);
	}

	switch(the_key){
	case KEY_X3:
		out_keyx = 0;
		break;
	case KEY_X3|KEY_X2:
		out_keyx = 1;
		break;
	case KEY_X2:
		out_keyx = 2;
		break;
	case KEY_X1|KEY_X2:
		out_keyx = 3;
		break;
	case KEY_X1:
		out_keyx = 4;
		break;
	case KEY_X1|KEY_X4:
		out_keyx = 5;
		break;
	case KEY_X4:
		out_keyx = 6;
		break;
	case KEY_X3|KEY_X4:
		out_keyx = 7;
		break;
	default:
		out_keyx = -1;
		break;
	}
	return out_keyx;
}



/*ピッチ決定＆発音*/
void set_pitch(int in_key)
{
	int the_keyx;	/*Xキー*/
	int the_note;	/*音階番号*/
	int the_oct;	/*オクターブ*/

	/*どの鍵盤？*/
	the_keyx = get_key(in_key);
	if(the_keyx < 0){	/*押してない*/
		return;
	}
	if(c_note[the_keyx] < 0){	/*音符がない*/
		return;
	}

	/*シャープ＆フラット*/
	the_note = c_note[the_keyx];
	if(in_key & KEY_Y2){
		the_note++;
	}else if(in_key & KEY_Y4){
		the_note--;
	}

	/*オクターブ*/
	if(in_key & KEY_Y3){	/*上*/
		the_oct = 3;
	}else if(in_key & KEY_Y1){	/*下*/
		the_oct = 1;
	}else{
		the_oct = 2;
	}

	/*発音*/
	if((in_key & KEY_B) == 0){
		sound_set_pitch(0, (2048 - note_freq(the_oct, the_note)));
		sound_set_volume(0, 0xff);
	}
}



/*初期化*/
void init()
{
	int i;	/*ループ用*/
	int the_c[504];	/*キャラクタ敷き詰め用*/

	/*音源初期化*/
	sound_init();
	sound_set_output(0x09);
	sound_set_wave(0, c_wave);	/*波形セット*/
	sound_set_volume(0, 0);
	sound_set_channel(1);

	/*画面の初期化*/
	text_screen_init();
	for(i = 0; i < 504; i++){
		the_c[i] = i+8;
	}
	screen_set_char(SCREEN2, 0, 0, 28, 18, the_c);

	lcd_set_segments(LCDSEG_VERTICAL);	/*縦持ちマーク点灯*/
	font_set_color(0x03);
	text_put_string(1, 2, "←");
	text_put_string(1, 4, "→");
	font_set_monodata(0 + 3*28 + 8, 1, c_font[11]);
	font_set_monodata(2 + 3*28 + 8, 1, c_font[10]);
	font_set_monodata(1 + 13*28 + 8, 1, c_font[6]);
	font_set_monodata(2 + 13*28 + 8, 1, c_font[5]);
	font_set_monodata(0 + 14*28 + 8, 1, c_font[0]);
	font_set_monodata(2 + 14*28 + 8, 1, c_font[4]);
	font_set_monodata(0 + 15*28 + 8, 1, c_font[1]);
	font_set_monodata(1 + 15*28 + 8, 1, c_font[2]);
	font_set_monodata(2 + 15*28 + 8, 1, c_font[3]);
	font_set_monodata(13 + 15*28 + 8, 1, c_font[13]);
	font_set_monodata(26 + 15*28 + 8, 1, c_font[12]);

	font_set_color(0x0c);	/*色反転*/
	text_put_string(0, 17, " わんだーりこーだー V1.00  (c)Effect ");
	text_put_string(0, 0, " tceffE)c(  00.1V ーだーこりーだんわ ");
	screen_fill_attr(SCREEN2, 0, 0, 28, 1, 0xc000, 0xffff);	/*逆さ表示*/
	font_set_monodata(1 + 3*28 + 8, 1, c_font[9]);
	font_set_monodata(1 + 14*28 + 8, 1, c_font[8]);
	font_set_monodata(14 + 15*28 + 8, 1, c_font[7]);
	font_set_monodata(27 + 15*28 + 8, 1, c_font[1]);
	font_set_color(0x03);
}



/*プログラムメイン*/
void main()
{
	int the_key_prev = -1;	/*直前のキー状態*/
	int the_key = -1;	/*現在のキー状態*/
	int the_loop = 1;	/*ループフラグ*/

	init();
	while(the_loop){
		the_key = key_press_check();
		if(the_key != the_key_prev){	/*変わった？*/
			sound_set_volume(0, 0);
			set_pitch(the_key);
			sys_wait(1);
			the_key_prev = the_key;
		}
		if(the_key == KEY_START){	/*STARTで終了*/
			the_loop = 0;
		}
	}
	sound_init();
}
