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

  タイトル ： 平行光源の設定、
              グーロ、フラットシェーディングの切り替え
  編集履歴 ： 98-05-01 作成開始
              98-06-19 SET5対応
              98-07-08 C0焼き付き問題に対応（ポーズ追加）
************************************************************/

#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 10000

extern NJS_CNK_OBJECT object_segalogo_s1_s1[];

static NJS_MATRIX *Matrix;
static NJS_VERTEX_BUF *VBuf;

static NJS_VIEW View;
static NJS_LIGHT Light;

PDS_PERIPHERAL* Per;

void PauseMode(void);

/************************************************************
  初期化関数
************************************************************/
void njUserInit(void)
{
    /* システムを初期化 */
    sbInitSystem(NJD_RESOLUTION_640x240_NTSCNI, NJD_FRAMEBUFFER_MODE_RGB565, 1);
    /* 画面のアスペクト比を補正 */
    njSetAspect(1.0F, 0.45F);

    /* バッファ用メモリをアロケート */
    Matrix = syMalloc(sizeof(NJS_MATRIX) * MAX_MATRIX_DEPTH);
    VBuf = syMalloc(sizeof(NJS_VERTEX_BUF) * MAX_VERTEXES);

    /* バックグラウンドカラーを設定 */
    njSetBackColor(ARGB(0, 128, 0, 0),
        ARGB(0, 128, 0, 0), ARGB(0, 128, 128, 0));
    /* 頂点データ登録用バッファをアロケート（１つの頂点＊６４バイト／４） */
    njInitVertexBuffer(MAX_VERTEXES * 64 / 4, 0, MAX_VERTEXES * 64 / 4, 0, 0);
	njInitPrint( NULL, 0, NJD_TEXFMT_ARGB_1555 );
    /* マトリクススタックを初期化（１＝ライト演算用のマトリクスを使用） */
    njInitMatrix(Matrix, MAX_MATRIX_DEPTH, 1);
    /* ３Ｄシステムの初期化（モデル描画のためのワークバッファを初期化） */
    njInit3D(VBuf, MAX_VERTEXES);
    /* 光源の種類を定めライトを新たに設置（平行光源を登録）
      （位置＝0,0,0）（向き＝0,0,-1） */
    njCreateLight(&Light, NJD_SPEC_DIR);
    /* ビューの初期化（位置＝0,0,0）（向き＝0,0,-1）（傾き＝０度） */
    njInitView(&View);
    /* ユーザの用意したビューをカレントビューに指定 */
    njSetView(&View);
    /* デバッグ文字の色 */
    njPrintColor(ARGB(255, 150, 150, 150));
}

/************************************************************
  定期実行されるメイン処理
************************************************************/
Sint32 njUserMain(void)
{
    static int timer = 0; /* シェーディングを切り替えるタイマー */

    static enum {
        SHADING_FLAT,
        SHADING_GOURAUD,
        SHADING_END
    } shading = SHADING_FLAT; /* シェーディングモード */

    static Angle angleX = NJM_DEG_ANG(0);
    static Angle angleY = NJM_DEG_ANG(0);
    static Angle angleZ = NJM_DEG_ANG(0);

    static Bool pauseMode = FALSE;

    /* サンプル名の表示 */
    njPrintC(NJM_LOCATION(4, 2), "Ninja Sample LIGHT");
    njPrintC(NJM_LOCATION(4, 4), "Press Start Button To Pause");

    /* モードの表示 */
    if (shading == SHADING_FLAT) {
        njPrintC(NJM_LOCATION(4, 6), "Mode = Flat Shading");
    }
    else {
        njPrintC(NJM_LOCATION(4, 6), "Mode = Gouraud Shading");
    }

    /* ペリフェラルチェック */
    Per = (PDS_PERIPHERAL *) pdGetPeripheral(PDD_PORT_A0);
    if (Per->press & PDD_DGT_ST) { /* スタートボタンが押された */
        pauseMode = !pauseMode;
    }

    /* ポーズ画面を作る */
    if (pauseMode == TRUE) {
        NJS_ARGB argb = { -0.8F, 0.0F, 0.0F, 0.0F };
        njControl3D(NJD_CONTROL_3D_CNK_CONSTANT_ATTR |
                    NJD_CONTROL_3D_OFFSET_MATERIAL);
        if (shading == SHADING_FLAT) {
            njSetConstantAttr(0xffffffff, NJD_FST_FL |
                                          NJD_FST_UA);
        }
        else {
            njSetConstantAttr(0xffffffff, NJD_FST_UA);
        }
        njSetConstantMaterial(&argb);
        PauseMode();
    }
    else {
        njControl3D(NJD_CONTROL_3D_CNK_CONSTANT_ATTR);
        if (shading == SHADING_FLAT) {
            njSetConstantAttr(0xffffffff, NJD_FST_FL);
        }
        else {
            njSetConstantAttr(0xffffffff, 0);
        }
    }

    if (pauseMode == FALSE) {
        /* ２秒経ったらシェーディング切り替え */
        timer++;
        if (timer == 120) {
            if (shading == SHADING_FLAT) {
                shading = SHADING_GOURAUD;
            }
            else {
                shading = SHADING_FLAT;
            }
            timer = 0;
        }
        /* 回転角の更新 */
        angleX += NJM_DEG_ANG(0.5F);
        angleY += NJM_DEG_ANG(0.5F);
        angleZ += NJM_DEG_ANG(0.5F);
    }

    njClearMatrix();
    njTranslate(NULL, 0.0F, 0.0F, -7.5F);
    njRotateXYZ(NULL, angleX, angleY, angleZ);
    njCnkDrawObject(object_segalogo_s1_s1);

    return NJD_USER_CONTINUE;
}

/************************************************************
  実行終了時に呼び出される終了処理
************************************************************/
void njUserExit(void)
{
	njExitPrint();
    /* メモリを解放 */
    syFree(Matrix);
    syFree(VBuf);

    /* システムの終了 */
    sbExitSystem();
}

/************************************************************
  ポーズ時に呼び出される処理
************************************************************/
void PauseMode(void)
{
    static Sint16 interval = 0;
    static Bool display = TRUE;

    interval++;
    if (interval >= 30) {
        display = !display;
        interval = 0;
    }
    if (display == TRUE) {
        njPrintSize(32);
        njPrintC(NJM_LOCATION(7, 6),"PAUSE!");
        njPrintSize(8);
    }
}
