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

  タイトル ： フォグの設定（雲）
              fog (cloud)
  編集履歴 ： 98-05-11 作成開始
              98-06-19 SET5対応
              98-07-08 C0焼き付き問題に対応（ポーズ追加）
              98-09-16 テクスチャバッファ確保のサイズ変更
              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 20000
#define MAX_TEXTURE_NUM 20

extern NJS_TEXLIST texlist_air00_body_1;
extern NJS_CNK_OBJECT object_air00_body_1_body_1[];
extern NJS_CNK_OBJECT object_air00_body_1_proR_0[];
extern NJS_CNK_OBJECT object_air00_body_1_proR_1[];
extern NJS_CNK_OBJECT object_air00_body_1_proR_5[];
extern NJS_CNK_OBJECT object_air00_body_1_proR_6[];

static NJS_MATRIX *Matrix;
static NJS_VERTEX_BUF *VBuf;
static NJS_VIEW View;
static NJS_LIGHT Light;
static NJS_TEXMEMLIST Tex[MAX_TEXTURE_NUM];
static NJS_FOG_TABLE FogOrg;
static NJS_FOG_TABLE Fog;

PDS_PERIPHERAL* Per;

void PauseMode(void);

static Sint32 fog_set_flag = 0;


/* フォグテーブルセット関数 */
/* sets the fog table */
void SetFogTable(void)
{
	if (fog_set_flag != 0) {
        njSetFogTable(Fog);
		fog_set_flag = 0;
	}
}
/************************************************************
  初期化関数
  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);
    VBuf = syMalloc(sizeof(NJS_VERTEX_BUF) * MAX_VERTEXES);

    /* バックグラウンドカラーを設定 */
	/* sets background color */
    njSetBackColor(ARGB(0, 150, 150, 150),
        ARGB(0, 150, 150, 150), ARGB(0, 150, 150, 150));

    /* テクスチャバッファの確保 */
    /* sets necessary memory for work area of a texture */ 
    njInitTextureBuffer((Sint8 *)VBuf,0x800*10);

    /* 頂点データ登録用バッファをアロケート（１つの頂点＊６４／４バイト） */
    /* 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 (1:for the light)*/
    njInitMatrix(Matrix, MAX_MATRIX_DEPTH, 1);

    /* ３Ｄシステムの初期化（モデル描画のためのワークバッファを初期化） */
    /* initializes 3D system  */ 
    njInit3D(VBuf, MAX_VERTEXES);

    /* 光源の種類を定めライトを新たに設置（平行光源を登録）
      （位置＝0,0,0）（向き＝0,0,-1） */
    /* initializes the light source  (Parallel light source ) */
    /* position( 0,0,0)/ direction (0,0,-1) */
    njCreateLight(&Light, NJD_SPEC_DIR);

    /* ビューの初期化（位置＝0,0,0）（向き＝0,0,-1）（傾き＝０度） */
    /* initializes the user-defined view */
    /* position(0,0,0) / direction(0,0,-1) / ( sight tilt = 0)*/
    njInitView(&View);

    /* ユーザの用意したビューをカレントビューに指定 */
	/* specifies the current view */
    njSetView(&View);

    /* テクスチャのロード */
    /* loads the texture */
    njInitTexture(Tex, MAX_TEXTURE_NUM);
    njLoadTexture(&texlist_air00_body_1);
    njSetTexture(&texlist_air00_body_1);

	/* フォグテーブルセット関数の登録 */
	/* registers the execution function following rendering */
	njSetEORFunction( SetFogTable );

    /* フォグテーブルの作成とデンシティの設定 */
    /* creates fog table and sets density */
    njGenerateFogTable3(FogOrg, 0.0F, -700.0F);

    /* フォグの色を指定 */
    /* sets the fog color */
    njSetFogColor(ARGB(0, 150, 150, 150));

    /* フォグ効果をオンにする */
    /* enables the fog effect */
    njFogEnable();

    /* デバッグ文字の色 */
    /* sets the text color */
    njPrintColor(ARGB(255, 150, 150, 150));
}

/************************************************************
  定期実行されるメイン処理
  main
************************************************************/
Sint32 njUserMain(void)
{
    static Angle angPro = NJM_DEG_ANG(0.0F); /* プロペラの回転角 */
                                             /* propeller's rotate angle */
    static int posFog = 0;

    static Bool pauseMode = FALSE;

    /* サンプル名の表示 */
    /* prints the sample program name */
    njPrintC(NJM_LOCATION(4, 2), "Ninja Sample FOG 2");
    njPrintC(NJM_LOCATION(4, 4), "Press Start Button To Pause");

    /* ペリフェラルチェック */
    /* gets the peripheral information */
    Per = pdGetPeripheral(PDD_PORT_A0);
    if (Per->press & PDD_DGT_ST) { /* スタートボタンが押された */
                                   /* pressing the start button ? */
        pauseMode = !pauseMode;
    }
    /* ポーズ画面を作る */
    /* pause */
    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);
        njSetConstantAttr(0xffffffff, NJD_FST_UA);
        njSetConstantMaterial(&argb);

        PauseMode();
    }
    else {
        njControl3D(NJD_CONTROL_3D_CNK_CONSTANT_ATTR);
        njSetConstantAttr(0xffffffff, 0);
    }

    if (pauseMode == FALSE) {
        int fog;
        for (fog = 0; fog < 128; fog++) {
            Fog[fog] = FogOrg[fog] + njSin((Angle)(NJM_DEG_ANG(1.0F) *
                360.0F * (Float)(fog + posFog) / 32.0F)) * 0.2F;
            if (Fog[fog] > 1.0F) {
                Fog[fog] = 1.0F;
            }
            if (Fog[fog] < 0.0F) {
                Fog[fog] = 0.0F;
            }
        }

        posFog++;
        if (posFog >= 128) {
            posFog = 0;
        }

        /* フォグテーブルのセット要求を発行 */
        /* requests the setting fog table */
        fog_set_flag = -1;

        /* プロペラの回転 */
        /* rotates the propeller */
        angPro += NJM_DEG_ANG(10.0F);
        object_air00_body_1_proR_0->ang[2] = angPro;
        object_air00_body_1_proR_1->ang[2] = angPro;
        object_air00_body_1_proR_5->ang[2] = angPro;
        object_air00_body_1_proR_6->ang[2] = angPro;
    }
	
    njPushMatrix(NULL);
    njTranslate(NULL, 0.0F, 0.0F, -350.0F);
    njRotateX(NULL, NJM_DEG_ANG(-10.0F));
    njRotateY(NULL, NJM_DEG_ANG(-145.0F));
    njCnkDrawObject(object_air00_body_1_body_1);
    njPopMatrix(1);

    return NJD_USER_CONTINUE;
}

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

    /* テクスチャを解放 */
   	/* exits texture use */
	njExitPrint();
    njExitTexture();
    
    /* システムの終了 */
    /* exits the system */
    sbExitSystem();
}

/************************************************************
  ポーズ時に呼び出される処理
   pause
************************************************************/
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);
    }
}
