/*
			MOV SYSTEM DEMO PLAY

			Hiroshi TODA
			1992 2/7

*/

#include <stdio.h>
#include <stdlib.h>
#include <egb.h>
#include <mos.h>
#include <cdrfrb.h>
#include <snd.h>
#include "video.h"
#include "ugoku.h"

#define C_WT 0x7fff		/* カーソル color */
#define C_PL 0			/* 初期プレーン color */
#define C_FL 0x303030		/* files back color */
#define C_COLOR 15		/* Command color palette */
#define W_COLOR 8		/* Window color palette */
#define B_COLOR 7		/* Back color palette */
#define E_COLOR 10		/* ERROR color palette */
#define P_COLOR 12		/* PLAY color palette */

extern unsigned int VSYNC_counter;	/* vsync counter */

int sw = 0, cx = 0, cy = 0;	/* MOUSE data */

char directory[100] ;
char newDirectory[100] ;
char otherDriveDirectory[100] ;
int driveNum ;
char para[256];		/* PARAM */
char gwork[1024];	/* 自家製 graphic work */
char swork[16384];	/* SND work */
char ework[1536];	/* EGB work */
char mwork[4096];	/* MOUSE work */

void ini()
{

	extern int getCurrentDisk() ;
/*	extern int get_directory( int drive, char *path_name_address );	*/

	SND_init(swork);
	SND_elevol_init();
	SND_elevol_mute(0x03);
	SND_elevol_set( 1, 127, 127 );

	EGB_init(ework,1536);			/* graph ini */
	EGB_resolution(ework,0,10);		/* 2画面合成 */
	EGB_resolution(ework,1,10);
	EGB_displayPage(ework,0,3);
	EGB_writePage(ework,0);			/* 画面0設定 */
	EGB_displayStart(ework,2,2,2);
	EGB_displayStart(ework,3,320,240);
	EGB_writePage(ework,1); 		/* 画面1設定 */
	EGB_displayStart(ework,2,2,2);
	EGB_displayStart(ework,3,320,240);

//	MOS_start(mwork,4096);			/* mouse ini */
//	MOS_resolution(0,10);
//	MOS_resolution(1,3);
//	MOS_writePage(1);
//	MOS_horizon(0,639);
//	MOS_vertical(0,479);
//	MOS_disp(0);
//	MOS_setpos( 320, 240 );

	DWORD(para+0) = 0;			/* key ini */
	keyin(gwork,para);
	DWORD(para+0) = 0x0200;			/* ASCII code */
	DWORD(para+4) = 0;
	DWORD(para+8) = 0;
	DWORD(para+12) = 0;
	keyin(gwork,para);

	int drv ;

	drv = getCurrentDisk() ;
	driveNum = drv ;
	directory[0] = 0x41 + drv ;
	directory[1] = ':' ;
	directory[2] = '\\' ;
	get_directory( drv + 1, directory + 3 );

	otherDriveDirectory[0] = 0 ;
}

void end()
{
	extern int changeCurrentDirectory( char *path_name_address ) ;
	extern int changeDisk( int ) ;

//	MOS_end();
	EGB_init(ework,1536);
	DWORD(para+0) = 0;
	SND_elevol_mute(0);
	SND_end();
	keyin(gwork,para);

	if( otherDriveDirectory[0] )
		changeCurrentDirectory( otherDriveDirectory ) ;
	changeCurrentDirectory( directory ) ;
	changeDisk( driveNum ) ;

}

/*
mouse(mmd)
int mmd;
{
	int s, x, y;

	do{
		MOS_rdpos(&sw,&cx,&cy);
	}while( sw == 0 );
	if( mmd == 0 ){
		do{
			MOS_rdpos(&s,&x,&y);
		}while( s );
	}
	return 0;
}
*/

itochar(n,count,p)	/* n --> char p[count] */
int n,count;
char *p;
{
	char dsp[] = "0123456789ABCDEF";

	switch( count ){
		case 8: *p++ = dsp[ n/10000000 ];
			n = n % 10000000;
		case 7: *p++ = dsp[ n/1000000 ];
			n = n % 1000000;
		case 6: *p++ = dsp[ n/100000 ];
			n = n % 100000;
		case 5: *p++ = dsp[ n/10000 ];
			n = n % 10000;
		case 4: *p++ = dsp[ n/1000 ];
			n = n % 1000;
		case 3: *p++ = dsp[ n/100 ];
			n = n % 100;
		case 2: *p++ = dsp[ n/10 ];
			n = n % 10;
		case 1: *p++ = dsp[ n ];
			*p = (char)0;
	}
	return 0;
}

/*
gprint( p, x, y )
char *p;
int x,y;
{
	int i;
	char dsp[86];

	EGB_writePage(ework,0);

	EGB_color(ework,0,C_COLOR);
	EGB_color(ework,2,C_COLOR);

	WORD(dsp+0) = x;
	WORD(dsp+2) = y;
	for ( i=0 ; i<80 ; i++ ){
		dsp[ i + 6 ] = (char)( BYTE( p + i ) );
		if( dsp[ i + 6 ] == (char)0 )break;
	}
	WORD(dsp+4) = i;
	EGB_writeMode(ework,0);
	EGB_sjisString(ework,dsp);
	return 0;
}
*/

/****** MOV *****/

/*  playv  */

	/* chek func */

int p_mov_play_check()
{
	int sw;

/*	注意:sw 押されているとbit off 押されてないとbit on 	*/

	SND_joy_in_1( 0xff, &sw );		/* end check */
	sw = (sw ^ 0xff) & 0x30;
	if( sw == 0 )return 0;
c01:	SND_joy_in_1( 0xff, &sw );
	sw = (sw ^ 0xff) & 0x30;
	if( sw & 0x10 ){
		while( sw == 0x30 ){
			SND_joy_in_1( 0xff, &sw );
			sw = (sw ^ 0xff) & 0x30;
		}
		if( sw == 0x20 )goto c02;
		while( sw ){
			SND_joy_in_1( 0xff, &sw );
			sw = (sw ^ 0xff) & 0x30;
			if( sw == 0x30 )break;
		}
		return 1;
	}
c02:	if( sw )goto c01;
	return -1;
}

/* on memory type */

p_mov_memory_play( name, wait, rep, page )
char *name;
int wait, rep;
{
	char *work ;
	int frame,x0,y0,x1,y1,wsize;
	int error;

	if( rep <= 0 )rep = 1 ;

	error
	 = mov_memory_play_init( name, p_mov_play_check,&frame,&x0,&y0,&x1,&y1,
	 &wsize );
	if( error )goto vd10;

	if( (work = (char *)malloc( wsize+153600 )) == NULL ){
		error = 7;
		goto vd10;			/* out of memory */
	}

		/* mute */
//	int s ;
//	SND_get_elevol_mute( &s ) ;
//	SND_elevol_mute( s | 0x03 ) ;

	error = mov_memory_play_repeat( work, work+153600, name, page, wait, rep);

//	SND_elevol_mute( s ) ;

	free( work );
vd10:
	return error;
}

/* disk read type */

p_mov_disk_play( name, wait, rep, page )
char *name;
int wait, rep;
{
	char *work ;
	int frame,x0,y0,x1,y1,wsize;
	int error;

	if( rep <= 0 )rep = 1 ;

	error
	 = mov_disk_play_init( name, p_mov_play_check,&frame,&x0,&y0,&x1,&y1,
	  &wsize );
	if( error )goto vd10;

	if( (work = (char *)malloc( wsize+153600 )) == NULL ){
		error = 7;
		goto vd10;			/* out of memory */
	}

		/* mute */
//	int s ;
//	SND_get_elevol_mute( &s ) ;
//	SND_elevol_mute( s | 0x03 ) ;

	error = mov_disk_play_repeat( work, work+153600, name, page, wait, rep);

//	SND_elevol_mute( s ) ;

	free( work );
vd10:
	return error;
}


/* path = fullname(path) + name 合成 */

make_path_name( path, fulname, name )
char path[], fulname[], name[];
{
	int i, k;

	for( k=0 ; k<80 ; k++ ){
		path[k] = fulname[k];
		if( path[k] == (char)0 )break;
	}
	for( i=k ; i>=0 ; i-- ){	/* path name 抽出 */
		if( path[i] == '\\' || path[i] == ':' )break;
	}
	for( k=0 ; k<13 ; k++ ){
		path[i+1+k] = name[k];
		if( name[k] == (char)0 )break;
	}
	return 0;
}

movfile( name, namemov )
char name[], namemov[];
{
	int i;

	for( i=0 ; i<76 ; i++ ){
		namemov[i] = name[i];
		if( name[i] == '.' || name[i] == (char)0 )goto mov01;
	}
	return 55;		/* bad file name */
mov01:	if( i == 0 )return 55;
	namemov[i++] = '.'; namemov[i++] = 'M'; namemov[i++] = 'O';
	namemov[i++] = 'V'; namemov[i] = (char)0;
	return 0;
}

/* time to frame */

cd_play_frame( time )
char *time;
{
	return BYTE(time+2) + BYTE(time+1)*75 + BYTE(time)*75*60;
}

/* frame to time */

cd_play_time( time, s )
char time[];
int s;
{
	int temp;

	time[2] = (char)(s % 75);
	temp = s / 75;
	time[1] = (char)(temp % 60);
	time[0] = (char)(temp / 60);
	return 0;
}

cd_play( time, count )
int time[], count;
{
	int type, s, e, i, start, end;
	char track[99][3];
	char total[3];
	char t[3], st[3], en[3], t1[3], t2[3];

	if( cdr_mstop(0) == 0 )goto cd01;
		/* 1回だけじゃだめなこともある !! */
cd01:
	for( i=0 ; i<4 ; i++ )
	{
		if( cdr_cdinfo(
			0, &type, &s, &e,
			(struct TIMEADRS *)(track), (struct TIMEADRS *)(total)
		) == 0 )goto cd02;
	}
	return -1;
cd02:	;

/*	for cd data check	*/
/*
	char out[10];
	EGB_writePage(ework,1);
	EGB_clearScreen( ework );
	for( j=0 ; j<8 ; j++ ){
		for( i=0 ; i<3 ; i++ ){
			itochar( (int)track[j][i], 3, out );
			gprint( out, i*32, j*40+20 );
		}
	}
	itochar( type, 3, out );
	gprint( out, 0, 400 );
	itochar( s, 3, out );
	gprint( out, 50, 400 );
	itochar( e, 3, out );
	gprint( out, 100, 400 );
	for( i=0 ; i<3 ; i++ ){
		itochar( (int)total[i], 3, out );
		gprint( out, i*32, 450 );
	}
	mouse(0);
*/

	t[0] = (char)time[1];
	t[1] = (char)time[2];
	t[2] = (char)time[3];
	start = cd_play_frame( t );
	if( time[0] < 1 )time[0] = 1;
	if( time[0] <= e ){
		for( i=time[0]-1 ; i<e ; i++ ){
			if( (BYTE( track[i] ) & 0x80) == 0 )break;
		}
		if( i == e )return -1;
		start = start + cd_play_frame( track[i] );
	}
	else start = cd_play_frame( total ) - 1;

	t[0] = (char)time[5];
	t[1] = (char)time[6];
	t[2] = (char)time[7];
	end = cd_play_frame( t );
	if( time[4] < 1 )time[4] = 1;
	if( time[4] <= e ){
		for( i=time[4]-1 ; i>=0 ; i-- ){
			if( (BYTE( track[i] ) & 0x80) == 0 )break;
		}
		if( i < 0 )return -1;
		end = end + cd_play_frame( track[i] );
	}
	else end = cd_play_frame( total ) - 1;
	if( start >= end )return -1;
	cd_play_time( st, start );
	cd_play_time( en, end );

/*	for cd data check	*/
/*
	EGB_writePage(ework,1);
	EGB_clearScreen( ework );
	for( i=0 ; i<3 ; i++ ){
		itochar( BYTE(st+i), 3, out );
		gprint( out, i*32, 20 );
	}
	for( i=0 ; i<3 ; i++ ){
		itochar( BYTE(en+i), 3, out );
		gprint( out, i*32, 40 );
	}
	mouse(0);
*/

	cdr_mtrplay( 0, (struct TIMEADRS *)(st), (struct TIMEADRS *)(en), 
													(unsigned char)count );

	for( i=0 ; i<1000 ; i++ )
	{							/* 演奏開始時に戻る */

		cdr_mphase( 0, &s, &e, 
				(struct TIMEADRS *)(t1), (struct TIMEADRS *)(t2) ) ;

		if( s )break;
	}
	return 0;
}

/* char *ad から n 個 →(atoi)→ s[] に代入 */

read_suuchi( s, ad, n )
int s[], n;
char ad[];
{
	int i, j;

	i = 0;
		/* 始めから数値でなければエラーを返す */
	if( (ad[i] < '0') || (ad[i] > '9') )return 1;
	for( j=0 ; j<n ; j++ ){
		while( ad[i] == '0' )i++;	/* 0X = 0 の仕様に対応 */
		s[j] = atoi( ad + i );
		while( (ad[i] >= '0') && (ad[i] <= '9') )i++;
		if( ad[i] == (char)0 )return 0;
		while(
		( (ad[i] < '0') || (ad[i] > '9') ) && (ad[i] > (char)0) )i++;
		if( ad[i] == (char)0 )return 0;
	}
	return 0;
}

void main(ac,av)
char ac,*av[];
{
	extern int changeCurrentDirectory( char *path_name_address ) ;
	extern int changeDisk( int ) ;

	FILE *fpt;
	char fullname[100];	/* PATH + FILES NAME1 */
	char namemov[80];	/* mov file name */
	char tablename[100];	/* PATH + FILES NAME1 */
	char para[80], out[80], dta[80];
	int rep[9][3], replv;
	int address, address2, cm;
	int tsize, i, n;
	int cdpl, play, disp, count, loop, memory, mute, wait;
	int cdtime[8], volu[3];
	char *table;

	ini();
	if( ac <= 1 )goto main0E;
main00:	if( ac >= 2 ){
		for( i=0 ; i<80 ; i++ ){
			tablename[i] = ( char )( BYTE( av[1] + i ) );
			if( tablename[i] == 0 )break;
		}
	}
	else goto main0E;
		/* table file size ck. */
	DWORD(para+0) = ( unsigned int )tablename;
	DWORD(para+4) = ( unsigned int )out;
	DWORD(para+8) = ( unsigned int )dta;
	DWORD(para+12) = 0x30;
	DWORD(para+16) = 0;
	if( files( gwork, para ) )goto main0E;
	tsize = DWORD( dta + 0x1a );
	if( (table = (char *)malloc( tsize+2 )) == NULL )goto main0E;
	if( ( fpt = fopen( tablename, "rb" ) ) == NULL )goto main0E;
	if( fread( table, tsize, 1, fpt ) < 1 ){
		fclose( fpt );
		free( table );
		goto main0E;
	}
	fclose( fpt );

	for( i=0 ; i<80 ; i++ )
	{
		newDirectory[i] = tablename[i] ;
		if( newDirectory[i] == 0 )break ;
	}
	for( i=i ; i>=0 ; i-- )
	{
		if( newDirectory[i] == '\\' )
		{
			if( i > 0 )
			{
				newDirectory[i] = 0 ;
				break ;
			}
			else
			{
				i++ ;
				newDirectory[i] = 0 ;
				break ;
			}
		}
		if( newDirectory[i] == ':' )
		{
			newDirectory[i+1] = 0 ;
			break ;
		}
	}
	if( newDirectory[1] == ':' )
	{
		int drv ;

		drv = ( ((int)(newDirectory[0])) & 0xdf ) - 0x41 ;
		if( drv < 0 )drv = 0 ;
		changeDisk( drv ) ;

		otherDriveDirectory[0] = 0x41 + drv ;
		otherDriveDirectory[1] = ':' ;
		otherDriveDirectory[2] = '\\' ;
		get_directory( drv + 1, otherDriveDirectory + 3 );

	}
	if( i > 0 )
	{
		changeCurrentDirectory( newDirectory ) ;
	}

	WORD( table +  tsize ) = 0x0a00;
	for( i=0 ; i<tsize ; i++ ){
		if( ((int)table[i] >= 0x41)
		 && ((int)table[i] <= 0x5a)
		)BYTE( table + i ) = BYTE( table + i ) + 0x20;
		if(	/* space などを 0 に */
		    (table[i] <= (char)0x20)
		 && (table[i] != (char)0x0a)
		)table[i] = (char)0;
	}
	n = 0; replv = 0;
	for( i=0 ; i<9 ; i++ )rep[i][0] = -1;
	rep[0][2] = 0;
	address = 0;
		/* main loop */
main01:	address2 = address;
	cdpl = 0; play = 0; disp = 0; count = 1;
	loop = 0; memory = 0; mute = 0; wait = 0;
	for( i=0 ; i<8 ; i++ )cdtime[i] = 0;
	cdtime[0] = 1; cdtime[4] = 100;
	volu[0] = 0; volu[1] = 127; volu[2] = 127;
main02:	while( table[address] == (char)0 )address++;
	if( address >= tsize )goto main90;
	if( table[address] == (char)0x0a )goto main90;
	cm = DWORD( table + address );
	if( cm == DWORD( "cdpl" ) )cdpl = 1;
	if( cm == DWORD( "cdst" ) )cdr_mstop(0);
	if( cm == DWORD( "cdpa" ) )cdr_pause(0);
	if( cm == DWORD( "cdco" ) )cdr_continue(0);
	if( cm == DWORD( "-sta" ) ){
		while( table[address] )address++;
		while( table[address] == (char)0 )address++;
		if( table[address] == (char)0x0a )goto main90;
		if( address >= tsize )goto main90;
		if( read_suuchi( cdtime, table+address, 4 ) )goto main10;
	}
	if( cm == DWORD( "-end" ) ){
		while( table[address] )address++;
		while( table[address] == (char)0 )address++;
		if( table[address] == (char)0x0a )goto main90;
		if( address >= tsize )goto main90;
		if( read_suuchi( cdtime+4, table+address, 4 ) )goto main10;
	}
	if( cm == DWORD( "volu" ) ){
		while( table[address] )address++;
		while( table[address] == (char)0 )address++;
		if( table[address] == (char)0x0a )goto main90;
		if( address >= tsize )goto main90;
		if( read_suuchi( volu, table+address, 3 ) )goto main10;
		SND_elevol_set( volu[0], volu[1], volu[2] );
	}
	if( cm == DWORD( "mute" ) ){
		while( table[address] )address++;
		while( table[address] == (char)0 )address++;
		if( table[address] == (char)0x0a )goto main90;
		if( address >= tsize )goto main90;
		if( read_suuchi( &mute, table+address, 1 ) )goto main10;
		SND_pcm_abort();	/* サウンド強制停止 */
		for( i=0 ; i<72 ; i++ )SND_key_abort( i );
		SND_elevol_mute( mute );
	}
	if( cm == DWORD( "loop" ) ){
		while( table[address] )address++;
		while( table[address] == (char)0 )address++;
		if( table[address] == (char)0x0a )goto main90;
		if( address >= tsize )goto main90;
		if( table[address] == 'e' )loop = -1;
		else if( read_suuchi( &loop, table+address, 1 ) )goto main10;
	}
	if( cm == DWORD( "-mem" ) ){
		while( table[address] )address++;
		while( table[address] == (char)0 )address++;
		if( table[address] == (char)0x0a )goto main90;
		if( address >= tsize )goto main90;
		if( table[address] == 'm' )memory = 0;
		else if( table[address] == 'd' )memory = 1;
		else goto main10;
	}
	if( cm == DWORD( "disp" ) ){
		while( table[address] )address++;
		while( table[address] == (char)0 )address++;
		if( table[address] == (char)0x0a )goto main90;
		if( address >= tsize )goto main90;
		if( table[address] == 'h' ){
			EGB_resolution(ework,0,10);		/* 2画面合成 */
			EGB_resolution(ework,1,10);
			EGB_displayPage(ework,0,3);
			EGB_writePage(ework,0);			/* 画面0設定 */
			EGB_displayStart(ework,2,2,2);
			EGB_displayStart(ework,3,320,240);
			EGB_writePage(ework,1); 		/* 画面1設定 */
			EGB_displayStart(ework,2,2,2);
			EGB_displayStart(ework,3,320,240);
		}
		else if( table[address] == 'i' ){
			EGB_resolution(ework,0,11);		/* 2画面合成 */
			EGB_resolution(ework,1,11);
			EGB_displayPage(ework,0,3);
			EGB_writePage(ework,0);			/* 画面0設定 */
			EGB_displayStart(ework,2,4,1);
			EGB_displayStart(ework,3,320,240);
			EGB_writePage(ework,1); 		/* 画面1設定 */
			EGB_displayStart(ework,2,4,1);
			EGB_displayStart(ework,3,320,240);
		}
		else goto main10;
	}
	if( cm == DWORD( "-cou" ) ){
		while( table[address] )address++;
		while( table[address] == (char)0 )address++;
		if( table[address] == (char)0x0a )goto main90;
		if( address >= tsize )goto main90;
		if( read_suuchi( &count, table+address, 1 ) )goto main10;
	}
	if( cm == DWORD( "play" ) ){
		while( table[address] )address++;
		while( table[address] == (char)0 )address++;
		if( table[address] == (char)0x0a )goto main90;
		if( address >= tsize )goto main90;
		for( i=0 ; i<80 ; i++ ){
			fullname[i] = table[address + i];
			if( fullname[i] == 0 )break;
		}
		play = 1;
	}
	if( cm == DWORD( "wait" ) ){
		while( table[address] )address++;
		while( table[address] == (char)0 )address++;
		if( table[address] == (char)0x0a )goto main90;
		if( address >= tsize )goto main90;
		if( read_suuchi( &wait, table+address, 1 ) )goto main10;
		VSYNC_init();
		VSYNC_counter = 0;
		while( VSYNC_counter < wait );	/* vsync counter */
		VSYNC_end();
	}
	while( table[address] )address++;
	if( address >= tsize )goto main90;
main10:	goto main02;

main90:	while( table[address] == (char)0x0a )address++;
	if( play ){
		if( movfile(fullname,namemov) == 0 ){
			if( memory ) p_mov_disk_play( namemov, 0, count, 2 ) ;
			else p_mov_memory_play( namemov, 0, count, 2 ) ;
		}
	}
	if( cdpl ){
		cd_play( cdtime, count );
	}
		/* replv = 1〜8 level は8まで */
	if( loop ){
	  if( loop > 0 ){		/* repeat start */
	    if( rep[replv][0] != address2 ){
	      replv++;			/* level++ */
	      if( replv > 8 )replv = 8;
	      rep[replv][0] = address2;	/* address */
	      rep[replv][1] = n - 1;		/* page (-1の調整必要) */
	      rep[replv][2] = loop - 1;	/* 回数 - 1 */
	    }
	  }
	  else {			/* repeat loop end */
	    if( rep[replv][2] ){
	      address = rep[replv][0];		/* address 修正 */
	      n = rep[replv][1];		/* page NO.修正 */
	      rep[replv][2]--;		/* 回数 dec. */
	    }
	    else {
	      replv--;			/* level-- */
	      if( replv < 0 )replv = 0;
	    }
	  }
	}
	n++;
	if( address >= tsize )goto main0E;
	else goto main01;
main0E:	cdr_mstop(0);
	end();
	return;
}
