/***  ＣＤＤＡ演奏ドライバ  ***/

#include <string.h>
#include <cdrfrb.h>
#include <snd.h>

#include "calc.h"
#include "graphic.h"
#include "spr_drv.h"

#define CD_SWITCH			( 0 < CD_type )

#define CD_STIME( n )	CD_timedata[ n ].start
#define CD_ETIME( n )	CD_timedata[ n ].end
#define CD_PLAYS		CD_timedata[ play_trkbeg ].start
#define CD_PLAYE		CD_timedata[ play_trkend ].end

#define F_TIME( s )			( (s).min*(75*60) + (s).sec*75 + (s).frame )
#define DATA_TRACK( n )		( ( CD_STIME( n ).min & 128 )!= 0 )

int		CD_type = 0, CD_trkbeg, CD_trkmax, CD_prgmax ;
int		play_trkbeg, play_trkend, CDI_err ; ;
char	CD_prog[256] ;

struct { struct TIMEADRS start, end ; } CD_timedata[100];

/***  ＣＤＤＡ設定  ***/

int CDDA_reset( void )
{
	struct	TIMEADRS	buf[100], disc_time ;
	int		i, t ;

	do{
		CDI_err = cdr_cdinfo(0,&CD_type,&CD_trkbeg,&CD_trkmax,buf,&disc_time);
	}while( CDI_err == CDERR3 || CDI_err == CDERR7 );

	if( CDI_err != 0 ){
		CD_type = 0, cdr_mstop(0);
		return CDI_err ;
	}

	/*  演奏開始・終了時間セット  */
	CD_STIME( CD_trkmax + 1 ).min	= disc_time.min ;
	CD_STIME( CD_trkmax + 1 ).sec	= disc_time.sec ;
	CD_STIME( CD_trkmax + 1 ).frame = disc_time.frame ;

	for( i = CD_trkmax ; 0 < i ; i-- ){ 
		CD_STIME( i ).min	= buf[ i-1 ].min ;
		CD_STIME( i ).sec	= buf[ i-1 ].sec ;
		CD_STIME( i ).frame	= buf[ i-1 ].frame ;
		t = F_TIME( CD_STIME( i + 1 ) )- 1 ;
		CD_ETIME( i ).min	= t / (75*60) ;
		CD_ETIME( i ).sec	= ( t / 75 )% 60 ;
		CD_ETIME( i ).frame	= t % 75 ;
	}

	/*  データトラックスキップ  */
	if( 1 < CD_type ){
		/*  先頭にデータトラックが無い場合に対応させる（ＣＤ−ロムロム等） */
		while( DATA_TRACK( CD_trkbeg ) == 0 && CD_trkbeg < CD_trkmax ){
			CD_trkbeg++ ;
		}
		CD_trkbeg++ ;
	}

	/*  プログラムセット  */
	if( 0 < ( CD_prgmax = CD_trkmax - CD_trkbeg + 1 ) ){
		for( i = 0 ; i < CD_prgmax ; i++ ) CD_prog[ i + 1 ] = CD_trkbeg + i ;
	}
	return CDI_err ;
}

/***  ＣＤＤＡ演奏  ***/

int CDDA_play( int start, int end, int rep )
{
	int		c ;

	CDI_err = 0 ;
	do{
		if( CD_type == 0 || CDI_err == CDERR7 ){
			if( ( CDI_err = CDDA_reset() )!= 0 ) return CDI_err ;
		}
		play_trkbeg = start, play_trkend = end ;
		if( end		== 0 ) play_trkend = CD_trkmax ;
		if( start	== 0 ) play_trkbeg = CD_trkbeg ;

		c = 5, cdr_pause( 0 );
		do{
			CDI_err = cdr_mtrplay( 0, &CD_PLAYS, &CD_PLAYE, rep );
		}while( 0 < --c && CDI_err == CDERR3 );

	}while( CDI_err == CDERR7 );

	return CDI_err ;
}

int CDDA_prog_play( int start, int rep )
{
	int		c ;

	CDI_err = 0 ;
	do{
		if( CD_type == 0 || CDI_err == CDERR7 ){
			if( ( CDI_err = CDDA_reset() )!= 0 ) return CDI_err ;
		}
		if( start < 1 || CD_prgmax < start ) return CDERR1 ;

		play_trkbeg = play_trkend = CD_prog[ start ];

		c = 5, cdr_pause( 0 );
		do{
			CDI_err = cdr_mtrplay( 0, &CD_PLAYS, &CD_PLAYE, rep );
		}while( 0 < --c && CDI_err == CDERR3 );

	}while( CDI_err == CDERR7 );

	return CDI_err ;
}

int	CDDA_pause( void )
{
	if( CD_SWITCH ){
		CDI_err = cdr_pause( 0 );
		CD_type = ( CDI_err != CDERR0 && CDI_err != CDERR7 ? CD_type : 0 );
	}
	return CDI_err ;
}

/***  ＢＧＭ設定  ***/

#define DSP_MUSNAME( n, col ) \
	put_string( 96, 30+n*10, ( n < CD_prgmax )? nam_p[n] : exit_str, col )

QUAD	pad_plus4[16] = {
	 0,0,  0,1,  0,-1,  0,0, 1,0, 0,0, 0, 0, 1,0,
	-1,0,  0,0,  0, 0, -1,0, 0,0, 0,1, 0,-1, 0,0
};
char	exit_str[] = "EXIT" ;

int		put_string( int x, int y, char *p, int col );
char	*set_num( int n, int wd );

void dsp_musnum( int n )
{
	if( CD_SWITCH == ON ){
		put_string( 208, 30+n*10, set_num( CD_prog[n+1], 2 ), GRB(28,28,28) );
	}else{
		put_string( 208, 30+n*10, "--", GRB(27,27,27) );
	}
}

int config_BGM( char *BGMname_p )
{
	char	*nam_p[20];
	int		button, ct_trig, bs_trig, trig ;
	int		sel, n, x, y, max ;

	CDDA_pause();

	for( n = 0 ; *BGMname_p != '\0' ; n++ ){
		nam_p[n] = BGMname_p, BGMname_p = strchr( BGMname_p, '\n' ) + 1 ;
	}
	CD_prgmax = max = n, sel = 0, bs_trig = 0 ;

	box_fill( 0, 0, 320, 240, PSET, 0x8000, 0x8000 );

	put_string( 92, 10, "BGM CONFIGURATION", GRB(31,24,24) );
	for( n = 0 ; n < CD_prgmax ; n++ ){
		DSP_MUSNAME( n, GRB(28,28,28) ), dsp_musnum( n );
	}
	DSP_MUSNAME( CD_prgmax, GRB(28,28,28) );
	DSP_MUSNAME( sel, GRB(31,31,16) );
	put_string( 40, 232, "PUSH SELECT TO CD STOP/START", GRB(24,31,24) );

	do{
		SND_joy_in_2( 0, &button );
		ct_trig = bs_trig, bs_trig = ~button & 255 ;
		trig	= bs_trig & ~ct_trig ;
		x = pad_plus4[ ~trig & 0xf ].x ;

		if( x != 0 && sel < CD_prgmax && CD_SWITCH == ON ){
			n = CD_prog[ sel + 1 ] + x ;
			if( n < CD_trkbeg || CD_trkmax < n ) x = 0 ;
			CD_prog[ sel + 1 ] += x ;
			dsp_musnum( sel );

		}else if( ( y = pad_plus4[ ~trig & 0xf ].y )!= 0 ){
			if( sel + y < 0 || CD_prgmax < sel + y ) y = 0 ;
			DSP_MUSNAME( sel, GRB(28,28,28) ), sel += y ;
			DSP_MUSNAME( sel, GRB(31,31,16) );
		}
		if( ( trig & 0x20 )!= 0 && CD_SWITCH == ON ){
			if( sel == CD_prgmax ) break ;
			CDDA_prog_play( sel + 1, 1 );
		}else if( ( trig & 0x80 )!= 0 ){
			if( CD_SWITCH == ON ){
				cdr_mstop(0), CD_type = 0 ;
			}else{
				CDDA_reset(), CD_prgmax = max ;
			}
			for( n = 0 ; n < CD_prgmax ; n++ ) dsp_musnum( n );
		}
		wait( 20000 );
	}while( ( trig & 0x40 )== 0 );

	box_fill( 0, 0, 320, 240, PSET, 0x8000, 0x8000 );

	return 0 ;
}
