コード例 #1
0
ファイル: controller.c プロジェクト: shlomnissan/ultra64demos
/*
 * Conroller read thread
 */
void controllerProc(void *arg)
{
  int i;
  u16 button;
  static u16 lastbutton[MAXCONTROLLERS];
  static int cnt;
  OSMesgQueue msgQ;
  OSMesg    msgbuf[MAX_MESGS];
  NNScClient client;

  /* create message queue */
  osCreateMesgQueue(&msgQ, msgbuf, MAX_MESGS);

  /* add client to scheduler */
  nnScAddClient((NNSched*)arg, &client, &msgQ);

  while(1){
    (void)osRecvMesg(&msgQ,NULL, OS_MESG_BLOCK);
    controllerReadStart();
    (void)osRecvMesg(&controllerMsgQ, NULL, OS_MESG_BLOCK);
    osContGetReadData(controllerdata);

    for (i=0; i<numControllers; i++) {
      button = controllerdata_ptr[i]->button;
      controllerdataTriger[i].button = 
	button & (~lastbutton[i]);
      lastbutton[i]=button;
    }
  }
}
コード例 #2
0
ファイル: main.c プロジェクト: shlomnissan/ultra64demos
/*---------------------------------------------------------------------------*
 * The DMA load of the segment.  
 *---------------------------------------------------------------------------*/
void	loadSegment(u32 bg16seg, u32 bg8seg)
{
  /* Load the Static segment. */
  LoadSegment(static, _codeSegmentEnd);
  osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);  
  
  /* Loading of Bg and RGBA segments. */
  LoadSegment(bg_rgba, (char *)bg16seg);
  osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);  
  
  /* Loading of  Bg and CI segments. */
  LoadSegment(bg_ci, (char *)bg8seg);
  osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);  
}
コード例 #3
0
ファイル: morphfaces.c プロジェクト: shlomnissan/ultra64demos
static void gameproc(void *arg) {
  char     *rsp_static_addr;  /* R4300 addr where rsp_static segment loaded */
  char     *rsp_static_end;   /* R4300 addr+1 for end of the load region    */
  int      rsp_static_len;
  OSIoMesg dmaMb;             /* Needed (empty) for call to osEPiStartDma    */

  /* Message Queue for OS messages indicating DMA completions */
  osCreateMesgQueue(&DMAMessageQ, DMAMessages, DMA_MSGQUEUE_SIZE);

  /* Message Queue for OS messages indicating RDP done */
  osCreateMesgQueue(&RDPDoneMessageQ, RDPDoneMessages, RDPDONE_MSGQUEUE_SIZE);
  osSetEventMesg(OS_EVENT_DP, &RDPDoneMessageQ, dummyMsg);

  /* Message Queue for OS messages indicating vertical retrace */
  osCreateMesgQueue(&RetraceMessageQ, RetraceMessages, RETRACE_MSGQUEUE_SIZE);
  osViSetEvent(&RetraceMessageQ, dummyMsg, 1);

  /*
   * Load the 'rsp_static' segment from the cartridge
   */
  rsp_static_len  = _rsp_staticSegmentRomEnd - _rsp_staticSegmentRomStart;

  /* Place it right after the code/data segment in the 3rd MB of memory.
   * Will not collide with CFB's or the Z buffer. Because the texture loads
   * are so frequent, this gives a significant performance enhancement.
   */

  rsp_static_addr = _codeSegmentEnd; /* R4300 address for static segment */
  rsp_static_end  = _codeSegmentEnd + rsp_static_len;

#ifdef DEBUG
  if (rsp_static_len > 0x00300000) {
    osSyncPrintf("** Static Segment too large **\n");
  }
#endif

  /* Note: dmaMb is working space used by osEPiStartDma */

  dmaMb.hdr.pri      = OS_MESG_PRI_NORMAL;
  dmaMb.hdr.retQueue = &DMAMessageQ;
  dmaMb.dramAddr     = rsp_static_addr;
  dmaMb.devAddr      = (u32)_rsp_staticSegmentRomStart;
  dmaMb.size         = rsp_static_len;

  osEPiStartDma(handler, &dmaMb, OS_READ);
  osRecvMesg(&DMAMessageQ, NULL, OS_MESG_BLOCK);  /* Wait for completion */

  /*
   * Do the one-time setup
   * (Build both display lists)
   */
  makestuff();

  /*
   * Run the main loop of the game
   */
  gameloop(rsp_static_addr);

} /* gameproc */
コード例 #4
0
ファイル: graphic.c プロジェクト: shlomnissan/ultra64demos
/*-----------------------------------------------------------------------------
 Graphic thread
-----------------------------------------------------------------------------*/
void gfxproc(void* arg)
{
  short* msg_type = NULL;

  pendingGFX = 0;
  /*  create message queue for VI retrace */
  osCreateMesgQueue(&gfx_msgQ, gfx_msgbuf, GFX_MESGS_MAX);

  nnScAddClient((NNSched*)arg, &gfx_client, &gfx_msgQ);

  /* Get graphic message queue */
  sched_gfxMQ = nnScGetGfxMQ((NNSched*)arg);

  /*
     Graphic process loop 
     The NMI(V-SYNC) process portion of SHVC
  */
  while(1){
    (void)osRecvMesg(&gfx_msgQ,(OSMesg *)&msg_type, OS_MESG_BLOCK);

    switch(*msg_type){
    case NN_SC_RETRACE_MSG:    /* retrace message process */

      switch(graphic_no){
      case GFX_00:   /*controller model screen */
	if(pendingGFX <2){
	  graphic_00();
	  pendingGFX++;
	}
	break;
      case GFX_01:  /* fighter plane screen */
      case GFX_10:
      case GFX_20:
      case GFX_30:
      case GFX_NULL:
	break;
      }
      break;
    case NN_SC_DONE_MSG:   /* end graphic task message */
      pendingGFX--;
      break;
    case NN_SC_PRE_NMI_MSG: /* PRE NMI message */
      /* please write a PRE NMI message process here */

      /* !! Important !!  Reset Y scale to 1.0 */
      osViSetYScale(1.0);

      /* so no task is created */
      pendingGFX+=2;
      break;
    }
  }
}
コード例 #5
0
ファイル: boot.c プロジェクト: shlomnissan/ultra64demos
/*
 * This is the main routine of the app.
 */
static void
mainproc(void *arg)
{

	/*
	 * Setup the message queues
	 */
	osCreateMesgQueue(&dmaMessageQ, &dmaMessageBuf, 1);

	osCreateMesgQueue(&rspMessageQ, &rspMessageBuf, 1);
	osSetEventMesg(OS_EVENT_SP, &rspMessageQ, NULL);

	osCreateMesgQueue(&rdpMessageQ, &rdpMessageBuf, 1);
	osSetEventMesg(OS_EVENT_DP, &rdpMessageQ, NULL);

	osCreateMesgQueue(&retraceMessageQ, &retraceMessageBuf, 1);
	osViSetEvent(&retraceMessageQ, NULL, 1);

	/*
	 * Stick the static segment right after the code/data segment
	 */
	staticSegment = _zbufferSegmentEnd;
	osPiStartDma(&dmaIOMessageBuf, OS_MESG_PRI_NORMAL, OS_READ,
		 (u32) _staticSegmentRomStart, staticSegment,
		 (u32) _staticSegmentRomEnd - (u32) _staticSegmentRomStart,
		 &dmaMessageQ);

	/*
	 * Wait for DMA to finish
	 */
	(void) osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);

	freeSegment = staticSegment + 
		(u32) _staticSegmentRomEnd - (u32) _staticSegmentRomStart;

	initControllers(MAXCONTROLLERS);

	game();
}
コード例 #6
0
ファイル: drawfont.c プロジェクト: shlomnissan/ultra64demos
// printString()
//
// print string s at x,y using font z
// 
void printString(int x,int y,int z,unsigned char *s) {
	OSMesg dummyMessage;
	int ofs,i,sx,dx,dy,cy;

	for(i=0; s[i]; i++){
		ofs=LeoGetAAdr((int)s[i]-32+z*192,&dx,&dy,&cy);

		ddGetFontChar(ofs, currBufferPtr, &dmaMessageQ);

		sx = (dx+1)&254;
		gDPLoadTextureTile_4b(glistp++,
                   currBufferPtr, G_IM_FMT_I, sx, dy, 0, 0,
                   (sx-1)<<G_TEXTURE_IMAGE_FRAC, (dy-1)<<G_TEXTURE_IMAGE_FRAC,
                   0, G_TX_CLAMP, G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, 
                   G_TX_NOLOD, G_TX_NOLOD);
		gSPTextureRectangle(glistp++,
                   x<<2, (y-cy)<<2, (x+dx)<<2, (y-cy+dy)<<2,
                   0, 0, 0, 0x400, 0x400);
		currBufferPtr+=128;
                x += dx+1;
		osRecvMesg(&dmaMessageQ,&dummyMessage,OS_MESG_BLOCK);
	}
}
コード例 #7
0
ファイル: morphfaces.c プロジェクト: shlomnissan/ultra64demos
/*
 * gameloop -- main loop of game
 *             Called by gameproc; runs in gameThread.
 *             Parameter: rsp_static_addr, the R4300 address where the
 *                        rsp_static segment was loaded
 */
static void gameloop(char *rsp_static_addr) {
  int oddframe = 0;        /* Odd or even rendered frame?  Start with even. */
  int firstframe = 1;      /* First frame? */
  dynamic_stuff *generate; /* Dynamic info we're generating now             */
  Gfx           *glistp0;  /* Start of this frame's dynamic display list */
  Gfx           *glistp;   /* Current position in dynamic display list */
  OSTask        *gentask;  /* Task we're generating */
  float         t;         /* Weight of 1st set of morph verticies */
  int           dir;       /* Direction in which we're morphing */
  int           pausecnt;  /* Countdown for "stickiness" at morph extremes */

  t = 0.0;
  dir = 1;
  pausecnt = 0;
  while (1) {
    /* Start task on RSP, built in previous iteration of loop. */
    if (!firstframe) osSpTaskStart(gentask);

    /*
     * Set up pointers to dynamic stuff.  We're always generating one set
     * of dynamic data and drawing another.
     */
    generate = &(dynamic[(oddframe ? 0 : 1)]);

    /* glist portion of generated dynamic data */
    glistp0 = &(generate->glist[0]);
    glistp  = glistp0;  /* This one will be incremented as list is built */
    
    /*
     * Tell RSP where each segment is
     */
    gSPSegment(glistp++, 0, 0x0);     /* Physical address segment */
    /* Static segment (mapping never changes) */
    gSPSegment(glistp++, STATIC_SEG,  OS_K0_TO_PHYSICAL(rsp_static_addr)); 
    /* Dynamic segment (mapping changes every frame) */
    gSPSegment(glistp++, DYNAMIC_SEG, OS_K0_TO_PHYSICAL(generate));

    /* RSP and RDP setup, and screen clear */
    gSPDisplayList(glistp++, rspinit_dl);
    gSPDisplayList(glistp++, rdpinit_dl);
#ifdef FB32BIT
    gDPSetColorImage(glistp++, G_IM_FMT_RGBA, G_IM_SIZ_32b, SCREEN_WD,
		     OS_K0_TO_PHYSICAL(oddframe ? cfb_A : cfb_B));
#else
    gDPSetColorImage(glistp++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WD,
		     OS_K0_TO_PHYSICAL(oddframe ? cfb_A : cfb_B));
#endif
    gSPDisplayList(glistp++, scrnclr_dl);
    /* Must set color image again after zbuffer clear */
#ifdef FB32BIT
    gDPSetColorImage(glistp++, G_IM_FMT_RGBA, G_IM_SIZ_32b, SCREEN_WD,
		     OS_K0_TO_PHYSICAL(oddframe ? cfb_A : cfb_B));
#else
    gDPSetColorImage(glistp++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WD,
		     OS_K0_TO_PHYSICAL(oddframe ? cfb_A : cfb_B));
#endif
    /* Set Z-buffer */
    gDPSetDepthImage(glistp++, OS_K0_TO_PHYSICAL(zbuffer));

    /*
     * Matrix setup, and call display list that does real work
     */
    drawframe(generate, &glistp, t);

    /*
     * Put an END on the top-level display list, and check that we
     * haven't overflowed the buffer.
     */
    gDPFullSync(glistp++); /* Only need this if you want 'accurate' SP done? */
    gSPEndDisplayList(glistp++);
#ifdef DEBUG
    if ((int)(glistp - glistp0) > GLIST_SIZE) {  /* does this check work?? */
      osSyncPrintf("*** GLIST OVERFLOW ***\n");
      /* Could quit here or something */
    } 
#endif

    /* Update morph parameter t */
    if (pausecnt == 0) {
      t += dir*(1.0/60.0);           /* A full 60 frames to do the morph */
      if (t < 0.0) {t = 0.0; dir =  1; pausecnt = 60;}
      if (t > 1.0) {t = 1.0; dir = -1; pausecnt = 60;}
    } else {
      pausecnt--;
    }

    /*
     * Build graphics task
     * Note that all addresses are KSEG0, even if used by the RSP.
     * Conversion is done by the task routines.
     */
    gentask = &(task[oddframe ? 0 : 1]);
    gentask->t.type            = M_GFXTASK;
    gentask->t.flags           = 0x0;
    gentask->t.ucode_boot      = (u64*) rspbootTextStart;
    gentask->t.ucode_boot_size = ((int)rspbootTextEnd - (int)rspbootTextStart);
    gentask->t.ucode           = (u64*) gspF3DEX2_xbusTextStart; /* use XBUS */
    gentask->t.ucode_data      = (u64*) gspF3DEX2_xbusDataStart;
    gentask->t.ucode_size      = 4096;
    gentask->t.ucode_data_size = 2048;
    gentask->t.dram_stack      = (u64*) dram_stack;
    gentask->t.dram_stack_size = SP_DRAM_STACK_SIZE64;
    gentask->t.output_buff     = (u64*) NULL;
    gentask->t.output_buff_size= (u64*) NULL;
    gentask->t.yield_data_ptr  = (u64*) NULL; /* Graphics only - no yielding */
    gentask->t.yield_data_size = 0x0;
    gentask->t.data_ptr        = (u64*) glistp0;
    gentask->t.data_size       = ((int) glistp - (int) glistp0);
    
    /*
     * Flush the whole cache.  Should just do parts of it.
     */
    osWritebackDCacheAll();
    
    if (!firstframe) {
      /* Wait for task completion (message from RDP) */
      osRecvMesg(&RDPDoneMessageQ, NULL, OS_MESG_BLOCK);
    
      /*
       * Specify frame buffer to be displayed starting at next retrace.
       * We display the one that we've just finished rendering.
       */
      osViSwapBuffer(oddframe ? cfb_B : cfb_A);
    }

    /*
     * Wait for the retrace before rendering next frame
     * (otherwise we might overwrite the frame which is being displayed).
     * But first, make sure that the retrace queue is empty in case we
     * took too long to render the last frame.
     */
    if (MQ_IS_FULL(&RetraceMessageQ))
      osRecvMesg(&RetraceMessageQ, NULL, OS_MESG_NOBLOCK);
    osRecvMesg(&RetraceMessageQ, NULL, OS_MESG_BLOCK);

    /* Switch to our other set of variables */
    oddframe ^= 1;

    /* No longer the first frame */
    firstframe = 0;
 
  } /* while(1) */

} /* gameloop */
コード例 #8
0
ファイル: main01.c プロジェクト: shlomnissan/ultra64demos
/*--------------------------
  main01 test stage

  return: next stage no
--------------------------*/
int main01(NNSched* sched)
{

  OSMesgQueue  msgQ;
  OSMesg       msgbuf[MAX_MESGS];
  NNScClient   client;
  u32          controller_num;
  u32          endflag;
  u32          cnt;


  if(numControllers > 2){
    controller_num = 2;
  } else {
    controller_num = numControllers;
  }

  /* create message queue for VI retrace */
  osCreateMesgQueue(&msgQ, msgbuf, MAX_MESGS);

  /* add client to scheduler */
  nnScAddClient(sched, &client, &msgQ);

  /* initialize game subject parameters */
  InitFiter(&fiter[0]);  /* #1 machine */
  fiter[0].pos.x = 45.0;
  fiter[0].dlist_ptr = fiter_1_dl;        /*set display list */
  fiter[0].dlist_buf = (Gfx*)gfx_dlist_buf[0]; /* display list buffer */

  /* read display list */
  auRomRead((u32)_fiter1SegmentRomStart, gfx_dlist_buf[0],
	    (u32)_fiter1SegmentRomEnd - (u32)_fiter1SegmentRomStart);

  InitFiter(&fiter[1]); /* #2 machine */
  fiter[1].pos.x = 360.0-45.0;
  fiter[1].dlist_ptr = fiter_2_dl;  /* set display list */
  fiter[1].dlist_buf = (Gfx*)gfx_dlist_buf[1]; /* display list buffer */

  /* read display list */
  auRomRead((u32)_fiter2SegmentRomStart, gfx_dlist_buf[1],
	    (u32)_fiter2SegmentRomEnd - (u32)_fiter2SegmentRomStart);

  /* viewpoint settings */
  lookat.eye_x = 00.0;
  lookat.eye_y = 0.0;
  lookat.eye_z = -20.0;
  lookat.at_x = 0.0;
  lookat.at_y = 0.0;
  lookat.at_z = 0.0;
  lookat.up_x = 0.0;
  lookat.up_y = 1.0;
  lookat.up_z = 0.0;
  lookat.pitch = 5.0;
  lookat.yaw =  0.0;
  lookat.roll = 0.0;
  lookat.dist = -40.0;

  /* read sequence data */
  auSeqPlayerSetFile(1,0);
  auSeqPlayerPlay(1);


  /* start graphic display */
  graphic_no = GFX_01;
  endflag =0;

  while(!endflag){
    (void) osRecvMesg(&msgQ, NULL, OS_MESG_BLOCK);

    for(cnt = 0; cnt < controller_num; cnt++){

      fiter_move(&fiter[cnt],cnt);
      lookat_move(cnt);

      /* end on Start button push */
      if(controllerdataTriger[cnt].button & START_BUTTON){
	 endflag++;
       }

      /* raise priority of graphic thread */
      if(controllerdata_ptr[cnt]->button & Z_TRIG){
	 threadpri_flag = 1;
      } else {
	threadpri_flag = 0;
      }
    }
  }

  /* stop sequence */
  auSeqPlayerStop(1);
  graphic_no = GFX_NULL;

  /* wait for end of graphic task /audio task */
  while((auSeqPlayerState(0) != AL_STOPPED) || (pendingGFX != 0)){
    (void) osRecvMesg(&msgQ, NULL, OS_MESG_BLOCK);
  };

  /* remove client to scheduler */
  nnScRemoveClient(sched, &client);

  return MAIN_00;
}
コード例 #9
0
ファイル: main.c プロジェクト: LuigiBlood/64ddipl_dumper
void	
mainproc(void *arg)
{	
  int	i, j;
  int	cont_no = 0;
  int	error, readerror;
  u8	bitpattern;
  u16	button = 0, oldbutton = 0, newbutton = 0; 
  u32	stat;
  char 	console_text[50];

  osCreateMesgQueue(&pifMesgQueue, pifMesgBuf, NUM_MESSAGE);
  osSetEventMesg(OS_EVENT_SI, &pifMesgQueue, dummyMessage);

  osContInit(&pifMesgQueue, &bitpattern, &contstat[0]);
  for (i = 0; i < MAXCONTROLLERS; i++) {
    if ((bitpattern & (1<<i)) &&
       ((contstat[i].type & CONT_TYPE_MASK) == CONT_TYPE_NORMAL)) {
      controller[i] = CONT_VALID;
    } else {
      controller[i] = CONT_INVALID;
    }
  }
  
  osCreateMesgQueue(&dmaMessageQ, dmaMessageBuf, 1);

  pi_handle = osCartRomInit();
  pi_ddrom_handle = osDriveRomInit();
  
  bzero(blockData, 0x1000);
  readerror = -1;

  init_draw();

  setcolor(0,255,0);
  draw_puts("If you see this for a long period of time,\nsomething f****d up. Sorry.");
  
  LeoCJCreateLeoManager((OSPri)OS_PRIORITY_LEOMGR-1, (OSPri)OS_PRIORITY_LEOMGR, LeoMessages, NUM_LEO_MESGS);
  LeoResetClear();

  setbgcolor(15,15,15);
  clear_draw();
  
  setcolor(0,255,0);
  draw_puts("\f\n    64DD IPL dumper v0.01b by LuigiBlood & marshallh\n    ----------------------------------------\n");
  setcolor(255,255,255);
  draw_puts("    PRESS START TO DUMP");

  while(1) {
    osContStartReadData(&pifMesgQueue);
    osRecvMesg(&pifMesgQueue, NULL, OS_MESG_BLOCK);
    osContGetReadData(&contdata[0]);
    if (contdata[cont_no].errno & CONT_NO_RESPONSE_ERROR) {
      button = oldbutton;
    } else {
      oldbutton = button;
      button = contdata[cont_no].button;
    }
    newbutton = ~oldbutton & button;
    
    if (newbutton & START_BUTTON)
    {
        //DUMP!!
        
        //64drive, enable write to SDRAM/ROM
		  srand(osGetCount()); // necessary to generate unique short 8.3 filenames on memory card
        ciEnableRomWrites();

        draw_puts("\f\n\n\n\n\n    Let's dump! Don't turn off the console!\n\n");
        
        osInvalDCache((void *)&blockData, (s32) 0x1000); 
        dmaIoMesgBuf.hdr.pri = OS_MESG_PRI_NORMAL;
        dmaIoMesgBuf.hdr.retQueue = &dmaMessageQ;
        dmaIoMesgBuf.dramAddr = &blockData;
        dmaIoMesgBuf.devAddr = IPLoffset;
        dmaIoMesgBuf.size = 0x1000;
        
        for (IPLoffset = 0; IPLoffset < 0x400000; IPLoffset += 0x1000)
        {
          //read 64DD IPL
          osWritebackDCacheAll();
 
          dmaIoMesgBuf.hdr.pri = OS_MESG_PRI_NORMAL;
          dmaIoMesgBuf.hdr.retQueue = &dmaMessageQ;
          dmaIoMesgBuf.dramAddr = (void *)&blockData;
          dmaIoMesgBuf.devAddr = 0xA6000000 + IPLoffset;
          dmaIoMesgBuf.size = 0x1000;
                               
          osEPiStartDma(pi_ddrom_handle, &dmaIoMesgBuf, OS_READ);
          osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);
         
          //Write to 64drive
          osWritebackDCacheAll();
 
          dmaIoMesgBuf.hdr.pri = OS_MESG_PRI_NORMAL;
          dmaIoMesgBuf.hdr.retQueue = &dmaMessageQ;
          dmaIoMesgBuf.dramAddr = (void *)&blockData;
          dmaIoMesgBuf.devAddr = 0xB0000000 + IPLoffset;
          dmaIoMesgBuf.size = 0x1000;
                               
          osEPiStartDma(pi_handle, &dmaIoMesgBuf, OS_WRITE);
          osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);
        }
		  
		  //DONE!! NOW WRITE TO SD
		  fat_start();
        
        draw_puts("\n    - DONE !!\n");
		
        for(;;);
    }
  }
}
コード例 #10
0
ファイル: graphic.c プロジェクト: shlomnissan/ultra64demos
/*----------------------------------------------------------------------------
  gfxWaitMessage

Wait for message from scheduler 
 
Return : Types of messages from scheduler 
                  OS_SC_RETRACE_MSG :  retrace message 
	  OS_SC_PRE_NMI_MSG:    PRE NMI message
----------------------------------------------------------------------------*/
short gfxWaitMessage(void)
{
  short* msg_type = NULL;
  (void)osRecvMesg(&gfx_msgQ,(OSMesg *)&msg_type, OS_MESG_BLOCK);
  return *msg_type;
}
コード例 #11
0
ファイル: main.c プロジェクト: shlomnissan/ultra64demos
/*---------------------------------------------------------------------------*
 * M A I N 
 *---------------------------------------------------------------------------*/
void	Main(void *arg)
{
  u8	draw_frame = 0;
  u32	objRM;
  Gfx	*gp, *gtop;
  OSTime rspstart;
  u32	 rsptime, rdptime;
  
  bg16seg = (u32)_codeSegmentEnd 
          + (u32)_staticSegmentEnd - (u32)_staticSegmentStart;
  bg8seg  = bg16seg + 
          + (u32)_bg_rgbaSegmentRomEnd - (u32)_bg_rgbaSegmentRomStart;
  
  loadSegment(bg16seg, bg8seg);
  menuInit();
  actionInit();
  rsptime = rdptime = 0;
  
  while(1){

    /*------ Start to read the controller. ------*/
    osContStartReadData(&siMessageQ);
    
    /*------ Wait for the retrace. ------*/
    osRecvMesg(&retraceMessageQ, NULL, OS_MESG_BLOCK);

    /*------ Setting the Bg structure. ------*/
    setBg();
    
    /*------ Setting the Object structure. ------*/
    setObject();
    
    /*------ Create the Gfx list. ------*/
    gtop = gp = glist[draw_frame];

    /*------ RSP initialization setting. ------*/
    gSPSegment(gp ++, 0, 0x0);
    gSPSegment(gp ++, STATIC_SEGMENT, _codeSegmentEnd);
    if (aMenu[MENU_BG_TX_FORMAT]){
      gSPSegment(gp ++, BG_SEGMENT, bg8seg);
    }
    gDPSetColorImage(gp ++, G_IM_FMT_RGBA,
		     G_IM_SIZ_16b, SCREEN_WD, system_cfb[draw_frame]);
    gSPDisplayList(gp ++, rdpInit_dl);
    gSPDisplayList(gp ++, clearCfb_dl);
    gSPDisplayList(gp ++, spriteInit_dl);

    /*------ Bg output. ------*/
    if (aMenu[MENU_BG_TX_FORMAT]){
      gDPSetTextureLUT(gp ++, G_TT_RGBA16);
      gSPObjLoadTxtr(gp ++, &objBgTLUT);
    }
    if (aMenu[MENU_BG_SCALABLE] == 0){

      /* Unscalable BG plane */
      gDPSetRenderMode(gp ++, G_RM_NOOP, G_RM_NOOP2);
      gDPSetCycleType(gp ++, G_CYC_COPY);
      gSPBgRectCopy(gp ++, &objBg);

    } else {
      /* Scalable BG plane */
      gDPSetRenderMode(gp ++, G_RM_SPRITE, G_RM_SPRITE2);
      gDPSetCycleType(gp ++, G_CYC_1CYCLE);
      gDPSetTextureFilter(gp ++,
			  RMmodeTable[aMenu[MENU_RENDERMODE]].txtrFilter);
      if (aMenu[MENU_BG_SCALABLE] == 1){
	/* Emulated by CPU */
	guS2DEmuSetScissor(0, 0, SCREEN_WD, SCREEN_HT, 
			   (RMmodeTable[aMenu[MENU_RENDERMODE]].txtrFilter
			    == G_TF_BILERP));
	guS2DEmuBgRect1Cyc(&gp, &objBg);
      } else {
	/* GBI command */
	gSPObjRenderMode(gp ++, RMmodeTable[aMenu[MENU_RENDERMODE]].objRMode);
	gSPBgRect1Cyc(gp ++, &objBg);
      }
    }
    gDPPipeSync(gp ++);

    /*------ Setting the Render Mode. ------*/
    objRM = RMmodeTable[aMenu[MENU_RENDERMODE]].objRMode;
    if (RMmodeTable[aMenu[MENU_RENDERMODE]].cycleType != G_CYC_COPY){
      if (!aMenu[MENU_RENDERMODE_2]){
	/* Opaque */
	if (RMmodeTable[aMenu[MENU_RENDERMODE]].antiAlias){
	  gDPSetRenderMode(gp ++, G_RM_AA_SPRITE, G_RM_AA_SPRITE2);
	} else {
	  gDPSetRenderMode(gp ++, G_RM_SPRITE, G_RM_SPRITE2);
	}
      } else {
	/* Translucent */
	if (RMmodeTable[aMenu[MENU_RENDERMODE]].antiAlias){
	  gDPSetRenderMode(gp ++, G_RM_AA_XLU_SPRITE, G_RM_AA_XLU_SPRITE2);
	} else {
	  gDPSetRenderMode(gp ++, G_RM_XLU_SPRITE, G_RM_XLU_SPRITE2);
	}
	gDPSetCombineMode(gp ++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM);
	gDPSetPrimColor(gp ++, 0, 0, 255, 255, 255, 128);
      }
    }
    
    /*------ Setting the Texture Filter and CycleType. ------*/
    gDPSetTextureFilter(gp ++, RMmodeTable[aMenu[MENU_RENDERMODE]].txtrFilter);
    gDPSetCycleType    (gp ++, RMmodeTable[aMenu[MENU_RENDERMODE]].cycleType );
    
    /*------ Setting the Texture Window. ------*/
    if (aMenu[MENU_OBJ_TX_WINDOW]) objRM |= G_OBJRM_NOTXCLAMP;

    /*------ Setting the Shrink. ------*/
    objRM |= ShrinkTable[aMenu[MENU_OBJ_SHRINK]];
    
    /*------ Setting the Object Render Mode. ------*/    
    gSPObjRenderMode(gp ++, objRM);
    
    /*------ Load setting of the Texture. -----*/
    if (!aMenu[MENU_OBJ_TX_TYPE]){
      gDPSetTextureLUT(gp ++, G_TT_NONE);
      gSPObjLoadTxtr(gp ++, (aMenu[MENU_OBJ_TX_LOAD_BY]
			     ? &objTxtrTile_RGBA16 : &objTxtrBlock_RGBA16));
    } else {
      gDPSetTextureLUT(gp ++, G_TT_RGBA16);
      gSPObjLoadTxtr(gp ++, (aMenu[MENU_OBJ_TX_LOAD_BY]
			     ? &objTxtrTile_CI4 : &objTxtrBlock_CI4));
      gSPObjLoadTxtr(gp ++, &objTLUT_CI4);
    }
    
    /*------ Output of Object:Rectangle1. ------*/
    gSPObjRectangle(gp ++, &(objRect[0]));

    if (RMmodeTable[aMenu[MENU_RENDERMODE]].cycleType != G_CYC_COPY){

      /*------ Output of Object:Rectangle2. ------*/
      gSPObjMatrix(gp ++, &(objMtx[0]));
      gSPObjSprite(gp ++, &(objRect[1]));

      /*------ Output of Object:Ball. ------*/      
      /* 
	 Ball is displayed by combining two sprite pieces.  Because of this, you need to change
	 the processing method by setting the Texture Filter.  

	 If the Texture Filter is PointSample, you don't have to specify SHRINKSIZE; but, If it
	 is Bilerp, it must be SHRINKSIZE_1.  When you specify SHRINKSIZE_1, the circumference
	 of Sprite for 0.5 texel is clamped.  The area excepted by this clamp becomes a part
	 that the Bilerp process gives no effect.     

	 Because you need to load the part of adjoining of Sprite twice in Bilerp, Ball draws
	 only for 64x63 texels.  It is important to understand the differences between
	 objBall[1] and objBall[2] well. 
      */
      if (!aMenu[MENU_RENDERMODE_2]){
	/* Draw one size larger to hide the joining part.  (Only opaque.)
	   It became unnecessary after S2DEX 1.05.   */
	/* objRM |= G_OBJRM_WIDEN; */
      }
      gDPPipeSync(gp ++);
      gDPSetTextureLUT(gp ++, G_TT_RGBA16);
      gSPObjLoadTxtr(gp ++, &objBallTLUT);
      if (RMmodeTable[aMenu[MENU_RENDERMODE]].txtrFilter == G_TF_POINT){
	gSPObjRenderMode(gp ++, objRM);
	gSPObjMatrix(gp ++, &(objMtx[2]));
	gSPObjLoadTxRectR(gp ++, &(objBall[0]));
	gSPObjLoadTxRectR(gp ++, &(objBall[1]));
	gSPObjMatrix(gp ++, &(objMtx[1]));
	gSPObjLoadTxSprite(gp ++, &(objBall[0]));
	gSPObjLoadTxSprite(gp ++, &(objBall[1]));
      } else {
	gSPObjRenderMode(gp ++, objRM|G_OBJRM_SHRINKSIZE_1);
	gSPObjMatrix(gp ++, &(objMtx[2]));
	gSPObjLoadTxRectR(gp ++, &(objBall[0]));
	gSPObjLoadTxRectR(gp ++, &(objBall[2]));
	gSPObjMatrix(gp ++, &(objMtx[1]));
	gSPObjLoadTxSprite(gp ++, &(objBall[0]));
	gSPObjLoadTxSprite(gp ++, &(objBall[2]));
      }
    }
    
    /*------ Output the processing meter. ------*/
    if (rsptime){
      gDPPipeSync(gp ++);
      gDPSetCycleType(gp ++, G_CYC_FILL);
      gDPSetRenderMode(gp ++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
      gDPSetFillColor(gp ++, (GPACK_RGBA5551(128,128,255,1) << 16 | 
			      GPACK_RGBA5551(128,128,255,1)));
      gDPFillRectangle(gp ++, 30, 201, 30+rsptime/100, 202);
      gDPFillRectangle(gp ++, 30, 205, 30+rdptime/100, 206);
      gDPSetFillColor(gp ++, (GPACK_RGBA5551(255,255,255,1) << 16 | 
			      GPACK_RGBA5551(255,255,255,1)));
      gDPFillRectangle(gp ++, 30,     200, 30,     207);
      gDPFillRectangle(gp ++, 30+166, 200, 30+166, 207);
    }
    gDPFullSync(gp ++);
    gSPEndDisplayList(gp ++);
    
    /*------ Execute the Gfx task. ------*/
    tlist.t.data_ptr = (u64 *)gtop;
    osWritebackDCache(gtop, ((u32)gp)-((u32)gtop));
    rspstart = osGetTime();
    osSpTaskStart(&tlist);
    
    /*------ Wait for the end. ------*/
    osRecvMesg(&rspMessageQ, NULL, OS_MESG_BLOCK);
    rsptime = OS_CYCLES_TO_NSEC(osGetTime() - rspstart) / 1000;

#ifdef	RSP_DEBUG
    /*------ The ASSERT process of the micro-code. ------*/
    if (ucCheckAssert()){
      ucDebugGfxLogPrint(&tlist);  	/* Output the process log of RSP, Gfx and DL. */
//	ucDebugRdpFifoPrint(&tlist); 	/* Output the RDP and fifo buffers.           */
//	ucDebugIMEMPrint(); 		/* Output IMEM.                     	      */
//      ucDebugDMEMPrint(); 		/* Output DMEM.                     	      */
      ucDebugAssertPrint();		/* Output Assert stop location, etc.          */
      ucDebugInfoPrint();		/* Output the work area for Debugging.        */
      while(1);
    }
#endif

#if 0
    /*------ Output the DEBUG information. ------*/
    if (Ac.pad[0].push & Z_TRIG){
      ucDebugRdpFifoPrint(&tlist); 	/* Output the RDP and fifo buffers.    */
      ucDebugInfoPrint();		/* Output the work area for Debugging. */
    }
#endif
    osRecvMesg(&rdpMessageQ, NULL, OS_MESG_BLOCK);
    rdptime = OS_CYCLES_TO_NSEC(osGetTime() - rspstart) / 1000;
    
    /* Switching the Frame. */
    osViSwapBuffer(system_cfb[draw_frame]);
    draw_frame ^= 1;

    /* Accept the controller data. */
    osRecvMesg(&siMessageQ, NULL, OS_MESG_BLOCK);
    osContGetReadData(contPad);
    
    /* The input process. */
    actionUpdate();
  }
}
コード例 #12
0
ファイル: boot.c プロジェクト: shlomnissan/ultra64demos
/*
 * This is the main routine of the app.
 */
static void
mainproc(void *arg)
{
#ifdef DEBUG
	int             i;
	char           *ap;
	u32            *argp;

	/*
	 * get arguments (options)
	 */
	argp = (u32 *) RAMROM_APP_WRITE_ADDR;
	for (i = 0; i < sizeof(argbuf) / 4; i++, argp++) {
		osEPiReadIo(handler, (u32) argp, &argbuf[i]);	/* Assume no DMA */
	}
	((char *) argbuf)[sizeof(argbuf)-1] = '\0';

	/*
	 * Parse the options 
	 */
	ap = (char *) argbuf;
	position_str = (char *) 0;
	while (*ap != '\0') {
		while (*ap == ' ')
			ap++;
		if (*ap == '-' && *(ap + 1) == 'r') {
			rdp_flag = 1;
			ap += 2;
		} else if (*ap == '-' && *(ap + 1) == 'i') {
			ap += 2;
			position_str = ap;
			break;			/* -i must be last argument */
		} else ap++;
	}
#endif

	/*
	 * Setup the message queues
	 */
	osCreateMesgQueue(&dmaMessageQ, &dmaMessageBuf, 1);

	osCreateMesgQueue(&rdpMessageQ, &rdpMessageBuf, 1);
	osSetEventMesg(OS_EVENT_DP, &rdpMessageQ, NULL);

	osCreateMesgQueue(&retraceMessageQ, &retraceMessageBuf, 1);
	osViSetEvent(&retraceMessageQ, NULL, 1);

	/*
	 * Stick the static segment right after the code/data segment
	 */
	staticSegment = _zbufferSegmentEnd;

	dmaIOMessageBuf.hdr.pri      = OS_MESG_PRI_NORMAL;
	dmaIOMessageBuf.hdr.retQueue = &dmaMessageQ;
	dmaIOMessageBuf.dramAddr     = staticSegment;
	dmaIOMessageBuf.devAddr      = (u32)_staticSegmentRomStart;
	dmaIOMessageBuf.size         = (u32)_staticSegmentRomEnd-(u32)_staticSegmentRomStart;

	osEPiStartDma(handler, &dmaIOMessageBuf, OS_READ);

	/*
	 * Wait for DMA to finish
	 */
	(void) osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);

	/*
	 * Stick the texture segment right after the static segment
	 */
	textureSegment = staticSegment + 
		(u32) _staticSegmentRomEnd - (u32) _staticSegmentRomStart;

	dmaIOMessageBuf.hdr.pri      = OS_MESG_PRI_NORMAL;
	dmaIOMessageBuf.hdr.retQueue = &dmaMessageQ;
	dmaIOMessageBuf.dramAddr     = textureSegment;
	dmaIOMessageBuf.devAddr      = (u32)_textureSegmentRomStart;
	dmaIOMessageBuf.size         = (u32)_textureSegmentRomEnd-(u32)_textureSegmentRomStart;

	osEPiStartDma(handler, &dmaIOMessageBuf, OS_READ);

	/*
	 * Wait for DMA to finish
	 */
	(void) osRecvMesg(&dmaMessageQ, NULL, OS_MESG_BLOCK);

	initControllers(MAXCONTROLLERS);

	game();
}
コード例 #13
0
ファイル: controller.c プロジェクト: shlomnissan/ultra64demos
void 
readController(int controllerSlot)
{
    static u16		button, lastbutton;
    int			stick_x, stick_y;
    
    if (controllerSlot < 0) {
	osSyncPrintf("no controller connection\n");
	return;
    }

    osContStartReadData(&controllerMsgQ);
    (void)osRecvMesg(&controllerMsgQ, NULL, OS_MESG_BLOCK);
    osContGetReadData(controllerdata);

    button = controllerdata[controllerSlot].button;
    stick_x = controllerdata[controllerSlot].stick_x;
    stick_y = controllerdata[controllerSlot].stick_y;
    
    if ((stick_x >= -5 && stick_x <= 5) &&
	(stick_y >= -5 && stick_y <= 5)) {
	stop_walk_cycle();
    } else {
	start_walk_cycle();
	p1_dx = (float) ((float)stick_x/90.0);
	p1_dz = (float) ((float)stick_y/90.0);
	p1_tx = (float) ((float)stick_x/90.0);
	p1_tz = (float) -((float)stick_y/90.0);
    }

    if (button & CONT_A && !(lastbutton & CONT_A)) {
	which_char++;
	which_char = which_char % 4;
    }
	    
    if (button & CONT_B && !(lastbutton & CONT_B)) {
	do_turbo_z ^= 0x01;
    }
	    
    if (button & CONT_G && !(lastbutton & CONT_G)) {
	if (do_view_rotate)
	    do_view_rotate = FALSE;
	else
	    do_view_rotate = TRUE;
    }
	    
    if (button & CONT_START) {
	resetControllers();
    }
	    
    if (button & CONT_UP) {
	view_dist -= 2.0;
    }
	    
    if (button & CONT_DOWN) {
	view_dist += 2.0;
    }

    if ((button & CONT_LEFT) && !(lastbutton & CONT_LEFT)) {
    }

    if ((button & CONT_RIGHT) && !(lastbutton & CONT_RIGHT)) {
    }

	    
    if (button & CONT_L) {
	view_rotate_inc = -(6.28/1200.0);
    }
	    
    if (button & CONT_R) {
	view_rotate_inc = (6.28/1200.0);
    }
	    
    if ((button & CONT_E) && !(lastbutton & CONT_E)) {
    }
	    
    if ((button & CONT_D) && !(lastbutton & CONT_D)) {
	use_fifo_ucode ^= TRUE;
    }
	    
    if ((button & CONT_C) && !(lastbutton & CONT_C)) {
	do_left_punch = TRUE;
    }
	    
    if ((button & CONT_F) && !(lastbutton & CONT_F)) {
	do_right_punch = TRUE;
    }
	    
    lastbutton = button;
}