/*
	Ninja Sample

	COPYRIGHT (C) SEGA ENTERSRISES,LTD.

	RenderTexture Sample for SET5

	1998.9.2

このサンプルはＦ４０のモデルをテクスチャにレンダリングするサンプルです。
一定時間ごとに通常の描画とテクスチャへの描画を切り替えています。

This is the sample which does rendering of a model of F40 to a texture.
Change usual drawing pictures and drawing pictures to a texture every fixed time.

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

#define	OBJECT	object_f40_gte_sh_null1_1_null1_1
#define TEXLIST texlist_f40_gte_sh_null1_1
extern	NJS_CNK_OBJECT	OBJECT[];
extern NJS_TEXLIST TEXLIST[];

/* テクスチャの設定 */
/* Setting of a texture */
#define TEX_NUM		40
#define TEXBUFSIZE	(0x800*100)
/* テクスチャ領域を確保 */
/* Secure texture domain */
NJS_TEXMEMLIST	tex[TEX_NUM];
/* レンダーテクスチャ用 */
/* For texture rendering */
#define RENDER_X	256
#define RENDER_Y	256
NJS_TEXINFO info;
NJS_TEXNAME texname[1];
NJS_TEXLIST rend_tlist = {texname, 1};

/* レンダーテクスチャを貼る３Ｄポリゴン用 */
/* Setting for 3D polygon that rendering texture is put on. */
#define	PXW	60
#define	PYW	60
#define	PX1	(-PXW/2)
#define	PY1	(PYW/2)
#define	PX2	(PX1 + PXW)
#define	PY2	(PY1 - PYW)
#define PZ  -150.f;

NJS_POINT3COL	p3c;
NJS_POINT3	p[4];
NJS_COLOR	col[4];
NJS_COLOR	texuv[4];

#define VERTEX_MAX	4096
#define MATRIX_DEPTH	32
NJS_VERTEX_BUF	*vbuf;
NJS_MATRIX	*matrix;
NJS_VIEW	view;
NJS_LIGHT	light;
NJS_SCREEN scr, scr_tex;

void njUserInit(void)
{
Sint8 *texbuf;

	sbInitSystem( NJD_RESOLUTION_640x480_NTSCNI, NJD_FRAMEBUFFER_MODE_RGB565, 1 );
	njInitVertexBuffer( 900000, 0, 200000, 0 ,0);
	njInitPrint( NULL, 0, NJD_TEXFMT_ARGB_1555 );
    /* 頂点計算用ワークバッファの確保 */
    /* Security of work buffer for vertex calculation */
    vbuf = (NJS_VERTEX_BUF *)syMalloc(sizeof(NJS_VERTEX_BUF) * VERTEX_MAX);

	/* マトリクススタックの初期化 */
	/* Initialization of matrix stack */
	matrix = (NJS_MATRIX *)syMalloc(sizeof(NJS_MATRIX) * MATRIX_DEPTH);
	njInitMatrix( matrix, MATRIX_DEPTH, 0);

    /*
        テクスチャのワークバッファを確保する。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.
    */
	texbuf = syMalloc(TEXBUFSIZE);
	njInitTextureBuffer(texbuf,TEXBUFSIZE);
	njInitTexture( tex,TEX_NUM);
	nwInitSystem(TEX_NUM, NJD_PORT_B0);
	/*
		レンダーテクスチャを設定するときは、リードできるアドレスが入っていれば
		どのアドレスを指定してもかまいません。
		この例ではtexbufを指定しておきます。
	*/
	/*
		Address the option that can read when establish rendering texture.
		Will establish texbuf in this example.
	*/
	njSetTextureInfo(&info,texbuf,NJD_TEXFMT_RECTANGLE |
	                            NJD_TEXFMT_RGB_565,	/* フレームバッファと合わせる *//* Adapt itself to a frame buffer. */
	                            RENDER_X, RENDER_Y);
	njSetTextureName(texname,&info,7777,NJD_TEXATTR_TYPE_MEMORY|NJD_TEXATTR_GLOBALINDEX);
	njLoadTexture( TEXLIST );
	njLoadTexture( &rend_tlist );
    syFree(texbuf);
    
	njInit3D( vbuf, VERTEX_MAX );

	njInitView( &view );
	njSetView( &view );

	/* スクリーンの設定 */
	/* Setting of screen. */
	scr.dist = 500.f;
	scr.w = 640;
	scr.h = 480;
	scr.cx = 320;
	scr.cy = 240;

	/* テクスチャにレンダリングする時のスクリーン設定 */
	/* Screen setting at doing rendering to a texture. */
	scr_tex.dist = 500.f;
	scr_tex.w = 256;
	scr_tex.h = 256;
	scr_tex.cx = 128;
	scr_tex.cy = 128;

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

	njControl3D( NJD_CONTROL_3D_NO_CLIP_CHECK );

	njSetAspect( 1.0f, 1.0f );

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

	/* ポリゴンの設定 */
	/* Setting of polygon. */
	p[0].x = PX1;
	p[0].y = PY1;
	p[0].z = PZ;
	texuv[0].tex.u = 0;
	texuv[0].tex.v = 0;
	col[0].color = 0xFFFFFFFF;

	p[1].x = PX1;
	p[1].y = PY2;
	p[1].z = PZ;
	texuv[1].tex.u = 0;
	texuv[1].tex.v = 255;
	col[1].color = 0xFFFFFFFF;

	p[2].x = PX2;
	p[2].y = PY2;
	p[2].z = PZ;
	texuv[2].tex.u = 255;
	texuv[2].tex.v = 255;
	col[2].color = 0xFFFFFFFF;

	p[3].x = PX2;
	p[3].y = PY1;
	p[3].z = PZ;
	texuv[3].tex.u = 255;
	texuv[3].tex.v = 0;
	col[3].color = 0xFFFFFFFF;

	p3c.p = p;
	p3c.col = col;
	p3c.tex = texuv;
	p3c.num = 4;
}

Float	x,y,z=0.f;
Sint32	rx,ry,rz;
NJS_PERIPHERAL *per;
Sint32 count = 0;

Sint32 njUserMain(void)
{
#if 0
	per = njGetPeripheral(NJD_PORT_A0);

	if(per->on & NJD_DGT_TA) {
		if(per->on & NJD_DGT_KU) z += 1.f;
		if(per->on & NJD_DGT_KD) z -= 1.f;
	}
	else if(per->on & NJD_DGT_TB) {
		if(per->on & NJD_DGT_KU) y += 0.1f;
		if(per->on & NJD_DGT_KD) y -= 0.1f;
		if(per->on & NJD_DGT_KL) x -= 0.1f;
		if(per->on & NJD_DGT_KR) x += 0.1f;
	}
#endif
	njClearMatrix();
	if ((count & 0x80) == 0) {
		/* 通常の描画 */
		/* Usual drawing pictures.*/
		njSetTexture(TEXLIST);
		njSetScreen(&scr);
		njCnkSetSimpleLight( 0.f, 0.f, 1.0f );
		njTranslate( NULL, x, y, z-9 );
		njRotateXYZ( NULL, rx + 0xfffff778,ry+0x9108,rz );
		njCnkSimpleDrawObject(OBJECT);
		njPrintC(NJM_LOCATION(12,22), "NORMAL RENDERING");
	} else {
		njPushMatrix(NULL);
		/* レンダーテクスチャへの描画 */
		/* Drawing pictures to rendering texture. */
		njSetTexture(TEXLIST);
		njSetScreen(&scr_tex);
		njCnkSetSimpleLight( 0.f, 0.f, 1.0f );
		njTranslate( NULL, x, y, z-9 );
		njRotateXYZ( NULL, rx + 0xfffff778,ry+0x9108,rz );
		njCnkSimpleDrawObject(OBJECT);
		njPopMatrix(1);

		njPushMatrix(NULL);
		/* レンダーテクスチャのテクスチャリストに切り替える */
		/* Change it in texture list of rendering texture. */
		njSetTexture(&rend_tlist);
		/* ここまでの描画関数の描画先をテクスチャ０番に設定。*/
		/* Drawing pictures in the texture zero. */
		njSetScreen(&scr);
		njRenderTextureNum(0);
		/* レンダリングしたテクスチャを３Ｄポリゴンに貼って表示する */
		/* Complete the texture which did rendering in 3D polygon, and show it.*/
		njSetTextureNum(0);
		njDrawPolygon3D(&p3c,4,
	                                 NJD_DRAW_NORMAL
	                               | NJD_USE_TEXTURE
	                               | NJD_FILL
	                               );
		njPrintC(NJM_LOCATION(12,22), "RENDER TEXTURE");
		njPopMatrix(1);
	}
	rx = -6000;
	ry += 173;
	count++;

    njPrintC(NJM_LOCATION(4,4),"RENDER TEXTURE SAMPLE");
#if 0
    njPrintF(NJM_LOCATION(2,4),x,3);
    njPrintF(NJM_LOCATION(2,5),y,3);
    njPrintF(NJM_LOCATION(2,6),z,3);
#endif
	return nwExecute();
}

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

