graphic_00.c 3.91 KB
/*============================================================================

		NINTENDO64 TECHNICAL SUPPORT CENTER 
		
		    NINTENDO64 SAMPLE PROGRAM 2

		Copyright (C) 1997, NINTENDO Co,Ltd.

============================================================================*/

#include <ultra64.h>
#include <PR/ramrom.h>
#include <assert.h>

#include "def.h"
#include "vram.h"
#include "segment.h"
#include "message.h"
#include "nnsched.h"
#include "graphic.h"
#include "controller.h"

extern Gfx cont_finish_dl[];

extern ModelMtx mtx_cont[];
extern Gfx lodmodel_dl[];

void Model_lodmodel(ModelMtx*);

extern void Perf_line(void);

/*-----------------------------------------------------------------------------
  graphic00

-----------------------------------------------------------------------------*/
void graphic_00(void)
{
  Dynamic* dynamic_ptr;
  NNScTask *t;
  static LookAt lookat;
  u16   perspNorm;


  /* 
     ディスプレイリストバッファ・タスクバッファの指定
  */
  dynamic_ptr = &gfx_dynamic[gfx_gtask_no];
  glist_ptr = &gfx_glist[gfx_gtask_no][0];
  t = &gfx_task[gfx_gtask_no];

  /* RSPとRDPの設定 */
  gfxRCPInit();

  /* フレームバッファとZバッファのクリア */
  gfxClearCfb();

  /* 投影マトリックスの計算と設定 */
  guPerspective(&dynamic_ptr->projection, &perspNorm,
                33, 320.0/240.0, 10, 2000, 1.0);
  guLookAtReflect(&dynamic_ptr->viewing, &lookat,
                  0, 0, 600,
                  0, 0, 0,
                  0, 1, 0);
  gSPPerspNormalize(glist_ptr++, perspNorm);
  gSPLookAt(glist_ptr++, &lookat);

  gSPMatrix(glist_ptr++, &(dynamic_ptr->projection), 
            G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
  gSPMatrix(glist_ptr++, &(dynamic_ptr->viewing), 
            G_MTX_PROJECTION | G_MTX_MUL | G_MTX_NOPUSH);
  
  /* モデルの描画 */
  Model_lodmodel(&mtx_cont[0]);
  gDPFullSync(glist_ptr++);

  /*
     F3DEX Ver1.20から追加された機能の
     L3DEXマイクロコードのダイレクトロード指定
     ただし、F3DEX Ver1.20にはこの機能に不具合があるので
     F3DEX Ver1.21を使用すること
     ちなみに、gSPLoadUcodeLはgSPLoadUcodeのマクロ。

     Change L3DEX -> L3DEX2
   */
  gSPLoadUcodeL(glist_ptr++, gspL3DEX2_fifo);

  /* RCPの再設定。実際はRSPのみで良いが、
     念のためここでは両方再設定しています */
  gfxRCPInit();

  /* パフォーマンスメータの描画。L3DEX(ライン)マイクロコード使用 */
  Perf_line();

  /* end top-level display list */
  gSPEndDisplayList(glist_ptr++);

  /* Flush the dynamic segmnet */
  osWritebackDCacheAll();

  /* グラフィックタスクの開始 */
  gfxTaskStart(t, gfx_glist[gfx_gtask_no],
	       (s32)(glist_ptr - gfx_glist[gfx_gtask_no]) * sizeof (Gfx),
	       GFX_GSPCODE_F3DEX2, NN_SC_SWAPBUFFER);
}


/*-----------------------------------------------------------------------------
  LODサンプルモデルの表示
  10-500  ”NEAR”モデル
  501
  
-----------------------------------------------------------------------------*/
void Model_lodmodel(ModelMtx* model_mtx)
{
  Mtx rotate_x;
  Mtx rotate_y;
  Mtx rotate_z;

  /* モデル座標系の計算 */
  guTranslate(&(model_mtx->trans), model_mtx->pos_x, model_mtx->pos_y, model_mtx->pos_z);
  guScale(&(model_mtx->scale), model_mtx->size, model_mtx->size, model_mtx->size);
  guRotate(&rotate_x, model_mtx->rot_x, 1.0, 0.0, 0.0);
  guRotate(&rotate_y, model_mtx->rot_y, 0.0, 1.0, 0.0);
  guRotate(&rotate_z, model_mtx->rot_z, 0.0, 0.0, 1.0);
  guMtxCatL(&rotate_x,&rotate_y, &model_mtx->rotate);
  guMtxCatL(&rotate_z,&model_mtx->rotate,&model_mtx->rotate);

  /* モデルマトリックスの設定 */

  gSPMatrix(glist_ptr++, &(model_mtx->trans), 
	    G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH);


  gSPMatrix(glist_ptr++, &(model_mtx->rotate), 
	    G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);

  gSPMatrix(glist_ptr++, &(model_mtx->scale), 
	    G_MTX_MODELVIEW | G_MTX_MUL | G_MTX_NOPUSH);

  gSPSegment(glist_ptr++, STATIC_SEGMENT, osVirtualToPhysical(gfx_dlist_buf[0]));
  /* モデルのディスプレイリスト */
  gSPDisplayList(glist_ptr++, lodmodel_dl);
}