/*================================
	"prdemo.c" : Demonstration
================================*/
#include <fmcfrb.h>
#include <math.h>
#include "pad.h"
#include "timekh.h"
#include "prdef.h"

#define	startTM()	TIM_rdcalendar(&st)
#define waitTM(_t)	do{TIM_rdcalendar( &et );}while(getTime(st,et)<(_t))
#define readPad()	do{_outb(PADOUT,COM0);}while((_inb(PAD1IN)&COMIN)!=0);\
					pad=_inb(PAD1IN)
vect ortholize( vect vec );
vect exProduct( vect v1, vect v2 );

void putmap( int x0, int y0, int z0, vect ex, vect ey, vect ez );
void putcar( int x0, int y0, int z0, vect ex, vect ey, vect ez, int cpol );
int  mycar( short x, short y, short z, int ang, vect kv );
int  encar( short x, short y, short z, int ang, vect kv, int col, int pol );
void writeScreen();
void clearVram(int a,int b,int c);

void putMess( char *str, int col );
void clearMess();
void clearScreen();
void putLap( short *lap, char *str1, char *str2 );
void putTitle( short col );

extern changeMap( int mn );
extern int mapNo;
extern char	mapName[][15];

extern int *_cos,*_sin;
extern int   maxtime,h;
extern short blap[10],flap[10];

extern way *way1st,*waybst;
static way *ecs[6];

static TIM_CALEN	st,et;

int		demo( int dsp, short sx, short sy )
{
	int cs,sn;
	vect ex,ey,ez,kv ;	kv.x=0,kv.y=0,kv.z=1000 ;

	int x=sx,y=sy,z=0,ang=375,vx,vy,vz,vang,vp=1;
	int	messTime=0,pol,wait=100,mess=1;
	int	t=0,i,j,ef=0,v=-1;
	char	pad;
	int	cn=0,h=200,viewtime=30 ;

	while(1)
	{
		startTM();
		readPad();
	//	エスケープ
		if(PUSH(PADRUN+PADSEL)) {
			if (wait<0){
				do {
					readPad();
				}while(PUSH(PADRUN)||PUSH(PADSEL));
				ef = -1;
				break;
			}
		}
		else if((PUSH(PADSEL)&&wait<0)||v==-1)
		{
			wait = 100;
			if( mess!=0 ){
				/*if( v==0 ) clearMess();
				else*/ clearScreen();
				mess = 0;
			}
			if( v==-1 ) v=dsp-1;

			v = (v+1)%3;
			switch(v){
			  case 0:
				putTitle( 14 );
				cn = 0;
				messTime = 2500;
				mess = 2;
				break;
			  case 1:
				putLap( blap, mapName[mapNo], "Course Record" );
				messTime = 900;
				mess = 1;
				break;
			  case 2:
				putLap( flap, mapName[mapNo], "1stLap Record" );
				messTime = 900;
				mess = 1;
				break;
			  default :
				break;
			}
		}
		if(PUSH(PADB)&&messTime>=0) messTime -= maxtime*9;

		if( v==0 || v==1 ){
			for(i=0; i<6; ++i)
				ecs[i] = waybst+i;
		}else {
			for(i=0; i<6; ++i)
				ecs[i] = way1st+i;
		}

	//	ゲームスタート
		if (!PUSH(PADSEL)&&PUSH(PADRUN)&&wait<0){
			ef = 1; break;
		}
		if(wait>=0) wait -= maxtime;
	//	視点切り替え
		if (!PUSH(PADSEL)&&PUSH(PADU)&&viewtime<=0) {
			cn = (cn+1)%6 ;
			if (ecs[cn]->ltime==0)
				cn = 0;
			viewtime=30 ;
		}
		if (!PUSH(PADSEL)&&PUSH(PADD)&&viewtime<=0) {
			vp = (vp+1)%2;
			viewtime=50 ;
		}
		if (viewtime>0) viewtime-=maxtime;

		if (PUSH(PADL))	ang += maxtime*2;
		if (PUSH(PADR))	ang -= maxtime*2;

	//	マップ選択
		if (PUSH(PADA)&&wait<0) {
			changeMap((mapNo+1)%MAPS);
			cn = 0;
			t = 0;
			v =-1; dsp = 1;
		}
	//	メッセージの消去
		if( messTime>=0 )
			messTime -= maxtime;
		if( messTime<0 && mess!=0 ){
			clearScreen();
			mess=0;
		}

	//	車ポリゴンのセット
		pol = 0;
		for(j=0;j<6;j++)
		{
			if( ecs[j]->ltime!=0 && t<=ecs[j]->ltime ){
				i = C32K((j+2)%2,((j+2)/2)%2,((j+2)/4)%2);
				pol=encar( ecs[j]->pt[t].x,
						   ecs[j]->pt[t].y,
						   ecs[j]->pt[t].z,
						   ecs[j]->ang[t],
						   kv/*ecs[j]->kv[t]*/, i, pol
						 );
			}
		}

	//	画面表示
		if( ecs[cn]->ltime>=t ){
			x = ecs[cn]->pt[t].x ;
			y = ecs[cn]->pt[t].y ;
			z = ecs[cn]->pt[t].z ;
		}
		vang = ang ;
		cs = cos(_PI*2*vang/1000)*1000;
		sn = sin(_PI*2*vang/1000)*1000;
		switch(vp){
		  case 1:
			ey.x = kv.z*cs /1000 ;
			ey.y = kv.z*sn /1000 ;
			ey.z = -(kv.x*cs + kv.y*sn) /1000 ;
			ey = ortholize( ey ) ;
			ez.x = (1000-sn)*kv.x /1000 ;
			ez.y = (1000-cs)*kv.y /1000 ;
			ez.z = kv.z ;
			ez = ortholize( ez ) ;
			ex = exProduct( ez,ey ) ; // 左手系
			vx = x*10-ey.x*h/100+ez.x*h/800 ; // x,y[mm]
			vy = y*10-ey.y*h/100+ez.y*h/800 ; // h,height[cm]
			vz = z-ey.z*h/100+ez.z*h/800 ; // vx-z[cm]
			break ;
		  default :
			ey.x = cs*5000/5099 ;
			ey.y = sn*5000/5099 ;
			ey.z = -1000*1000/5099 ;
			ez.x = cs*1000/5099 ;
			ez.y = sn*1000/5099 ;
			ez.z = 1000*5000/5099 ;
			ex = exProduct( ez,ey ) ; // 左手系
			vx = x*10-ey.x*h/33 ;	// x,y[mm]
			vy = y*10-ey.y*h/33 ;	// z,h[cm]
			vz = z-ey.z*h/33 ;		// vx-vz[cm]
			break ;
		}

	//	画面表示
		clearVram( ex.z,ey.z,ez.z );
		putmap( vx,vy,vz, ex,ey,ez );
		putcar( vx,vy,vz, ex,ey,ez, pol );
		writeScreen();
	//	カウント終了処理
		waitTM(maxtime);
		t += maxtime;
		if( ecs[cn]->ltime<t ) t=0;
	}
	clearScreen();
	return ef;
}
