main.c 7.92 KB
/*
 *  NINTENDO64 SAMPLE PROGRAM
 *
 *  FILE : main.c
 *
 *  Copyright (C) 1997, NINTENDO Co,Ltd.
 */


#include  <ultra64.h>
#include  <PR/gs2dex.h>
#include  "system.h"
#include  "action.h"
#include  "cursor.h"
#include  "bg.h"
#include  "tile.h"
#include  "puzzle.h"
#include  "sprite.h"
#include  "mysched.h"
#include  "n_libaudio.h"
#include  "audio.h"


/* グラフィックス共通 */
#define  S2DEX_UCODE(x)	gspS2DEX_fifo##x##Start
#define  GfxLog		0

extern  Gfx  init_dl[];


/* BG  */
BG_STATE  bgStat[2];


/* Cursor */
Action        Ac;
CURSOR_STATE  curStat;


/* Tile */
TILE_STATE  root;
TILE_STATE  tileStat[TILES];


/* Puzzle */
PUZZLE_STATE  puzStat;


/*
 *  オーディオ用
 */
u8  *seqptr;


#ifdef TIMER_BAR
/*
 * デバッグ用タイマーバー
 */
u32  time_retrace = 0;

u32  time_gfx_rsp_start = 0;
u32  time_gfx_rsp_end   = 0;
u32  time_gfx_rdp_end   = 0;

u32  time_aud_rsp_start = 0;
u32  time_aud_rsp_end   = 0;

u32  time_gfx_cpu_start = 0;
u32  time_gfx_cpu_end   = 0;

u32  time_aud_cpu_start = 0;
u32  time_aud_cpu_end   = 0;

u32  delta_gfx_rsp_start;
u32  delta_aud_rsp_start;

u32  delta_gfx_cpu_start;
u32  delta_aud_cpu_start;

u32  delta_gfx_rsp_end;
u32  delta_gfx_rdp_end;
u32  delta_aud_rsp_end;

u32  delta_gfx_cpu_end;
u32  delta_aud_cpu_end;
#endif


/*
 * タスクデータ定義
 */
MYScTask  tlist[2] = {{
  NULL,                                         /* frame buffer             */
  M_GFXTASK,					/* task type                */
  OS_TASK_DP_WAIT|OS_TASK_LOADABLE,		/* task flags               */
  (u64 *)&rspbootTextStart,			/* boot ucode ptr           */
  SP_BOOT_UCODE_SIZE,				/* boot ucode size          */
  (u64 *)&S2DEX_UCODE(Text),			/* ucode ptr                */
  SP_UCODE_SIZE,				/* ucode size               */
  (u64 *)&S2DEX_UCODE(Data),			/* ucode data ptr           */
  SP_UCODE_DATA_SIZE,				/* ucode data size          */
  NULL,						/* dram stack      (不使用) */
  0,						/* dram stack size (不使用) */
  (u64 *)system_rdpfifo,			/* fifo buffer top          */
  (u64 *)system_rdpfifo+RDPFIFO_SIZE,		/* fifo buffer bottom       */
  NULL,						/* data ptr      (後で設定) */
  0,						/* data size     (設定不要) */
  (u64 *)system_rspyield,			/* yield data ptr           */
  (u32)GfxLog  /* S2DEXでは DL log ptr を指定      yield data size(設定不要)*/
},{
  NULL,
  M_GFXTASK,
  OS_TASK_DP_WAIT|OS_TASK_LOADABLE,
  (u64 *)&rspbootTextStart,
  SP_BOOT_UCODE_SIZE,
  (u64 *)&S2DEX_UCODE(Text),
  SP_UCODE_SIZE,
  (u64 *)&S2DEX_UCODE(Data),
  SP_UCODE_DATA_SIZE,
  NULL,
  0,
  (u64 *)system_rdpfifo,
  (u64 *)system_rdpfifo+RDPFIFO_SIZE,
  NULL,
  0,
  (u64 *)system_rspyield,
  (u32)GfxLog
}};


/*
 * グラフィクスタスクリスト領域
 */
Gfx  glist[2][GLIST_LEN];


/*
 *  メイン
 */
void  Main(void  *arg)
{

  u8    
    draw_frame = 0,
    *ptr;
  s32   
    length,
    seqNo;
  Gfx  
    *gp,
    *gtop;


  /* static セグメントのロード */
  length = (s32)_staticSegmentRomEnd - (s32)_staticSegmentRomStart;
  romCopy(_staticSegmentRomStart, _codeSegmentEnd, length);

  /* パズル用イメージのロード */
  length = (s32)_imageSegmentRomEnd - (s32)_imageSegmentRomStart;
  romCopy(_imageSegmentRomStart, (u8 *)IMAGE_ADDRESS, length);

  /* Action 構造体の初期化 */
  actionInit(&Ac);

  /* BG 構造体の初期化 */
  bgInit(&bgStat[0], &objBg[0], &objTLUTBg);
  bgInit(&bgStat[1], &objBg[1], &objTLUTBg);

  /* カーソル構造体の初期化 */
  cursorInit(&curStat, &objCursor, &objTxtrCursor);

  /* タイル構造体の初期化 */
  tileInit(&root, tileStat, &each_tile, &complete);

  /* パズル構造体の初期化 */
  puzzleInit(&puzStat);


  /* シーケンスデータの読み込み */
  seqNo  = 0;
  seqptr = alHeapAlloc(&hp, 1, MAX_SEQ_LENGTH);
  ptr    = seqfile->seqArray[seqNo].offset;
  length = seqfile->seqArray[seqNo].len;
  if(length & 0x1)
    length++;
  osInvalDCache(seqptr, length);
  romCopy(ptr, seqptr, length);

  /* シーケンスデータの再生 */
  n_alCSeqNew(seq, seqptr);
  n_alCSPSetSeq(seqp, seq);
  n_alCSPSetVol(seqp, 0x4fff);
  n_alCSPPlay(seqp);
  

  /* コントローラの読み込み開始 */
  osContStartReadData(&siMessageQ);


  /* メインループ */
  while(1){

    /* オーディオマネージャからのリトレースメッセージを待つ */
    osRecvMesg(&mainFrameMQ, NULL, OS_MESG_BLOCK);

#ifdef TIMER_BAR
    time_gfx_cpu_start = osGetCount();
#endif

    /* BG 構造体の更新 */
    bgUpdate(&bgStat[draw_frame]);

    /* カーソル楮体の更新 */
    cursorUpdate(&curStat, &Ac, draw_frame);

    /* カーソル位置のチェック */
    puzzleCheck(&puzStat, &curStat, &root);

    /* パズル構造体の更新 */
    puzzleUpdate(&puzStat, &curStat, &root, draw_frame);


    /* Gfx リスト作成 */
    gtop = gp = glist[draw_frame];

    /* RSP 及び RDP の共通設定 */
    gSPSegment    (gp ++, 0, 0x0);
    gSPSegment    (gp ++, STATIC_SEGMENT, _codeSegmentEnd);
    gSPDisplayList(gp ++, init_dl);

    /* 出力バッファの指定 */
    gDPSetColorImage(gp ++, G_IM_FMT_RGBA,
		     G_IM_SIZ_16b, SCREEN_WD, system_cfb[draw_frame]);


    /* BG の描画 */
    gp = bgDraw(gp ++, &bgStat[draw_frame]);

    /* タイルの描画 */
    gp = tileDraw(gp ++, &root, draw_frame);

    /* カーソル描画 */
    gp = cursorDraw(gp ++, &curStat, draw_frame);

#ifdef TIMER_BAR
    /* デバッグ用タイマーバーの描画 */
    gDPPipeSync(gp ++ );
    gDPSetCycleType(gp ++, G_CYC_FILL);
    gDPSetRenderMode(gp ++, G_RM_NOOP, G_RM_NOOP2);

    /* 区切り */
    gDPSetFillColor(gp ++, GPACK_RGBA5551(0, 0, 0,1) << 16 | 
                    GPACK_RGBA5551(0, 0, 0,1));
    /* 0 % */
    gDPFillRectangle(gp ++, 114, 380, 119, 419);
    /* 50 % */
    gDPFillRectangle(gp ++, 318, 380, 321, 419);
    /* 100 % */
    gDPFillRectangle(gp ++, 520, 380, 525, 419);

    /* CPU */
    /* gfx */
    gDPPipeSync(gp ++ );
    gDPSetFillColor(gp ++, GPACK_RGBA5551(255, 0, 0, 1) << 16 | 
                    GPACK_RGBA5551(255, 0, 0, 1));
    gDPFillRectangle(gp ++, 120 + delta_gfx_cpu_start,   380,
                            120 + delta_gfx_cpu_end - 1, 389);
    /* aud */
    gDPPipeSync(gp ++ );
    gDPSetFillColor(gp ++, GPACK_RGBA5551(0, 0, 255, 1) << 16 | 
                    GPACK_RGBA5551(0, 0, 255, 1));
    gDPFillRectangle(gp ++, 120 + delta_aud_cpu_start,   380,
                            120 + delta_aud_cpu_end - 1, 389);

    /* RSP */
    /* gfx */
    gDPPipeSync(gp ++ );
    gDPSetFillColor(gp ++, GPACK_RGBA5551(0, 255, 0, 1) << 16 | 
                    GPACK_RGBA5551(0, 255, 0, 1));
    gDPFillRectangle(gp ++, 120 + delta_gfx_rsp_start,   395, 
                            120 + delta_gfx_rsp_end - 1, 404);
    /* aud */
    gDPPipeSync(gp ++ );
    gDPSetFillColor(gp ++, GPACK_RGBA5551(255, 255, 0, 1) << 16 | 
                    GPACK_RGBA5551(255, 255, 0, 1));
    gDPFillRectangle(gp ++, 120 + delta_aud_rsp_start,   395, 
                            120 + delta_aud_rsp_end - 1, 404);

    /* RDP */
    /* gfx */
    gDPPipeSync(gp ++ );
    gDPSetFillColor(gp ++, GPACK_RGBA5551(255, 0, 255, 1) << 16 | 
                    GPACK_RGBA5551(255, 0, 255, 1));
    gDPFillRectangle(gp ++, 120 + delta_gfx_rsp_start,   410,
                            120 + delta_gfx_rdp_end - 1, 419);
#endif

    /* 終端 */
    gDPFullSync(gp ++);
    gSPEndDisplayList(gp ++);
    

    /* タスクリストをグラフィックスタスクスレッドに送る */
    tlist[draw_frame].list.t.data_ptr = (u64 *)gtop;
    tlist[draw_frame].framebuffer     = &system_cfb[draw_frame];
    osSendMesg(&sc.graphicsRequestMQ, (OSMesg)&tlist[draw_frame], OS_MESG_BLOCK);


    /* Frame 切り替え */
    draw_frame ^= 1;


    /* コントローラデータ受け取り */
    osRecvMesg(&siMessageQ, NULL, OS_MESG_BLOCK);

    /* Action 構造体の更新 */
    actionUpdate(&Ac);

    /* コントローラの読み込み開始 */
    osContStartReadData(&siMessageQ);


    /* オーディオ処理 */
    if(n_alCSPGetState(seqp) == AL_STOPPED){
      n_alCSeqNew(seq, seqptr);
      n_alCSPSetSeq(seqp, seq);
      n_alCSPPlay(seqp);
    }

#ifdef TIMER_BAR
    time_gfx_cpu_end = osGetCount();
#endif

    /* オーディオマネージャに終了メッセージを送る */
    osSendMesg(&__am.audioStartMsgQ, NULL, OS_MESG_BLOCK);
  }


  /* オーディオ後処理 */
  n_alCSPStop(seqp);
}