
/*
	Ninja Sample

	COPYRIGHT (C) SEGA ENTERSRISES,LTD.

	Sample By Akira Matsuo

	1997.11.7

	Modified by Sean Hunt

	7.21.98
*/

#include <shinobi.h>
#include <sg_sycbl.h>

#define NINJA_TEST 1
#define TEX_TEST 1

#define STK_MAX 10  /* Max size of Matrix Stack */

#define N_CLIP     -5.f
#define F_CLIP     -60000.f

/*---------------------------*/
/*removed for Set4	*/
/*void Blur(Int cnt, NJS_MATRIX *mat, void (*func)(void *), void *param); /* See Blur.c */
NJS_MATRIX bm[10];
/*----------------------------*/

void Cylinder(Uint32 attr); /* See Cylinder.c */
void Sphere(Uint32 attr);   /* See Spherer.c */
void Triangle3D();          /* See Polygon.c */
void NormalPolygon3D();     /* See Polygon.c */
void NormalLine3D();        /* See Polygon.c */
void NormalPoint3D();       /* See Polygon.c */

NJS_MATRIX stack[STK_MAX+32];

NJS_TEXMEMLIST texmemlist[2];
NJS_TEXNAME texname[2];
NJS_TEXLIST texlist = {texname, 2};
NJS_FOG_TABLE ftable;

NJS_VIEW _view_[2];
NJS_POINT2 region1[2];
NJS_POINT2 region2[2];

NJS_PERIPHERAL *per;

/* for Sphere Size ---------*/
extern Int NPOLY;
extern Int STAGE;
extern Float RADIUS;
extern Float HEIGHT;
Int earth_npoly = 24;
Int earth_stage = 24;
Float earth_radius = 200.f;
Float earth_height =200.f;
Int ufo_npoly = 24;
Int ufo_stage = 6;
Float ufo_radius = 20.f;
Float ufo_height = 6.f;
/*--------------------------*/

/*	from F40	*/
extern NJS_VERTEX_BUF	vbuf[4096];

void njUserInit(void)
{
	SYE_CBL_CABLE Cable;
    long stack32align;

    /* Init */
	njSetBorderColor(0x00000000);

	/* Check the cable for NTSC or VGA */
	Cable = syCblCheckCable();

	switch( Cable )
	{
	case SYE_CBL_CABLE_VGA:
		sbInitSystem(NJD_RESOLUTION_VGA, NJD_FRAMEBUFFER_MODE_RGB565, 1);
		break;

	case SYE_CBL_CABLE_NTSC:
		sbInitSystem(NJD_RESOLUTION_640x480_NTSCNI, NJD_FRAMEBUFFER_MODE_RGB565, 1);
		break;
	}
	njInitVertexBuffer( 700000, 0, 300000, 0, 0 );
	njInitPrint( NULL, 0, NJD_TEXFMT_ARGB_1555 );
	/*	from F40	*/

	njInitTextureBuffer((Sint8 *)vbuf,0x40800);


    /* Near & Far Clipping */
    njClipZ(N_CLIP, F_CLIP);

    /* Init Matrix stack */
    stack32align = ((((long) stack) + 0x1F) & 0xFFFFFFE0);
    njInitMatrix((NJS_MATRIX *) stack32align, STK_MAX, 0);

    /* Init View */
    njInitView(&(_view_[1]));
    njInitView(&(_view_[0]));
    njTranslateViewRelative(&(_view_[0]), 0.f, 0.f, 1000.f);
    njSetView(&(_view_[0]));
    /* njClearMatrix(); */

    /* Load Charactor Texture Map */
    njInitTexture(texmemlist, 2);
    njSetTextureName(&texname[0] ,"frog.pvr", 0, NJD_TEXATTR_GLOBALINDEX);
    njSetTextureName(&texname[1] ,"earth2.pvr", 1, NJD_TEXATTR_GLOBALINDEX);
    njLoadTexture(&texlist);
    njSetTexture(&texlist);

}


Sint32 njUserMain(void)
{
    static Int rot = 0;
    static Float fade_rate = 0.f;
    static Float fade_dir;
    static Int move = 0;
    static Int direction = -100;
    static Int item = 0;
    static Int cam = 0;
/*	no push member as a struct, only as a union; use press instead	*/

  	per = (PDS_PERIPHERAL *) njGetPeripheral(NJD_PORT_A0);
    if( per->press & NJD_DGT_TR ) {
        if(item < 7)
            item++;
        else
            item = 0;
    }
    /*	if( per->press & NJD_DGT_TL )
        return(1);	*/
    if( per->press & NJD_DGT_TL )
        cam = 1 - cam;

    njPrintC(NJM_LOCATION(5,5),"Hit Right Trigger to See The Next Sample.");
    /*	njPrintC(NJM_LOCATION(5, 55),"Hit 'Q' to Quit.");
	never really quits	*/
	/*	test code	*/
	/*	item = 1;	*/

    switch(item){
    case 0:
        {
        NJS_POINT3 p1,p2;
        NJS_MATRIX mat;
        p1.x = 0.f;
        p1.y = 0.f;
        p1.z = 0.f;

        njUnitMatrix(&mat);
        njRotateY(&mat, NJM_DEG_ANG((int)(-rot)));
        njRotateX(&mat, NJM_DEG_ANG((int)rot));
        njRotateZ(&mat, NJM_DEG_ANG((int)rot));
        njTranslate(&mat, 450.f, 0.f, 0.f);
        njCalcPoint(&mat, &p1, &p2);
        njTranslateViewAbsolute(&(_view_[1]), p2.x, p2.y+0.1f, p2.z);
        njLookAtView(&(_view_[1]), 0.f, 0.f, 0.f);
        njSetView(&(_view_[cam]));
        /* njClearMatrix();  */

        njPrintC(NJM_LOCATION(5,7),"Point3D & Polygon3D : Filled w/ Texture.");
        if(cam)
            njPrintC(NJM_LOCATION(5,54),"View from the Flying Saucer.");
        else
            njPrintC(NJM_LOCATION(5,54),"View from the Space.");
        njPrintC(NJM_LOCATION(5,56),"Hit Left Trigger to Switch Camera.");
        njPushMatrix(NULL);
        njSetBackColor(0xff000000, 0xff000000, 0xff000000);
        NormalPoint3D();
        njRotateY(NULL, NJM_DEG_ANG((int)(-rot)));
        njRotateX(NULL, NJM_DEG_ANG((int)rot));
        njSetTextureNum(1);
        NPOLY  = earth_npoly;
        STAGE  = earth_stage;
        RADIUS  = earth_radius;
        HEIGHT  = earth_height;
        Sphere(NJD_DRAW_NORMAL|NJD_FILL|NJD_USE_TEXTURE);
        njPushMatrix(NULL);
        njRotateZ(NULL, NJM_DEG_ANG((int)rot));
        njTranslate(NULL, 450.f, 0.f, 0.f);
        NPOLY  = ufo_npoly;
        STAGE  = ufo_stage;
        RADIUS  = ufo_radius;
        HEIGHT  = ufo_height;
        if(cam)
            Sphere(NJD_DRAW_NORMAL|NJD_FILL|NJD_TRANSPARENT);
        else
            Sphere(NJD_DRAW_NORMAL|NJD_FILL);

        njPopMatrix(2);
        rot += 1;
        break;
        }
    case 1:
        {
        njPrintC(NJM_LOCATION(5,7),"Point3D & Polygon3D : Filled w/o Texture.");
        njSetView(&(_view_[0]));
        /* njClearMatrix(); */
        njPushMatrix(NULL);
        njSetBackColor(0xff000000, 0xff000000, 0xff000000);
        NormalPoint3D();
        njRotateY(NULL, NJM_DEG_ANG((int)(-rot)));
        njRotateX(NULL, NJM_DEG_ANG((int)rot));
        njSetTextureNum(1);
        NPOLY  = earth_npoly;
        STAGE  = earth_stage;
        RADIUS  = earth_radius;
        HEIGHT  = earth_height;
        Sphere(NJD_DRAW_NORMAL|NJD_FILL);
        njPushMatrix(NULL);
        njRotateZ(NULL, NJM_DEG_ANG((int)rot));
        njTranslate(NULL, 450.f, 0.f, 0.f);
        NPOLY  = ufo_npoly;
        STAGE  = ufo_stage;
        RADIUS  = ufo_radius;
        HEIGHT  = ufo_height;
        Sphere(NJD_DRAW_NORMAL|NJD_FILL);
        njPopMatrix(2);
        rot += 1;
        break;
        }
    case 2:
        njPrintC(NJM_LOCATION(5,7),"Point3D & Polygon3D : Wired w/ Texture.");
        njSetView(&(_view_[0]));
        /* njClearMatrix(); */
        njPushMatrix(NULL);
        njSetBackColor(0xff000000, 0xff000000, 0xff000000);
        NormalPoint3D();
        njRotateY(NULL, NJM_DEG_ANG((int)(-rot)));
        njRotateX(NULL, NJM_DEG_ANG((int)rot));
        njSetTextureNum(1);
        NPOLY  = earth_npoly;
        STAGE  = earth_stage;
        RADIUS  = earth_radius;
        HEIGHT  = earth_height;
        Sphere(NJD_DRAW_NORMAL|NJD_USE_TEXTURE);
        njPushMatrix(NULL);
        njRotateZ(NULL, NJM_DEG_ANG((int)rot));
        njTranslate(NULL, 450.f, 0.f, 0.f);
        NPOLY  = ufo_npoly;
        STAGE  = ufo_stage;
        RADIUS  = ufo_radius;
        HEIGHT  = ufo_height;
        Sphere(NJD_DRAW_NORMAL|NJD_FILL);
        njPopMatrix(2);
        rot += 1;
        break;
    case 3:
        njPrintC(NJM_LOCATION(5,7),"Point3D & Polygon3D : Wired w/o Texture.");
        njSetView(&(_view_[0]));
        /* njClearMatrix(); */
        njPushMatrix(NULL);
        njSetBackColor(0xff000000, 0xff000000, 0xff000000);
        NormalPoint3D();
        njRotateY(NULL, NJM_DEG_ANG((int)(-rot)));
        njRotateX(NULL, NJM_DEG_ANG((int)rot));
        njSetTextureNum(1);
        NPOLY  = earth_npoly;
        STAGE  = earth_stage;
        RADIUS  = earth_radius;
        HEIGHT  = earth_height;
        Sphere(NJD_DRAW_NORMAL);
        njPushMatrix(NULL);
        njRotateZ(NULL, NJM_DEG_ANG((int)rot));
        njTranslate(NULL, 450.f, 0.f, 0.f);
        NPOLY  = ufo_npoly;
        STAGE  = ufo_stage;
        RADIUS  = ufo_radius;
        HEIGHT  = ufo_height;
        Sphere(NJD_DRAW_NORMAL|NJD_FILL);
        njPopMatrix(2);
        rot += 1;
        break;
    case 4:
        njPrintC(NJM_LOCATION(5,7),"Fade");
        njSetView(&(_view_[0]));
        /* njClearMatrix(); */
        njPushMatrix(NULL);
        njSetBackColor(0xff000000, 0xff000000, 0xff000000);
        njSetFadeColor(0xffff0000);
        NormalPoint3D();
        njRotateY(NULL, NJM_DEG_ANG((int)(-rot)));
        njRotateX(NULL, NJM_DEG_ANG((int)rot));
        njExecuteFade(fade_rate);
        njFadeEnable();
        njSetTextureNum(1);
        NPOLY  = earth_npoly;
        STAGE  = earth_stage;
        RADIUS  = earth_radius;
        HEIGHT  = earth_height;
        Sphere(NJD_DRAW_NORMAL|NJD_FILL|NJD_USE_TEXTURE);
        njFadeDisable();

        njPushMatrix(NULL);
        njRotateZ(NULL, NJM_DEG_ANG((int)rot));
        if(fade_dir > 0)
            NormalLine3D();
        njTranslate(NULL, 450.f, 0.f, 0.f);
        NPOLY  = ufo_npoly;
        STAGE  = ufo_stage;
        RADIUS  = ufo_radius;
        HEIGHT  = ufo_height;
        Sphere(NJD_DRAW_NORMAL|NJD_FILL);
        njPopMatrix(2);
        if(fade_rate < .05f)
            fade_dir = .01f;
        if(fade_rate > .5f)
            fade_dir = -.01f;
        fade_rate += fade_dir;
        rot += 1;
        break;
    case 5:
        njPrintC(NJM_LOCATION(5,7),"Fog : Effected from Z = -10000 to Z = -50000");
        njPrintC(NJM_LOCATION(5,9),"Cylinder Position Z = ");
	    njPrintF(NJM_LOCATION(27,9), move-_view_[0].pz, 8);
        njSetView(&(_view_[0]));
        /* njClearMatrix(); */
        njSetBackColor(0xff000000, 0xff000000, 0xff000000);
        njSetFogColor(0xff000000);
        njGenerateFogTable3(ftable, -10000.f, -50000.f);
        njSetFogTable(ftable);
        njPushMatrix(NULL);
        NormalPoint3D();
        njPushMatrix(NULL);
        njTranslate(NULL, 0.f, 0.f, (Float)move);
        njRotateZ(NULL, NJM_DEG_ANG(180));
        njRotateY(NULL, NJM_DEG_ANG((int)(rot)));
        njRotateX(NULL, NJM_DEG_ANG((int)rot));
        njTranslate(NULL, 0.f, -400.f, 0.f);
        njFogEnable();
        njSetTextureNum(0);
	    Cylinder(NJD_DRAW_NORMAL|NJD_FILL|NJD_USE_TEXTURE);
        njPopMatrix(2);
        njFogDisable();
        move += direction;
        if(move < -50000)
            direction = 100;
        if(move > -500)
            direction = -100;
        rot += 1;
        break;
    case 6:
        {
        static float ang = 0.f;
        njPrintC(NJM_LOCATION(5,7),"Triangle3D : Filled w/ Texture");
        njSetView(&(_view_[0]));
        /* njClearMatrix(); */
        njSetBackColor(0xff8080ff, 0xff8080ff, 0xffffffff);
        njPushMatrix(NULL);
        njRotateX(NULL, NJM_DEG_ANG(ang));
        njSetTextureNum(0);
        Triangle3D();
        njPopMatrix(1);
        ang += 0.1f;
        break;
        }
    case 7:
        {
        static float ang = 0;
        njPrintC(NJM_LOCATION(5,7),"Polygon3D : Filled w/ Texture");
        njSetView(&(_view_[0]));
        /* njClearMatrix(); */
        njSetBackColor(0xff8080ff, 0xff8080ff, 0xffffffff);
        njPushMatrix(NULL);
        njRotateX(NULL, NJM_DEG_ANG(ang));
        njSetTextureNum(0);
        NormalPolygon3D();
        njPopMatrix(1);
        ang += 0.1f;
        break;

		/*	Blur removed for Set4	*/
        }

    }
    return 0;
}


void njUserExit(void)
{
    njExitPrint();
    njExitTexture();
    sbExitSystem();
}


void MallocP3C(NJS_POINT3COL *p3c, Uint32 n)
{
    p3c->p = (NJS_POINT3 *)calloc(n, sizeof(NJS_POINT3));
    p3c->col = (NJS_COLOR *)calloc(n, sizeof(NJS_COLOR));
    p3c->tex = (NJS_COLOR *)calloc(n, sizeof(NJS_COLOR));
    p3c->num = n;
}

void FreeP3C(NJS_POINT3COL *p3c)
{
    free(p3c->p);
    free(p3c->col);
    free(p3c->tex);
}