/*
    Ninja Sample

    COPYRIGHT (C) SEGA ENTERSRISES,LTD.

    TexLow Sample for SET5

    1999.3.2
*/
#include <Shinobi.h>
#include <Nindows.h>

#define OBJECT  object_f40_gte_sh_null1_1_null1_1
#define TEXLIST texlist_f40_gte_sh_null1_1

#define START 	0
#define LOAD 	1
#define LOAD_S 	2
#define DRAW 	3
#define RELEASE 4
#define HOLD 	5

extern  NJS_CNK_OBJECT  OBJECT[];
extern NJS_TEXLIST TEXLIST[];

/* テクスチャの設定 */
/* setting of texture */
NJS_TEXMEMLIST  tex[100];

NJS_MATRIX   *matrix;
NJS_VERTEX_BUF   *vbuf;

NJS_VIEW    view;
NJS_LIGHT   light;

Sint32  xx = 0,yy = 0,zz = 0;
Int co = 0;
Uint32 tex_buffer_size;
Uint32 count1,count2,count;
Uint32 micro1,micro2,micro = 0;
const PDS_PERIPHERAL* per;
Int eorcount = 0;
Int re_eorcount;

/* LoadTex.c */
Sint32 LoadTexture(NJS_TEXLIST *texlist,Uint32 n);
Sint32 LoadTextureServer(void);
Sint32 LoadMode(void);
void ReleaseTexture(NJS_TEXLIST *texlist,Uint32 n);


void EORCount(void);

void njUserInit(void)
{
    /*
        njInitSystemの変わりにsbInitSystemを実行する。
        詳しくは、sbinit.cをご覧ください

    */
    /*
       Executing "sbInitSystem" in a change of "njInitSystem".
       (reference with sbinit.c in detail)
    */
    njSetBorderColor( 0 ) ;
    sbInitSystem( NJD_RESOLUTION_640x480_NTSCNI, NJD_FRAMEBUFFER_MODE_RGB565, 1 );

    vbuf = syMalloc(sizeof(NJS_VERTEX_BUF)*4096);
    matrix = syMalloc(sizeof(NJS_MATRIX)*32);
    /*
        テクスチャのワークバッファを確保する。0x800以上の0x800単位の指定する。
        最大サイズ分あったほうがロードは速い
    */
    /*
        Securing work buffer of texture. 
        It is setting of 0x800 unit more than 0x800.
        It does not take the time that the greatest size was used for loads.
    */
    tex_buffer_size = 0x800*100;
    njInitTextureBuffer((Sint8*)vbuf,tex_buffer_size);

    njInitVertexBuffer( 900000, 0, 200000, 0 ,0);
    njInitPrint(NULL,0,0);

    njInitMatrix( matrix, 32 , 0);
    njInit3D( vbuf, 4096 );
    njInitView( &view );

	njCnkSetSimpleLight( 0.f, 0.f, 1.0f );
	njCnkSetSimpleLightIntensity( 1.0f, 0.5f );

    njSetView( &view );

    njInitTexture( tex,100);

    /*
        NINDOWS初期化 SET4から引数にポートを設定する

    */
    /*
        NINDOWS initialization
        Establishing a port in an argument (than SET 4)
    */

	   nwInitSystem(100,NJD_PORT_A0);
    /*
        テクスチャはDG WorkShopのカレントディレクトリに
        置いてください


    */
    /*
        Put texture with baing current directory of DG WorkShop
    */
    njSetTexture( TEXLIST );

    njControl3D( NJD_CONTROL_3D_CONSTANT_ATTR|NJD_CONTROL_3D_NO_CLIP_CHECK );
    njSetConstantAttr( 0xffffffff, NJD_FILTER_BILINEAR);

    njClipZ( -2.0f, -100.f );
    njSetAspect( 1.0f, 1.0f );

    njSetBackColor(0x00000000,0x00000000,0x000000FF);
    njPrintSize(16);
	njPrintColor(0x80C0C0C0);

	njSetEORCallBackFunction(EORCount);

}


Sint32 njUserMain(void)
{
	static Int i = 0;
	static Int mode = START;

    njPrintC(NJM_LOCATION(2,3),"TEST SET5 .. TexLow");
	njPrint(NJM_LOCATION(2,4),"LOAD TIME %d micro sec", micro);

    per = pdGetPeripheral(PDD_PORT_A0);

	switch(mode){
	case START:
	    njInitTextureBuffer((Sint8*)vbuf,tex_buffer_size);
		i = 0;
		mode = LOAD;
		count1 = syTmrGetCount();
		co = 0;
	case LOAD:
		LoadTexture(TEXLIST,i);
		mode = LOAD_S;
	case LOAD_S:
		njPrint(NJM_LOCATION(2,5),"LOAD %d TEXTURE", i);
		if(LoadTextureServer() > 0){
			if(LoadMode() == 0){
				if(i >= (TEXLIST->nbTexture - 1)){
					mode = DRAW;
					count2 = syTmrGetCount();
					count = syTmrDiffCount(count1,count2);
					micro = syTmrCountToMicro(count);
				}
				else{
					mode = LOAD;
					i++;
				}
			}
		}
		else{
			/* エラーの場合は同じテクスチャをロードしなおす　*/
			/* Texture load loads a texture in case of error again */
			mode = LOAD;
		}
		co++;
		break;
	case DRAW:
		/* テクスチャロードに何回ループしたか */
		/* Do do a loop of several times texture load? */
		njPrint(NJM_LOCATION(2,5),"LOAD LOOP %d COUNT", co);
	    njClearMatrix();
	    njTranslate( NULL, 1.f, 0.f, -7.f );
	    njRotateXYZ( NULL, xx,yy,zz );
	    njCnkSimpleDrawObject(OBJECT);
	    yy += 173;
		xx = -6000;
		/* テクスチャバッファの変更*/
		/* A change of texture buffer size. */
		if (per->press & NJD_DGT_TA) {
			tex_buffer_size -= 0x800;
			if(tex_buffer_size < 0x800)
				tex_buffer_size = 0x800;
		}

		if (per->press & NJD_DGT_TX) {
			tex_buffer_size += 0x800;
			if(tex_buffer_size > 0x800*100)
				tex_buffer_size = 0x800*100;
		}
		
		njPrint(NJM_LOCATION(2,6),"TEXTURE BUFFER SIZE ");
		njPrintColor(0x80C0C000);
		njPrint(NJM_LOCATION(22,6),"0x%X",tex_buffer_size);
		njPrintColor(0x80C0C0C0);

		/* スタートボタンでテクスチャリリース　*/
		/* Release a texture with start button. */
		njPrint(NJM_LOCATION(2,7),"PUSH START -> RELEASE");
		if (per->press & NJD_DGT_ST) {
			mode = RELEASE;
			re_eorcount = eorcount;
		}
		break;
	case RELEASE:
		/* EORが3回以上入ったらリリース開始　*/
		/* If three times or more EOR entered it, release it, and start it */
		if((eorcount - re_eorcount) > 3){
			for(i = 0;i < TEXLIST->nbTexture;i++){
				ReleaseTexture(TEXLIST,i);
			}
			mode = HOLD;
		}
		break;
	case HOLD:
		/* スタートボタンでもう一度テクスチャをロードする */
		/* Load a texture with start button once again. */
		njPrint(NJM_LOCATION(2,6),"PUSH START -> LOAD");
		if (per->press & NJD_DGT_ST) {
			mode = START;
		}
		break;
	}
	
    return nwExecute();
}

void njUserExit(void)
{
	syFree(matrix);
	syFree(vbuf);
    nwExitSystem();
    njExitPrint();
    njExitTexture();
    sbExitSystem();
}

void EORCount(void)
{
	eorcount++;

}