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

  タイトル ： ポリゴンモデルにテクスチャを張る
              texture
  編集履歴 ： 98-04-28 製作開始
              98-06-19 SET5対応
              98-09-16 テクスチャバッファ確保のサイズ変更
              99-04-05 appends the English comments
************************************************************/

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

void main(void)
{
#ifdef __GNUC__
	shinobi_workaround();
#endif
    njSetBorderColor( 0x00000000 );
    njUserInit();
    while (njUserMain() == NJD_USER_CONTINUE) {
        njWaitVSync();
    }
    njUserExit();
}


/* グローバルセクション */
/* global data */

/* 外部定義のモデルデータとテクスチャデータ */
/* model and texture data */
extern NJS_OBJECT   object_cube[];
extern NJS_TEXLIST  texlist_cube;

/* マトリクス関連 */
/* matrix */
#define MATRIX_DEPTH 16
#define VERTEX_MAX   1048

/* 光源 ＆ 視点 */
/* light source and view point */

static NJS_VIEW  g_View;
static NJS_LIGHT g_Light;

/* 回転データ */
/* rotation data */

static Angle g_XAng = NJM_DEG_ANG(0.0F);
static Angle g_YAng = NJM_DEG_ANG(0.0F);
static Angle g_ZAng = NJM_DEG_ANG(0.0F);

/* テクスチャデータ */
/* texture data */
#define TEXTURE_NUM 1

static NJS_TEXMEMLIST g_Texture[TEXTURE_NUM]; /*テクスチャデータ保持領域*/
                                              /* texture data area */

static NJS_VERTEX_BUF *g_VBuf;
static NJS_MATRIX *g_Matrix;  /* マトリクススタック */
                              /* matrix stack */

/* ポーズ判定フラグ */
/* pause flag */
Bool g_bPause = FALSE;

/* ポーズ処理関数 */
/* pause function */
void ActivePhase(void);

/* アクティブ処理関数 */
/* active(not pause) function */
void PausePhase(void);

/**********************************************************************

	njSetBorderColor( 0x00000000 );
    njUserInit --- Ninjaシステム初期化関数
                   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 */
    g_Matrix = (NJS_MATRIX *)syMalloc(sizeof(NJS_MATRIX) * MATRIX_DEPTH);
    g_VBuf = (NJS_VERTEX_BUF *)syMalloc(sizeof(NJS_VERTEX_BUF) * VERTEX_MAX);
    njInitTextureBuffer( ( Sint8 * )g_VBuf, 0x800*10 );

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

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

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

    /* 演算用頂点バッファの初期化 */
    njInit3D( g_VBuf, VERTEX_MAX);
    /* initializes 3D system  */

    /* 光源の初期化 */
    /* initialize the light source */
    njCreateLight(&g_Light, NJD_LAMBERT_DIR);

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

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

    /* テクスチャのロードとセットアップ */
    /* loads and sets up the texture */
    njInitTexture(g_Texture, TEXTURE_NUM);  /* テクスチャの領域を確保 */
                                            /* sets the area used for storing texture information */
    njLoadTexture(&texlist_cube);  /* テクスチャリストのデータのロード */
                                   /* loads data in the texture list  */
    njSetTexture(&texlist_cube);   /* テクスチャリストをカレントにセット */
                                   /* sets current texture list */

    /* クリッピング面の設定 */
	/* specifies the limit values of near clipping and far clipping */
    njClipZ( -1.0f, -500.f );

    /* テキストのカラーの設定 */
     /* sets the text color */
   njPrintColor(ARGB(0xff, 0xc0, 0xc0, 0xc0));
}


/**********************************************************************

    njUserMain --- Ninjaシステムメイン処理関数
                   main
**********************************************************************/

Sint32 njUserMain(void)
{
    NJS_PERIPHERAL *per;

    /* ジョイスティックポート１のペリフェラル情報を取得 */
    /* gets the peripheral information (port A) */
    per = njGetPeripheral(NJD_PORT_A0);

    /* ボタンが押されたかどうかチェック */
    /* checks the start button */
    if (per->press & NJD_DGT_ST) {
        g_bPause = !g_bPause;
    }

	/* ポーズ状態によって処理を切り替える */
	/* pause or not */
	if (!g_bPause) {
		ActivePhase();
	} else {
		PausePhase();
	}

    /* デバッグ情報の表示 */
    /* prints the sample program name */
    njPrintC(NJM_LOCATION(23, 4), "Ninja Sample TEXTURE CUBE");

    return NJD_USER_CONTINUE;
}


/**********************************************************************

    ActivePhase --- アクティブ処理関数
                    main ( not pause )
**********************************************************************/

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

    /* 平行移動 */
    /* translate */
    njTranslate(NULL, 0.0F, 0.0F, -10.0F);

    /* X,Y,Z 軸の順番に回転 */
    /* rotates x,y,z */
    njRotateXYZ(NULL, g_XAng, g_YAng, g_ZAng);

    /* オブジェクトの描画 */
    /* draws the object */
    njDrawObject(object_cube);

    /* X,Y,Z 軸への回転角の更新 */
    /* updates rotation angle (x,y,z) */
    g_XAng += NJM_DEG_ANG(1.0F);
    g_YAng += NJM_DEG_ANG(1.0F);
    g_ZAng += NJM_DEG_ANG(1.0F);
}


/**********************************************************************

    PausePhase --- ポーズ処理関数
                   pause
**********************************************************************/

void PausePhase(void)
{
    NJS_POINT2COL pc;
    NJS_POINT2    p[4];
    NJS_COLOR     col[4];
    Uint8  alpha;
	static Angle ang = NJM_DEG_ANG(0.0F);
	
    /* マトリクススタックのクリア */
    /* clears the matrix stack */
    njClearMatrix();

    /* 平行移動 */
    /* translate */
    njTranslate(NULL, 0.0F, 0.0F, -10.0F);

    /* X,Y,Z 軸の順番に回転 */
    /* rotates x,y,z */
    njRotateXYZ(NULL, g_XAng, g_YAng, g_ZAng);

    /* オブジェクトの描画 */
    /* draws the object */
    njDrawObject(object_cube);

    /* セーバー用スプライトの設定 */
    /* sets polygon for screen saver */

    /* アルファ値の算出 */
    /* calculates alpha value */
    ang += NJM_DEG_ANG(2.0F);
    alpha = (Uint8)(njSin(ang) * 64 + 192);
    
    pc.p   = p;
    pc.col = col;
    pc.tex = NULL;
    pc.num = 4;
    
    p[0].x = 0;
    p[0].y = 0;
    col[0].argb.a = alpha;
	col[0].argb.r = 0;
	col[0].argb.g = 0;
	col[0].argb.b = 0;

    p[1].x = 0;
    p[1].y = 480;
    col[1].argb.a = alpha;
	col[1].argb.r = 0;
	col[1].argb.g = 0;
	col[1].argb.b = 0;

    p[2].x = 640;
    p[2].y = 480;
    col[2].argb.a = alpha;
	col[2].argb.r = 0;
	col[2].argb.g = 0;
	col[2].argb.b = 0;

    p[3].x = 640;
    p[3].y = 0;
    col[3].argb.a = alpha;
	col[3].argb.r = 0;
	col[3].argb.g = 0;
	col[3].argb.b = 0;

    /* セーバー用ポリゴンの描画 */
    /* draws the screen saver */
    njDrawPolygon2D(&pc, 4, -2.0F, NJD_FILL | NJD_TRANSPARENT);

	/* ポーズのお知らせ */
	/* prints 'PAUSE' string */
    njPrintC(NJM_LOCATION(38, 30), "PAUSE");
}


/**********************************************************************

    njUserExit --- Ninjaシステム終了処理関数
                   exit
**********************************************************************/

void njUserExit(void)
{
    /* メモリの開放 */
	/* frees the memory area */
    syFree(g_Matrix);
    syFree(g_VBuf);

	njExitPrint();
    njExitTexture();

    /* システムの終了処理をします 最後に必ず呼び出してください */
    /* exits the system    */
    sbExitSystem();
}
