#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <snd.h>
#include "defs.h"

#define BUFF_SIZE (66000)
#define BIOS_WORK_SIZE (16384)

extern char *swork;
extern char *SPCSTR;
extern BOOL Input();
extern void wrtstr();
extern int  File_sel();

       char buff[BUFF_SIZE];
static int buff_size;
static int buff_sw;
static char *buff_top[2];
static char *buff_btm[2];
static char status_save;

static char *bios_work;
static int tempo,signature;
static int eof;
static FILE *fp;

/*------------------------------------------------*/
int ML_Start(buffer,size,work)
char *buffer;
int size;
char *work;
{
	bios_work = work;
	if((buff_size = (size/12)*6) < 64)
		return(2);

	buff_top[0] = buffer;
	buff_btm[0] = buff_top[0] + buff_size -6;
	buff_top[1] = buff_top[0] + buff_size;
	buff_btm[1] = buff_top[1] + buff_size -6;

	SND_eup_init(bios_work);
	return(0);
}
/*------------------------------------------------*/
int ML_End()
{
	SND_eup_end();
	return(0);
}


/*------------------------------------------------*/
int ML_Set(path)
char *path;
{
	int i,err,size;
	char buffer[128];
	char bankpath[128];
	char fm_bankname[8];
	char pcm_bankname[8];
	char tmppath[128];
	char *p,*pp;

	eof = 1;
	
	if( (p = strrchr( path, '.' )) == NULL )
		return 1;
	if ( (strcmp( p, ".EUP") !=0) && 
		 (strcmp( p, ".eup") !=0) )
		return 1;
	
	if((fp = fopen(path,"rb")) == NULL)
		return(1);

	fseek(fp,852,SEEK_SET);

	if(fread(buffer,1,32,fp) < 32)
		goto ERROR;
	for(i=0 ; i<32 ;i++)
		err=SND_eup_mute_set(i,(int)buffer[i]);

	if(fread(buffer,1,32,fp) < 32)
		goto ERROR;
	for(i=0 ; i<32 ;i++)
		err=SND_eup_port_set(i,(int)buffer[i]);

	if(fread(buffer,1,32,fp) < 32)
		goto ERROR;
	for(i=0 ; i<32 ;i++)
		err=SND_eup_midi_ch_set(i,(int)buffer[i]);

	if(fread(buffer,1,32,fp) < 32)
		goto ERROR;
	for(i=0 ; i<32 ;i++)
		err=SND_eup_bias_set(i,(int)buffer[i]);

	if(fread(buffer,1,32,fp) < 32)
		goto ERROR;
	for(i=0 ; i<32 ;i++)
		err=SND_eup_transpose_set(i,(int)buffer[i]);
/*
channel assign
*/
	fseek(fp,1748,SEEK_SET);
	if(fread(buffer,1,6,fp) < 6)
		goto ERROR;
	for(i = 0;i < 6;i++)
		err=SND_midi_ch_assign(i,(int)buffer[i]);

	if(fread(buffer,1,8,fp) < 8)
		goto ERROR;
	for(i = 0;i < 8;i++)
		err=SND_midi_ch_assign(i+64,(int)buffer[i]);
/*
bank load
*/
	SND_pcm_mode_set(0);
	
	strcpy(	bankpath, path );
	if( ( p = strrchr( bankpath, '\\') ) == NULL )
		p = bankpath;
	else
		p++;

	if(fread( p,1,8,fp) < 8)
		goto ERROR;
	if( *p != '\0'){
		for( pp=p, i=0 ;(*pp != '\0')&&(i<8); i++, pp++ )
			;
		strcpy ( pp, ".FMB\0" );
		if ( SND_fm_bank_load( bankpath,fm_bankname) != 0 ){
			strcpy( tmppath, getenv("FMINST") );
			if( ( pp = strrchr( tmppath, '\\') ) == NULL )
				pp = tmppath;
			else
				pp++;
			strcat( pp, p );
			if ( SND_fm_bank_load( tmppath,fm_bankname) != 0 ){
        	    wrtstr(SPCSTR,30,1,0x1F);
	        	wrtstr("Can't open/read ",30,1,0x12);
	 	     	wrtstr( p,46,1,0x12);
	 		}
	    }
	}

	if(fread( p,1,8,fp) < 8)
		goto ERROR;
	if( *p != '\0'){
		for( pp=p, i=0 ;(*pp != '\0')&&(i<8); i++, pp++ )
			;
		strcpy ( pp, ".PMB\0" );
		if ( SND_pcm_bank_load( bankpath,pcm_bankname) != 0 ){
			strcpy( tmppath, getenv("PCMINST") );
			if( ( pp = strrchr( tmppath, '\\') ) == NULL )
				pp = tmppath;
			else
				pp++;
			strcat( pp, p );
			if ( SND_pcm_bank_load( tmppath,pcm_bankname) != 0 ){
         		wrtstr(SPCSTR,30,1,0x1F);
	    		wrtstr("Can't open/read ",30,1,0x12);
	        	wrtstr( p,46,1,0x12);
	        }
	    }
	}

	fseek(fp,2048,SEEK_SET);

	if(fread(&size,4,1,fp) < 1)
		goto ERROR;
	if(fread(buffer,1,2,fp) < 2)
		goto ERROR;
	signature = (int)buffer[0];
	tempo = (int)buffer[1];

	eof = 0;
	status_save = 0xfe;
	buff_sw = 1;
	load_sub();
	load_sub();
	SND_eup_tempo_set(tempo);
	return(0);
ERROR:
	fclose(fp);
	return(2);
}

/*------------------------------------------------*/
int ML_Play(mode)
int mode;
{
	SND_eup_loop_set(mode);
	SND_eup_play_start(buff_top[0],buff_size*2,signature);
	return(0);
}

/*------------------------------------------------*/
int ML_Stop()
{
	SND_eup_play_stop();
	if(eof == 0)
		fclose(fp);
	return(0);
}

/*------------------------------------------------*/
int ML_Check()
{
	char *ptr;

		if(eof != 0)
			return(0);
		ptr = SND_eup_stat_ptr();

		if(((buff_sw == 0) && (ptr <= buff_btm[0]))
				||((buff_sw == 1) && (ptr >= buff_top[1])))
			return(load_sub());
		else
			return(0);
			
}	

/*------------------------------------------------*/
int load_sub()
{
	char *ptr;
	char status;
	int sw;

	if(!buff_sw){
		buff_sw = 1;
		sw = 0;
	}
	else{
		buff_sw = 0;
		sw = 1;
	}
	ptr = buff_top[buff_sw];
	while((!eof) && (ptr <= buff_btm[buff_sw])){
		if(fread(ptr,1,6,fp) < 6){
			fclose(fp);
			return(2);
		}
		else if(*ptr == 0xfe){
			eof = 1;
			fclose(fp);
		}
		ptr = ptr + 6;
	}

	status = status_save;
	if(!eof){
		status_save = *buff_btm[buff_sw];
		*buff_btm[buff_sw] = 0xfd;
	}
	*buff_btm[sw] =  status;
	SND_eup_play_restart();
	return(0);
}




void	runeup()
{
static unsigned char filename[160]={ 0 };

	/* filename[0] = '\0'; */
    if ( Input(filename,"ﾌｧｲﾙ名:") != FALSE || File_sel(filename) != FALSE  )
	return;

	ML_Stop();
	wrtstr("ファイル読み込み中",30,1,0x15);

	if ( ML_Set( (char *)filename) ) {
		ML_Stop();
		goto ERROR;
	}
	ML_Play(0);
    wrtstr(SPCSTR,30,1,0x1F);
	wrtstr("　　演奏開始　　",30,1,0x15);
	return;
ERROR: ;
    wrtstr(SPCSTR,30,1,0x1F);
	wrtstr("演奏出来ません",30,1,0x12);
}


void stopeup(){
	ML_Stop();
}
