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

  タイトル ： スペキュラ効果
              speclar
  編集履歴 ： 98-05-01 製作開始
              98-06-19 SET5対応
              99-04-05 appends the English comments
************************************************************/

#include <shinobi.h>
#include <njdef.h>

void main(void)
{
	njSetBorderColor( 0x00000000 );
    njUserInit();
    while (njUserMain() == NJD_USER_CONTINUE) {
        njWaitVSync();
    }
    njUserExit();
}

#define MAX_MATRIX_DEPTH 10
#define MAX_VERTEXES 1000

#define SPECULAR_CYCLE 500
#define SPECULAR_CHANGE_SPEED NJM_DEG_ANG(1.0F)

#define SCREEN_SAVE_TIME 30

extern NJS_OBJECT object__sphere3_sphere3[];

static NJS_MATRIX *Matrix;
static NJS_VERTEX_BUF *VertexBuffer;

static NJS_VIEW View;
static NJS_LIGHT SpecularLight;
static NJS_LIGHT AmbientLight;

/*----------------------------------------------------------------------
           初期化
           initialize
----------------------------------------------------------------------*/
void njUserInit(void)
{
    /* システムの初期化 */
    /* Initializes the Dreamcast H/W and readies the SEGA library */
    sbInitSystem(NJD_RESOLUTION_640x240_NTSCNI, NJD_FRAMEBUFFER_MODE_RGB565, 1);

    /* 画面のアスペクト比を設定 */
	/* corrects the screen aspect ratio */
    njSetAspect( 1.0F, 0.45F );

    /* メモリ割り当て */
    /* allocates the memory */
    Matrix = syMalloc(sizeof(NJS_MATRIX) * MAX_MATRIX_DEPTH);
    VertexBuffer   = syMalloc(sizeof(NJS_VERTEX_BUF) * MAX_VERTEXES);

    /* 背景色の設定 */
	/* sets background color */
    njSetBackColor(ARGB(0, 192, 0, 0), ARGB(0, 0, 192, 0), ARGB(0, 0, 0, 192));

    /* 頂点格納バッファの確保 */
    /* allocates the buffers for registration of vertex data */
    njInitVertexBuffer(MAX_VERTEXES * 64 / 4, 0, MAX_VERTEXES * 64 / 4, 0, 0);
	njInitPrint( NULL, 0, NJD_TEXFMT_ARGB_1555 );

    /* マトリクススタックの初期化 */
  	/* initializes the matrix stack */
    njInitMatrix(Matrix, MAX_MATRIX_DEPTH, 1);

    /* 3Dシステムの初期化 */
    /* initializes 3D system  */ 
    njInit3D(VertexBuffer, MAX_VERTEXES);
    njControl3D( NJD_CONTROL_3D_CONSTANT_ATTR );

    /* スペキュラ光源の設定 */
    /* sets the specular light source */
    njCreateLight(&SpecularLight, NJD_SPEC_POINT);
    njSetLightIntensity(&SpecularLight, 0.0F, 0.0F, 0.0F);
    njSetLightColor(&SpecularLight, 1.0F, 1.0F, 1.0F);
    njTranslateLight(&SpecularLight, 10.0F, 10.0F, -77.0F);
    njSetLightAngle(&SpecularLight, NJM_DEG_ANG(30.0F), NJM_DEG_ANG(60.0F));

    /* 環境光の設定 */
    /* sets the ambient light source */
    njCreateLight(&AmbientLight, NJD_LAMBERT_DIR);
    njSetLightIntensity(&AmbientLight, 0.0F, 0.4F, 0.4F);
    njSetLightColor(&AmbientLight, 1.0F, 1.0F, 1.0F);

    /* ビューの初期化 */
    /* initializes the user-defined view */
    njInitView(&View);

    /* ビューの設定 */
	/* specifies the current view */
    njSetView(&View);

	/* 文字色の設定 */
    /* sets the text color */
	njPrintColor(0xFFC0C0C0);
}

/*----------------------------------------------------------------------
         メイン
         main
----------------------------------------------------------------------*/
Sint32 njUserMain(void)
{
    static Angle rotateAng = NJM_DEG_ANG(0.0F);/* 回転角度用変数 */
                                               /* rotation angle */
    static int counter = 0;                    /* スペキュラ表示時間設定用カウンタ */
                                               /* counter for specular mode */
	static Bool pause = FALSE; 	               /* ポーズがかかっているか */
	                                           /* pause flag */
	static int pause_counter = 0;
	static PDS_PERIPHERAL *key;

	/* ポーズの判定 */
	/* checks pause */
	key = pdGetPeripheral(PDD_PORT_A0);

	if (key->press & PDD_DGT_ST) {
	    if (pause == FALSE) {
		    njSetBackColor(0x00000000, 0x00000000, 0x00000000);
		    pause = TRUE;
		} else {
		    njSetBackColor(0x00C00000, 0x0000C000, 0x000000C0);
		    pause = FALSE;
		}
	}

	if (pause == FALSE) {
	    counter++;
	}
    if (counter == SPECULAR_CYCLE) {
        counter = 0;/* カウンタのリセット */
                    /* resets the counter */
    }
    /* シェーディングの設定 */
    /* sets the shading mode */
    njSetConstantAttr( 0xFFFFFFFF, NJD_FLAG_USE_FLAT);

    /* スペキュラの切り替え */
    /* changes specular mode (on/off) */
    if (counter < SPECULAR_CYCLE / 2) {
        njPrintC(NJM_LOCATION(7, 7),"SPECULAR ON");
        njSetLightIntensity(&SpecularLight, 20.0F, 0.0F, 0.0F);
    } else {
        njPrintC(NJM_LOCATION(7, 7),"SPECULAR OFF");
        njSetLightIntensity(&SpecularLight, 0.0F, 0.0F, 0.0F);
    }

    /* サンプル名の表示 */
    /* prints the sample program name */
    njPrintC(NJM_LOCATION(23, 4), "Ninja Sample SPECULAR");

    /* マトリックススタックのクリア */
    /* clears the matrix stack */
    njClearMatrix();

    /* 球面の表示 */
    /* draws phere */

    njTranslate(NULL, 0.0F, 0.0F, -100.0F);
    
    /* X,Y,Z 軸の順番に回転 */
    /* rotates x,y,z */
    njRotateXYZ(NULL, rotateAng, rotateAng, rotateAng);

    /* オブジェクトの描画 */
    /* draws object       */
	if (pause == FALSE) {
	   njDrawObject(object__sphere3_sphere3 );
	} else {
	    pause_counter++;
	    if (pause_counter > SCREEN_SAVE_TIME) {
		    njDrawObject(object__sphere3_sphere3 );
			njPrintC(NJM_LOCATION(30, 5), "PAUSE");
		}
		if (pause_counter == SCREEN_SAVE_TIME * 2) {
				pause_counter = 0;
		}
	}

    /* X,Y,Z 軸への回転角の更新 */
    /* updates the rotation angle */
	if (pause == FALSE) {
	    rotateAng += SPECULAR_CHANGE_SPEED;
	}
    return NJD_USER_CONTINUE;
}

/*----------------------------------------------------------------------
         終了処理
         exit
----------------------------------------------------------------------*/
void njUserExit(void)
{
	njExitPrint();
	
    /* メモリの開放 */
   	/* frees the memory area */
    syFree(Matrix);
    syFree(VertexBuffer);
    
    /* システムの終了 */
    /* exits the system    */
    sbExitSystem();
}
