/*
	音声モードＰＣＭファイル　簡易切り出しツール
		(for FM-Towns GCC Compiler 1.36 with tbios library)

	Programed 1991 S.Kamio
	FM-Towns + 2 Mbyte memory + towns-menu + tbios system.

	1st version 0.1		july/7/1991
*/


#include <stdio.h>
#include <tbios.h>	/* my header */

byte s[256*1024];
byte ss[256*1024];
char fn[16];
int t[256];
int fsize,ffs;

void main (uint argc,char *argv[])
{
	uint i,ff;
	int gl=0,gr=639,cl=0;
	byte me[1024];
	FILE *fp,*fopen();

	putchar (12);
	for (i=0;i<2048;i++)
		putchar (32);
	putchar (12);
	fsize=_get_file_size(argv[1]);
	if (fsize<0)
	{
		printf ("not find.\n");
		printf ("usage : run386 se.exp <loadname.snd> <outputname.snd>\n");
		printf ("<outputname>は､現在開発中ですので､サポートしていません｡\n");
		printf ("<outputname>は､セーブ時に常に指定します。\n");
		printf ("全てのネームに、「．ｓｎｄ」は省略できません。\n");
		exit (1);
	}
	if (fsize>(256*1024))
	{
		printf ("size over.\n");
		exit (1);
	}
	if (argc!=2)
	{
		printf ("no enough parametors.\n");
		exit (1);
	}
	fp=fopen(argv[1],"rb");
	fread (&s[0],1,fsize,fp);
	fclose (fp);
	fsize=fsize-32;
	KBD_init ();
	for (i=128;i<256;i++)
		t[i]=i;
	for (i=0;i<128;i++)
		t[i]=128-i;
	t[255]=254;

	VGA480_init ();
	for (i=0;i<64;i++)
		EGB_palette (0,0x20+i,64,0,i);
	disp ();
	KBD_click (1);
	i=KBD_read ();
	while (i!=27)
	{
		if (gl<0)
			gl=0;
		if (gr<0)
			gr=0;
		if (gr>639)
			gr=639;
		if (gl>=gr)
			gl=gr;
		EGB_get (gl,0,gl,255,&me[0]);
		EGB_get (gr,0,gr,255,&me[256]);
		EGB_writecolor (253);
		EGB_line (gl,0,gl,255);
		EGB_line (gr,0,gr,255);
		EGB_writecolor (255);
		EGB_gprint (32,380,"コマンドを入力してください。");
		EGB_gprint (32,400,"キーボードでのみ操作可能です。");
		EGC_linebf256 (0,257,1023,269,2);
		EGC_linebf256 (gl,257,gr,269,221);
		EGB_put (gl,0,gl,255,&me[0]);
		EGB_put (gr,0,gr,255,&me[256]);
		i=KBD_inkey ();
		switch (i)
		{
			case 'p':
			case 'P':
				play (gl,gr);
				break;
			case 's':
			case 'S':
				play (gl,gr);
				EGC_linebf256 (0,380,1023,399,0);
				filename_in ();
				EGC_linebf256 (0,380,1023,511,0);
				EGB_gprint (32,380,"保存中です。けっこうかかりますよ！");
				EGB_gprint (32,400,"気長に待っててね！（＾＿＾）");
				if ((fp=fopen (&fn[0],"wb"))!=NULL)
				{
					fwrite (&ss[0],1,ffs,fp);
					close (fp);
				}
				EGC_linebf256 (0,380,1023,511,0);
				break;
			case 'g':
			case 'G':
				disp ();
				break;
			case 29 :
				if (cl==0)
					gl--;
				if (cl!=0)
					gr--;
				break;
			case 28 :
				if (cl==0)
					gl++;
				if (cl!=0)
					gr++;
				break;
			case '4':
				if (cl==0)
					gl-=16;
				if (cl!=0)
					gr-=16;
				break;
			case '6':
				if (cl==0)
					gl+=16;
				if (cl!=0)
					gr+=16;
				break;
			case ' ':
				cl=(cl+1) % 2;
				EGC_linebf256 (0,360,1023,399,0);
				if (cl==0)
				{
					EGB_gprint (520,380,"pen left.");
				} else
				{
					EGB_gprint (520,380,"pen right.");
				}
			default :
				EGC_linebf256 (320,460,1023,511,0);
				ff=((uint)s[24]+(uint)s[25]*256)*0x62;
				sprintf ((char *)&me[0],"(%d,%d)  debug %u Hz",gl,gr,ff);
				EGB_gprint (320,460,&me[0]);
				break;
		}
	}
	EGB_cls ();
	KBD_click (1);
	EGB_writepage (1);
	EGB_displaypage (1,3);
	printf ("EASY SOUND CUTTER. for all fm-townes with 2 Mbytes memory.\n");
	printf ("   ORICONS console emulators.\n");
	printf ("RUN386 se.exp <filename>\n");
	printf ("   <filename> must be '????.snd'\n");
	printf ("                       June 1991\n");
	byebee_menu ();
	exit (1);
}

disp ()
{
	int i;

	EGB_backcolor (0x00);
	EGB_cls ();
	EGB_writecolor (0xff);
	for (i=0;i<256;i++)
		EGC_linebf256 (0,i,639,i,0x20+abs((i % 64)-32));
	EGB_line (0,0,639,0);
	EGB_line (0,256,639,256);
	for (i=0;i<fsize;i++)
		EGC_pset256 (i*639/fsize,t[s[i+32]],0x4f+0x80);
	EGB_writecolor (0x68);
	EGB_gprint (5,270,"サウンド切断プログラム（開発途中版）　by s.kamio");
	EGB_writecolor (0x72);
	EGB_gprint (20,300,"ESC : END   /  P : PLAY   /  G : FLASH   /  S : SAVE");
	EGB_gprint (20,316,"(<- or 4) Pen move left. / (-> or 6) Pen move right.");
	EGB_gprint (20,332,"SPACE : Pen change.");
	EGB_writecolor (0xff);
}

/*
 私の製作したライブラリが、何故か１６ＫＨｚ未満の音声を再生しようとすると
 暴走してしまいます。そのために、一度２０ＫＨｚまで音声を引き延ばして再生しま
 す。
*/

ssplay (int fsp)
{
	byte c[340*1024];
	int i,ns,es,dd,ff;

	ff=(int)ss[24]+(int)ss[25]*256;
	EGC_linebf256 (0,380,1023,511,0);
	EGB_gprint (32,380,"再生用にデーターの加工をしています。");
	ns=fsp*1960/ff;
	if (ns>(340*1024))
	{
		printf ("memory over.\n");
		EGB_cls ();
		EGB_gprint (0,300,"Out of memory. Fatal error occured!");
		EGB_gprint (0,316,"20KHz play buffer = 340KByte (17 second)");
		exit (1);
	}
	dd=ff/2;
	es=32;
	for (i=32;i<ns;i++)		/* zooming */
	{
		c[i]=(byte)t[((t[ss[es]]*(1960-dd)+t[ss[es+1]]*dd)/1960)];
		dd=dd+ff;
		es=es+(dd/1960);
		dd=dd % 1960;
	}
	for (i=0;i<32;i++)
		c[i]=ss[i];
	EGC_linebf256 (0,380,1023,399,0);
	EGB_gprint (32,380,"確認再生をしています。");
	c[24]=1960 % 256;		/* new pcm frequency = 20 KHz */
	c[25]=1960 / 256;
	c[12]=ns % 256;			/* new size */
	c[13]=(ns/256) % 256;
	c[14]=(ns/256/256) % 256;
	c[15]=ns/256/256/256;
	c[26]=0;				/* not over 20000 Hz */
	c[27]=0;
	c[20]=0;				/* no loop */
	c[21]=0;
	c[22]=0;
	c[23]=0;
	SND_init ();
	SND_mute (0xff);
	SND_evolume (0,127,127);
	SND_voicechannel (3);
	SND_voiceplay (&c[0],71,60,60);
	waite (50);
	while (((SND_pad (1) & 0x10)!=0) && (SND_voicecondition (71)!=0))
		dclock ();
	SND_mute (0x00);
	SND_pcmstop ();
	SND_bye ();
	EGC_linebf256 (0,380,1023,399,0);
}

int KBD_inkey ()		/* 入力待ち付のキー入力 */
{
	int i;

	while ((i=KBD_read ())==0)
	{
		break_check ();
		dclock ();
	}
	return (i);
}

dclock ()
{
	byte c[8192];
	long t;

	t=time(0);
	EGC_linebf256 (0,480,1023,496,0);
	waite (8);
	EGB_writecolor (239);
	EGB_gprint (400,480,(char *)ctime((long *)&t));
	EGB_get (400,480,400+8*24,480+15,&c[0]);
	EGB_put (432,270,432+8*24,270+15,&c[0]);
	EGB_writecolor (255);
}

play (int gl,int gr)
{
	int i;
	int glp,grp,fsp;

	glp=gl*fsize/639;
	grp=gr*fsize/639;
	fsp=grp-glp;
	if (fsp>0)
	{
		for (i=0;i<32;i++)					/* header */
			ss[i]=s[i];
		for (i=0;i<(fsp+32);i++)			/* copy */
			ss[i+32]=s[32+glp+i];
		for (i=(fsp+32);i<(256*1024-32);i++)/* clear */
			ss[i+32]=128;
		ss[12]=fsp % 256;					/* new size */
		ss[13]=(fsp/256) % 256;
		ss[14]=(fsp/256/256) % 256;
		ss[15]=fsp/256/256/256;
		ss[16]=ss[17]=ss[18]=ss[19]=0;		/* loop point */
		ss[20]=ss[21]=ss[22]=ss[23]=0;		/* loop length */
		ffs=fsp+32;							/* new file size */
		ssplay (fsp);
	}
}

filename_in ()				/* ファイルネーム入力 */
{
	char q=0;
	int p;
	char mes[80];

	for (p=0;p<12;p++)
		fn[p]=0;
	p=0;
	KBD_click (0);
	while (q!=(char)13)
	{
		EGC_linebf256 (0,380,1023,511,0);
		EGB_gprint (32,380,"ファイルネームを入力してください。");
		EGB_gprint (32,400,"無効なネームを入力するとキャンセルします。");
		EGB_gprint (32,420,"「．ｓｎｄ」は省略できません。ＣＲで決定。");
		sprintf (&mes[0],"保存名称｢%s｣ : debug (%d) (%d)",&fn[0],p,(uint)q);
		EGB_gprint (0,440,&mes[0]);
		q=(char)KBD_inkey ();
		if (q>(char)31)
			fn[p++]=q;
		if (p>=11) p=11;
		if ((q==(char)8) && (p>0))
		{
			fn[--p]=0;
			EGB_gprint (480,440,"ＤＥＬＥＴＥ(debug)");
		}
	}
	fn[++p]=0;
	KBD_click (1);
}

byebee_menu ()					/* プログラムの終了 メニューに帰る */
{
	uint i;

	EGB_palette (0,255,0,0,0);
	EGB_backcolor (0xff);
	EGB_writecolor (0);
	EGB_cls ();
	EGB_gprint (200,160,"ＴＯＷＮＳ−ＭＥＮＵに戻ります。");
	for (i=0;i<=255;i+=4)
		EGB_palette (1,255,i,i,i);
	exit (0);
}
