/*
	Ninja Sample

	COPYRIGHT (C) SEGA ENTERSRISES,LTD.

	RenderTexture Sample for SET5

	1998.9.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
extern	NJS_CNK_OBJECT	OBJECT[];
extern NJS_TEXLIST TEXLIST[];

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

/* レンダーテクスチャを貼る３Ｄポリゴン用 */
#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)
{
Uint16 *buff;
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 );
    /* 頂点計算用ワークバッファの確保 */
    vbuf = (NJS_VERTEX_BUF *)syMalloc(sizeof(NJS_VERTEX_BUF) * VERTEX_MAX);

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

	/*
		テクスチャのワークバッファを確保する。これまではF40のテクスチャで最大
		サイズの1024x128のMIPMAPなしのロードできるサイズ0x40800バイトを確保
		していたが0x800以上の0x800単位の指定でロードできるように変更しました。
		最大サイズ分あったほうがロードは速い
	*/
	texbuf = syMalloc(TEXBUFSIZE);
	njInitTextureBuffer(texbuf,TEXBUFSIZE);
	njInitTexture( tex,TEX_NUM);		/* テクスチャ領域の初期化 */
	nwInitSystem(TEX_NUM, NJD_PORT_B0);	/*  NINDOWS初期化 */
	/* レンダーテクスチャをメモリテクスチャで用意する */
	buff = (Uint16 *)syMalloc(RENDER_X * RENDER_Y * 2);
	njSetTextureInfo(&info,buff,NJD_TEXFMT_RECTANGLE |
	                            NJD_TEXFMT_RGB_565,	/* フレームバッファと合わせる */
	                            RENDER_X, RENDER_Y);
	njSetTextureName(texname,&info,7777,NJD_TEXATTR_TYPE_MEMORY|NJD_TEXATTR_GLOBALINDEX);
	njLoadTexture( TEXLIST );
	njLoadTexture( &rend_tlist );
	syFree(buff);		/* ロードし終わったらバッファを開放しても良い */
    syFree(texbuf);
    
	njInit3D( vbuf, VERTEX_MAX );

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

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

	/* テクスチャにレンダリングする時のスクリーン設定 */
	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);

	/* ポリゴンの設定 */
	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) {
		/* 通常の描画 */
		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);
		/* レンダーテクスチャへの描画 */
		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);
		/* レンダーテクスチャのテクスチャリストに切り替える */
		njSetTexture(&rend_tlist);
		/* ここまでの描画関数の描画先をテクスチャ０番に設定。*/
		/* (このサンプルでは上の njDrawObject 一つです） */
		njSetScreen(&scr);
		njRenderTextureNum(0);
		/* レンダリングしたテクスチャを３Ｄポリゴンに貼って表示する */
		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();
}

