/*---------------------------------------------------------------------------
  Ninja2 Toon Shader Sample
  COPYRIGHT (C) SEGA ENTERPRISES, LTD.
  2000.6.2 HK
---------------------------------------------------------------------------*/
//Header
#include	<shinobi.h>
#include	"Nj.h"

//Define
#define HK_TOONMODE_NE   0 //Noedge
#define HK_SIMPLEMODE_NE 1 //noedge
#define HK_TOONMODE_AE   2 //AutoEdge
#define HK_SIMPLEMODE_AE 3 //AutoEdge
#define HK_WIREMODE      4 //WIRE

#define HK_OBJONLY  0
#define HK_MOTION   1

#define HK_BLACK	0
#define HK_RED		1
#define HK_BLUE		2
#define HK_WHITE	3

#define HELP_Y_VGA		42
#define HELP_Y_DEF		15

#define MOT0	0
#define MOT1	1
#define MOT2	2
#define MOT3	3
#define MOT4	4
#define MOT5	5

#define OBJECT	 object_tnoedge_Bip01_Bip01

#define	TEX		texlist_tnoedge_Bip01

#define MOTION1	motion_tnoedge_sw_Bip01
#define MOTION2	motion_tnoedge_gun_Bip01
#define MOTION3	motion_tnoedge_run_Bip01
#define MOTION4	motion_tnoedge_tr_Bip01
#define MOTION5	motion_tnoedge_sk_Bip01

//Extern
extern	NJS_CNK_OBJECT	OBJECT[];
extern  NJS_TEXLIST TEX[];
extern	NJS_MOTION	MOTION1[];
extern	NJS_MOTION	MOTION2[];
extern	NJS_MOTION	MOTION3[];
extern	NJS_MOTION	MOTION4[];
extern	NJS_MOTION	MOTION5[];

//Static
NJS_VECTOR	light = { 0.f, 0.f, -1.0f };

static	Sint32	xx = 0;
static	Sint32	yy = 0;
static	Sint32	yy2 = 0;
static	Sint32	zz = 0;
static	Sint32	lx = 0;
static	Sint32	ly = 16000;

static Sint32 stopf = 0;
static Sint32 fuku = HK_BLACK;
static Sint32 mottype = MOT0;
static Sint32 ptime = 0;
static Sint32 shademode = HK_TOONMODE_AE;
static Sint32 helpy = 0;
static Sint32 info = 0;

static Sint32 check = 0;

static	Float	zzz = -10.f;
static	Float	xxx = 0.f;
static	Float	yyy = 0.f;

static	Float	speed = 0.5f;
static	Float	mo = 0.f;

/*---------------------------------------------------------------------------
		初期化
		initialize
---------------------------------------------------------------------------*/
Sint32	UserInit(void)
{
	//ケーブルチェック(文字表示制御)
	switch(syVideoGetCableType()){
		case SYD_VIDEO_CABLE_TYPE_VGA :
			helpy=HELP_Y_VGA;
			njPrintSize(8);
			break;
		default:
			helpy=HELP_Y_DEF;
			njPrintSize(16);
			break;
	}
	//バックグラウンドカラー
	njSetBackColor( 0x004444cc, 0x004444cc, 0x004444cc );
	//TOONライト
	njCnkSetToonLight( 0.5f, 0.5f, 0.5f );
	njCnkSetToonLightIntensity( 1.0f, 0.0f );
	njCnkSetToonShade( 0xffcccccc, 0xff404040 );
	//シンプルライト
	njCnkSetSimpleLight( 0.5f, 0.5f, 0.5f );
	njCnkSetSimpleLightIntensity( 0.8f, 0.2f );
	//カリング設定
	njPolygonCullingMode( NJD_POLYGON_CULLINGSMALL  ); 
	njPolygonCullingSize( 0.1f ); 
	//ワイヤーフレーム描画方式設定
	njCnkSetWireDrawMode(NJ_WIRE_REAL );
	//テクスチャ
	if(nuLoadTexture( TEX ) < 0){
		return USER_EXIT;
	}
	njSetTexture( TEX );
	
	return USER_CONTINUE;
}
/*---------------------------------------------------------------------------
		メイン
		main
---------------------------------------------------------------------------*/
Sint32 DrawMotion(Sint32 (*func)(NJS_CNK_MODEL *))
{

	njPushMatrixEx();	
	njTranslate( NULL, xxx-20, yyy-70, zzz-500 );
	njRotateXYZ( NULL, xx,yy2,zz );

	switch(mottype){
		case MOT1:
		njDrawMotion( OBJECT, MOTION1, mo,func );	
		break;				
		case MOT2:
		njTranslate( NULL, xxx, yyy-20, zzz+200 );
		njDrawMotion( OBJECT, MOTION2, mo, func );
		njTranslate( NULL, xxx, yyy+20, zzz-200 );
		break;
		case MOT3:
		njTranslate( NULL, xxx, yyy-20, zzz-300 );
		njDrawMotion( OBJECT, MOTION3, mo, func );
		njTranslate( NULL, xxx, yyy+20, zzz+300 );
		break;
		case MOT4:
		njTranslate( NULL, xxx, yyy, zzz-280 );
		njDrawMotion( OBJECT, MOTION4, mo, func );
		njTranslate( NULL, xxx, yyy, zzz+280 );
		break;
				case MOT5:
		njTranslate( NULL, xxx+80, yyy-20, zzz+20 );
		njDrawMotion( OBJECT, MOTION5, mo, func );
		njTranslate( NULL, xxx-80, yyy+20, zzz-20 );
		break;
	}
	
	njPopMatrixEx();
}


Sint32 ModelDraw()
{
	if(mottype==MOT0){//回転モーション
		njPushMatrixEx();	
		njTranslate( NULL, xxx, yyy+30, zzz-180 );
		njRotateXYZ( NULL, xx,yy,zz );
		
		switch(shademode){
			case HK_TOONMODE_NE:
				njCnkToonDrawObject( OBJECT );
				break;
			case HK_SIMPLEMODE_NE:
				njCnkSimpleDrawObject( OBJECT );
				break;
			case HK_TOONMODE_AE:
				njCnkToonDrawObject( OBJECT );
				njCnkToonEdgeDrawObject( OBJECT );
				break;
			case HK_SIMPLEMODE_AE:
				njCnkSimpleDrawObject( OBJECT );
				njCnkToonEdgeDrawObject( OBJECT );
				break;
			case HK_WIREMODE:
				njCnkWireDrawObject( OBJECT );
				break;
			default:
				njCnkToonDrawObject( OBJECT );
				break;
			}
			njPopMatrixEx();
	}else{//データによるモーション
		switch(shademode){
			case HK_TOONMODE_NE:
				DrawMotion( njCnkToonDrawModel );
				break;
			case HK_SIMPLEMODE_NE:
				DrawMotion( njCnkSimpleDrawModel );
				break;
			case HK_TOONMODE_AE:
				DrawMotion( njCnkToonDrawModel );
				DrawMotion( njCnkToonEdgeDrawModel );
				break;
			case HK_SIMPLEMODE_AE:
				DrawMotion( njCnkSimpleDrawModel );
				DrawMotion( njCnkToonEdgeDrawModel );
				break;
			case HK_WIREMODE:
				DrawMotion( njCnkWireDrawModel );
				break;
			default:
				DrawMotion( njCnkToonDrawModel );
				break;
		}	
	}
}


Sint32	UserMain(void)
{
	NJS_VECTOR	l;
	Uint32 back;
	static	Float	tt = 1.0f;//エッジの太さ
	
	njPushMatrixEx();
	njRotateXYZ( NULL, lx,ly,0 );
	njCalcVector( NULL, &light, &l);
	njPopMatrixEx();

	njCnkSetToonLight( l.x, l.y, l.z );
	njCnkSetSimpleLight( l.x, l.y, l.z );
	njCnkSetToonEdge( tt, 0x00000000 );
	
	
	//文字表示
#if DEBUG
	njPrintC(NJM_LOCATION(2,2),"[NINJA2 TOON SHADER DEMO]");
	if(info==0){
		njPrintC(NJM_LOCATION(2,4),"Frame  = ");
		njPrintD(NJM_LOCATION(11,4),mo,3);
		
		switch(shademode){
			case HK_TOONMODE_AE:
				njPrintC(NJM_LOCATION(2,5),"Draw   = AUTO_EDGE_TOON");
				break;
			case HK_TOONMODE_NE:
				njPrintC(NJM_LOCATION(2,5),"Draw   = NO_EDGE_TOON");
				break;
			case HK_SIMPLEMODE_AE:
				njPrintC(NJM_LOCATION(2,5),"Draw   = AUTO_EDGE_SIMPLE");
				break;
			case HK_SIMPLEMODE_NE:
				njPrintC(NJM_LOCATION(2,5),"Draw   = NO_EDGE_SIMPLE");
				break;
			case HK_WIREMODE:
				njPrintC(NJM_LOCATION(2,5),"Draw   = EDGE_WIRE");
				break;
		}
		
		switch(fuku){
				case HK_BLACK:
					njPrintC(NJM_LOCATION(2,6),"Color  = BLACK");
					break;
				case HK_RED:
					njPrintC(NJM_LOCATION(2,6),"Color  = RED");
					break;
				case HK_BLUE:
					njPrintC(NJM_LOCATION(2,6),"Color  = BLUE");
					break;
				case HK_WHITE:
					njPrintC(NJM_LOCATION(2,6),"Color  = WHITE");
					break;
		}
		
		switch(mottype){
			case MOT0:
				njPrintC(NJM_LOCATION(2,7),"Motion = Y_AXIS_ROT");
				break;
			case MOT1:
				njPrintC(NJM_LOCATION(2,7),"Motion = SWORD");
				break;
			case MOT2:
				njPrintC(NJM_LOCATION(2,7),"Motion = GUN");
				break;
			case MOT3:
				njPrintC(NJM_LOCATION(2,7),"Motion = RUN");
				break;
			case MOT4:
				njPrintC(NJM_LOCATION(2,7),"Motion = TURN");
				break;
			case MOT5:
				njPrintC(NJM_LOCATION(2,7),"Motion = BALLKICK");
				break;
		}
	}
	njPrintC(NJM_LOCATION(2,helpy+11),"HELP = A BUTTON ");
	njPrintD(NJM_LOCATION(2,helpy+13),check,2);
#endif
	check++;
	if(check==61)check=0;//止まってないよカウンター
	
	//リセットパラメータ
	if(Per->press&PDD_DGT_ST){
		if(info==1){
			info=0;
		}else{
			info=1;
		}
		zzz = -10.f;
		xxx = 0.f;
		yyy = 0.f;
		xx = 0;
		yy = 0;
		yy2 = 0;
		zz = 0;
		mo=0.f;
	}
	
	//シェーディングモード設定
	if(Per->press&PDD_DGT_TY){
		switch(shademode){
			case HK_TOONMODE_AE:
				shademode=HK_TOONMODE_NE;
				break;
			case HK_TOONMODE_NE:
				shademode=HK_SIMPLEMODE_AE;
				break;
			case HK_SIMPLEMODE_AE:
				shademode=HK_SIMPLEMODE_NE;
				break;
			case HK_SIMPLEMODE_NE:
				shademode=HK_WIREMODE;
				break;
			case HK_WIREMODE:
				shademode=HK_TOONMODE_AE;
				break;
		}
	}
	
	//モーション選択設定
	if(Per->press&PDD_DGT_TB){
		switch(mottype){
			case MOT0:
				mottype=MOT1;
				break;
			case MOT1:
				mottype=MOT2;
				break;
			case MOT2:
				mottype=MOT3;
				break;
			case MOT3:
				mottype=MOT4;
				break;
			case MOT4:
				mottype=MOT5;
				break;
			case MOT5:
				mottype=MOT0;
				break;
		}
	}
	
	//ボディカラー(テクスチャ)変更
	if(Per->press&PDD_DGT_TX){
		switch(fuku){
			case HK_BLACK://Next RED
				back = TEX->textures[2].texaddr;
				TEX->textures[2].texaddr = TEX->textures[1].texaddr;
				TEX->textures[1].texaddr = back;
				fuku = HK_RED;
				break;
			case HK_RED://Next BLUE
				back = TEX->textures[1].texaddr;
				TEX->textures[1].texaddr = TEX->textures[2].texaddr;
				TEX->textures[2].texaddr = back;
				back = TEX->textures[3].texaddr;
				TEX->textures[3].texaddr = TEX->textures[1].texaddr;
				TEX->textures[1].texaddr = back;
				fuku = HK_BLUE;
				break;
			case HK_BLUE://Next WHI
				back = TEX->textures[1].texaddr;
				TEX->textures[1].texaddr = TEX->textures[3].texaddr;
				TEX->textures[3].texaddr = back;
				back = TEX->textures[4].texaddr;
				TEX->textures[4].texaddr = TEX->textures[1].texaddr;
				TEX->textures[1].texaddr = back;
				fuku = HK_WHITE;
				break;
			case HK_WHITE://Next BLK
				back = TEX->textures[1].texaddr;
				TEX->textures[1].texaddr = TEX->textures[4].texaddr;
				TEX->textures[4].texaddr = back;
				fuku = HK_BLACK;
				break;
		}
	}
	
	//モーションフレームカウンタ
	if(stopf==0){
		yy += 60;//MOT0増分
		switch(mottype){
				case MOT1:
					mo += speed;
					if( mo >= (MOTION1->nbFrame) ) {mo=0.f;}
				break;
				case MOT2:
					mo += speed;
					if( mo >= (MOTION2->nbFrame) ) {mo=0.f;}
				break;
				case MOT3:
					mo += speed;
					if( mo >= (MOTION3->nbFrame) ) {mo=0.f;}
				break;
				case MOT4:
					mo += speed;
					if( mo >= (MOTION4->nbFrame) ) {mo=0.f;}
				break;
				case MOT5:
					mo += speed;
					if( mo >= (MOTION5->nbFrame) ) {mo=0.f;}
				break;
			}
	}else{
#if DEBUG
		if(info==0) njPrintC(NJM_LOCATION(15,4),"(STOP)");
#endif
	}
	
	//オブジェクト回転とストップ制御
	if (Per->on & PDD_DGT_TA ) {
		if (Per->on & PDD_DGT_KU) {xx += 200;}
		if (Per->on & PDD_DGT_KD) {xx -= 200;}
		if (Per->on & PDD_DGT_KR) {yy += 45;yy2 +=45;}
		if (Per->on & PDD_DGT_KL) {yy -= 45;yy2 -=45;}
		if (ptime==10000) {ptime = 5000;}//フロー防止
		if (ptime>20){
#if DEBUG
			njPrintC(NJM_LOCATION(2,helpy),  "***************HELP*****************");
			njPrintC(NJM_LOCATION(2,helpy+1),"AnalogTriggerLR = ZOOM");
			njPrintC(NJM_LOCATION(2,helpy+2),"AnalogUDLR      = PANNING");
			njPrintC(NJM_LOCATION(2,helpy+3),"DigitalUDLR     = LIGHT");
			njPrintC(NJM_LOCATION(2,helpy+4),"A               = STOP ");
			njPrintC(NJM_LOCATION(2,helpy+5),"B               = MOTION SELECT");
			njPrintC(NJM_LOCATION(2,helpy+6),"X               = COLOR SELECT");
			njPrintC(NJM_LOCATION(2,helpy+7),"Y               = DRAW TYPE");
			njPrintC(NJM_LOCATION(2,helpy+8),"A+DigitalUDLR   = ROTATE");
			njPrintC(NJM_LOCATION(2,helpy+9),"Start           = RESET & HIDEINFO");
#endif
		}
		ptime++;
	}else{
		if (Per->on & PDD_DGT_KU) 	{lx += 200;}
		if (Per->on & PDD_DGT_KD) 	{lx -= 200;}
		if (Per->on & PDD_DGT_KR) 	{ly += 200;}
		if (Per->on & PDD_DGT_KL) 	{ly -= 200;}
		if (ptime!=0&&ptime<15){
			if(stopf==1){
				stopf=0;
			}else{
				stopf=1;
			}
		}
		ptime = 0;
	}
	
	//ズーム
	if (Per->on & PDD_DGT_TR) 	{zzz += 1.f;}
	if (Per->on & PDD_DGT_TL) 	{zzz -= 1.f;}
	
	//パンニング
	if (Per->x1 > 100 )	{xxx += 1.f	;}
	if (Per->x1 < -100)	{xxx -= 1.f	;}
	if (Per->y1 > 100 )	{yyy -= 1.f	;}
	if (Per->y1 < -100)	{yyy += 1.f	;}
	

	ModelDraw();//描画

	return USER_CONTINUE;
}
/*---------------------------------------------------------------------------
		終了処理
		exit
---------------------------------------------------------------------------*/
Sint32	UserExit(void)
{
	return USER_CONTINUE;
}