/*
	Ninja Sample
	
	COPYRIGHT (C) SEGA ENTERSRISES,LTD.

	Sample

	1998.2.3
*/

#include <Ninjawin.h>
#include <stdio.h>
#include <stdlib.h>

#define	OBJECT	object_J_W1030_Null
#define	TEXLIST	texlist_J_W1030
#define	TE	object_J_W1030_R_te
#define	UDE	object_J_W1030_DR_arm
#define	ACTION	action_1105
#define	MOTION	motion_1105

#define	ACTION2	action_j_w1030
#define	MOTION2	motion_j_w1030

#define	ACTION3	action_koke
#define	MOTION3	motion_koke

#define	ACTION4	action_walk1030
#define	MOTION4	motion_walk1030

#define	ACTION5	action_yoroyoro
#define	MOTION5	motion_yoroyoro

#define STEP			0.5f

extern	NJS_OBJECT	OBJECT[];
extern	NJS_OBJECT	TE[];
extern	NJS_OBJECT	UDE[];
extern	NJS_ACTION	ACTION[];
extern	NJS_MOTION	MOTION[];
extern	NJS_ACTION	ACTION2[];
extern	NJS_MOTION	MOTION2[];
extern	NJS_ACTION	ACTION3[];
extern	NJS_MOTION	MOTION3[];
extern	NJS_ACTION	ACTION4[];
extern	NJS_MOTION	MOTION4[];
extern	NJS_ACTION	ACTION5[];
extern	NJS_MOTION	MOTION5[];
extern	NJS_TEXLIST	TEXLIST;

NJS_MOTION_LINK motionlink;
NJS_ACTION_LINK actionlink;
NJS_MOTION_LINK motionlink2;
NJS_ACTION_LINK actionlink2;
NJS_ACTION *action;
NJS_ACTION dummy;

NJS_MATRIX	matrix[128];
NJS_VERTEX_BUF	vbuf[4096];

NJS_TEXMEMLIST	tex[10];

NJS_VIEW	view;
NJS_LIGHT	light;

Sint32	xx,yy,zz = 0;

Float	ff = 0.f;
Float	ll = 0.f;
Float	aa = 0.f;
Float	frame = 0.f;
Float	step = 0.f;
Int	loop=0;
Int	Lastframe = 0;
Int frames_ini = 0;
Int frames_end = 0;

NJS_PERIPHERAL *per,*per1;

void njUserInit(void)
{
	njInitSystem( NJD_RESOLUTION_VGA, NJD_FRAMEBUFFER_MODE_RGB555, 1 );
	njInitVertexBuffer( 500000, 0, 500000, 0 );
	njInitMatrix( matrix, 128, 1 );
	njInit3D( vbuf, 4096 );
	njInitView( &view );
	njCreateLight( &light, NJD_SPEC_DIR );
	njSetLightIntensity( &light, 1.0f, 2.0f, 0.5f );
	njSetView( &view );

	njInitTexture( tex, 10 );
	njLoadTexture( &TEXLIST );
	njSetTexture( &TEXLIST );
	
	njSetBackColor( 0xff000000,0xff000000,0xff0000ff );

	njClipZ( -5.0f, -1000.f );

	actionlink.motionlink = &motionlink;
	actionlink.object = ACTION->object;
	motionlink.motion[0] = MOTION4;
	motionlink.motion[1] = MOTION;

	actionlink2.motionlink = &motionlink2;
	actionlink2.object = ACTION->object;
	motionlink2.motion[0] = MOTION;
	motionlink2.motion[1] = MOTION4;

	dummy.object = OBJECT;
	dummy.motion = NULL;
}

Sint32 njUserMain(void)
{
    static Int _rot = 0xf000;
    static Int _spec = 1;
    static Int _spline = 1;
    static Int _linear = 1;
	static Int _run	= 1;
	static Int _attack = 0;
	static Int _push = 0;
	static Int _lose = 0;
	static Int _shift = 0;
	char	*mot[] = {
		"Tumbling", "Slipping", "Leapping", "Earthquake", "Stop Motion",
	};

	per1 = njGetPeripheral(NJD_PORT_JOYSTICK1);
	per = njGetPeripheral(NJD_PORT_SYSKEYBOARD);

    if( per->on & NJD_DGT_TR ) {
       _rot += 0x100;
	   if (_rot >= 0x10000) _rot = 0;
	}
	if( per->push & NJD_DGT_TL ) {
        _spec = 1 - _spec;
	}
	if( per->push & NJD_DGT_TX ) {
		_lose ^= 1;
		if (_lose) {
			TE->evalflags |= 0x8;
			UDE->evalflags |= 0x8;
		} else {
			TE->evalflags &= (~0x8);
			UDE->evalflags &= (~0x8);
		}
	}
	if( per->push & NJD_DGT_TA ) {
       _spline ^= 1;
	}
	if( per->push & NJD_DGT_TB ) {
		ll = 0.f;
       _push = 1;
	}
	if( per->push & NJD_DGT_TC ) {
       _shift++;
	   _shift %= 5;
	}

   if(_spec == 1){
        njPrintC(NJM_LOCATION(0,1),"Specular On");
        njPrintC(NJM_LOCATION(45,1),"Hit 'Q' to turn Off Specular");
        njSetLightIntensity( &light, 1.0f, 2.0f, 0.5f );
    }
    else{
        njPrintC(NJM_LOCATION(0,1),"Specular Off");
        njPrintC(NJM_LOCATION(45,1),"Hit 'Q' to turn On Specular");
        njSetLightIntensity( &light, 0.f, 2.f, 0.5f );
    }

	if (_spline) {
		njPrintC(NJM_LOCATION(0,2),"Spline");
	    njPrintC(NJM_LOCATION(45,2),"Hit 'Z' to change to Linear");
		MOTION->inp_fn |= 0x40;
		MOTION2->inp_fn |= 0x40;
		MOTION3->inp_fn |= 0x40;
		MOTION4->inp_fn |= 0x40;
		MOTION5->inp_fn |= 0x40;
	} else {
		njPrintC(NJM_LOCATION(0,2),"Linear");
	    njPrintC(NJM_LOCATION(45,2),"Hit 'Z' to change to Spline");
		MOTION->inp_fn &= ~0x40;
		MOTION2->inp_fn &= ~0x40;
		MOTION3->inp_fn &= ~0x40;
		MOTION4->inp_fn &= ~0x40;
		MOTION5->inp_fn &= ~0x40;
	}

    njPrintC(NJM_LOCATION(0,3), mot[_shift]);
    njPrintC(NJM_LOCATION(45,0),"Hit 'E' to rotate Model");
    njPrintC(NJM_LOCATION(45,3),"Hit 'C' to change Motion");
	njPrintC(NJM_LOCATION(45,4),"Hit 'X' to execute Motion");

	njClearMatrix();
	njTranslate( NULL, 0.f, -10.f, -300.f );
	njRotateY( NULL, _rot );

	if ( !_push ) {
		if (_run) {
			njFastDrawMotion( ACTION4->object, ACTION4->motion, ff );
			ff += STEP;
			if ( ff >= ACTION4->motion->nbFrame ) ff = 0.f;
		} else {
			if (ll == 0.f) {
				motionlink2.frame[0] = aa;
				motionlink2.frame[1] = 1.f;
			}
			njFastDrawMotionLink( actionlink2.object, actionlink2.motionlink, ll/frames_end );
			ll += STEP;
			if ( ll >= frames_end ) {
				ff = 1.f;
				ll = 0.f;
				aa = 0.f;
				_run = 1;
			}
		}
	} else {
		if (_attack) {
			njFastDrawMotion( action->object, action->motion, aa );
			aa += step;
			if ( aa > Lastframe ) {
				if (loop > 0) {
					aa = 0.f;
					loop--;
				} else {
					_attack = 0;
					_push = 0;
					_run = 0;
				}
			}
		} else {
			if (ll == 0.f) {
				motionlink.frame[0] = ff;
				motionlink.frame[1] = 1.f;
				switch (_shift) {
				case	0:
					motionlink.motion[0] = MOTION4;
					motionlink.motion[1] = MOTION;
					motionlink2.motion[0] = MOTION;
					motionlink2.motion[1] = MOTION4;
					action = ACTION;
					Lastframe = ACTION->motion->nbFrame - 8;
					frames_ini = 3;
					frames_end = 3;
					loop = 0;
					step = STEP;
					break;
				case	1:
					motionlink.motion[0] = MOTION4;
					motionlink.motion[1] = MOTION3;
					motionlink2.motion[0] = MOTION3;
					motionlink2.motion[1] = MOTION4;
					Lastframe = ACTION3->motion->nbFrame - 1;
					action = ACTION3;
					frames_ini = 3;
					frames_end = 3;
					loop = 0;
					step = STEP;
					break;
				case	2:
					motionlink.motion[0] = MOTION4;
					motionlink.motion[1] = MOTION2;
					motionlink2.motion[0] = MOTION2;
					motionlink2.motion[1] = MOTION4;
					Lastframe = ACTION2->motion->nbFrame - 1;
					action = ACTION2;
					frames_ini = 6;
					frames_end = 4;
					loop = 3;
					step = STEP;
					break;
				case	3:
					motionlink.motion[0] = MOTION4;
					motionlink.motion[1] = MOTION5;
					motionlink2.motion[0] = MOTION5;
					motionlink2.motion[1] = MOTION4;
					Lastframe = ACTION5->motion->nbFrame - 5;
					action = ACTION5;
					frames_ini = 6;
					frames_end = 6;
					loop = 0;
					step = STEP / 4;
					break;
				case	4:
					motionlink.motion[0] = MOTION4;
					motionlink.motion[1] = NULL;
					motionlink2.motion[0] = NULL;
					motionlink2.motion[1] = MOTION4;
					Lastframe = 20;
					action = &dummy;
					frames_ini = 12;
					frames_end = 12;
					loop = 0;
					step = STEP;
					break;
				}
			}
			njFastDrawMotionLink( actionlink.object, actionlink.motionlink, ll/frames_ini );
			ll += STEP;
			if ( ll >= frames_ini) {
				aa = 1.f;
				ll = 0.f;
				_attack = 1;
			}
		}
	}

	if((per->on & NJD_DGT_ST)||(per1->on & NJD_DGT_ST)){
		return NJD_USER_EXIT;
	}

	return NJD_USER_CONTINUE;
}

void njUserExit(void)
{
	njExitTexture();
	njExitSystem();
}
