/* main loop */
static void mainLoop(void)
{
    ARUint8         *dataPtr;
    ARMarkerInfo    *marker_info;
    int             marker_num;
	float curPaddlePos[3];
    int             i;
    double          err;
    double			angle;

	err=0.;
    /* grab a video frame */
    if( (dataPtr = (ARUint8 *)arVideoGetImage()) == NULL ) {
        arUtilSleep(2); 
        return;
    }
	
    if( count == 0 ) arUtilTimerReset();  
    count++;
   
	/* detect the markers in the video frame */
    if( arDetectMarkerLite(dataPtr, thresh, &marker_info, &marker_num) < 0 ) {
        cleanup();
        exit(0);
    }

    argDrawMode2D();
    if( !arDebug ) {
        argDispImage( dataPtr, 0,0 );
    }
    else {
        argDispImage( dataPtr, 1, 1 );
        if( arImageProcMode == AR_IMAGE_PROC_IN_HALF )
            argDispHalfImage( arImage, 0, 0 );
        else
            argDispImage( arImage, 0, 0);

        glColor3f( 1.0, 0.0, 0.0 );
        glLineWidth( 1.0 );
        for( i = 0; i < marker_num; i++ ) {
            argDrawSquare( marker_info[i].vertex, 0, 0 );
        }
        glLineWidth( 1.0 );
    }

    arVideoCapNext();

	for( i = 0; i < marker_num; i++ ) 
		marker_flag[i] = 0;
  
	/* get the paddle position */
	paddleGetTrans(paddleInfo, marker_info, marker_flag, 
				marker_num, &cparam);
	/* draw the 3D models */
	glClearDepth( 1.0 );
	glClear(GL_DEPTH_BUFFER_BIT);


	/* get the translation from the multimarker pattern */
	if( (err=arMultiGetTransMat(marker_info, marker_num, config)) < 0 ) {
        argSwapBuffers();
        return;
    }	
	
	//    printf("err = %f\n", err);
    if(err > 100.0 ) {
        argSwapBuffers();
        return;
    }
	
	//draw a red ground grid
	drawGroundGrid( config->trans, 15, 150.0, 110.0, 0.0);

	/* find the paddle position relative to the base */
	if (paddleInfo->active)
		findPaddlePosition(curPaddlePos,paddleInfo->trans,config->trans);

	/* checking for paddle gesture */
	if( paddleInfo->active) 
	  {
	    int findItem=-1;
	    if (myPaddleItem.item!=-1)
	      {

		  if( check_incline(paddleInfo->trans, config->trans, &angle) ) {
		      myPaddleItem.x += 2.0 * cos(angle);
		      myPaddleItem.y += 2.0 * sin(angle);
		      if( myPaddleItem.x*myPaddleItem.x + 
			  myPaddleItem.y*myPaddleItem.y > 900.0 ) {
			  myPaddleItem.x -= 2.0 * cos(angle);
			  myPaddleItem.y -= 2.0 * sin(angle);
			  myListItem.item[myPaddleItem.item].onpaddle=0;		     
			  myListItem.item[myPaddleItem.item].pos[0]=curPaddlePos[0]; 
			  myListItem.item[myPaddleItem.item].pos[1]=curPaddlePos[1];  
			  myPaddleItem.item = -1;
			}
		  }
	      }
	    else
	      {
		if ((findItem=check_pickup(paddleInfo->trans, config->trans,&myListItem, &angle))!=-1)  {
		    
		    myPaddleItem.item=findItem;
		    myPaddleItem.x =0.0;
		    myPaddleItem.y =0.0;
		    myPaddleItem.angle = 0.0;
		    myListItem.item[myPaddleItem.item].onpaddle=1;
		  }
	      }
	  }

	/* draw the item */
	drawItems(config->trans,&myListItem);

	/* draw the paddle */
	if( paddleInfo->active ){ 
	  draw_paddle(paddleInfo,&myPaddleItem);
	}
	
	argSwapBuffers();
}
示例#2
0
/* The main game loop */
static void do_game(game_t *p_game)
{
  uint8_t exit=FALSE;

  while(!exit)
    {
      uint16_t input = get_input(p_game);
      uint16_t fire;
      int i;

      exit = input & FE_EVENT_EXIT;
      fire = input & FE_EVENT_SELECT;

      /* Move the paddle (according to input) */
      update_paddle(&p_game->paddle, input & FE_EVENT_LEFT ? 4:0, input & FE_EVENT_RIGHT ? 4:0);

      /* Handle the ball(s) */
      p_game->free_ball = -1;
      for (i=0; i<MAX_BALLS; i++)
	{
	  /* Unused balls are skipped */
	  if (!(p_game->p_balls[i].state & BALL_STATE_ACTIVE))
	    {
	      draw_ball(&p_game->p_balls[i]);
	      p_game->free_ball = i;
	      continue;
	    }

	  /* The player is holding the ball */
	  if (p_game->p_balls[i].state & BALL_STATE_HOLDING)
	    {
	      p_game->p_balls[i].lastx = p_game->p_balls[i].x;
	      p_game->p_balls[i].x += p_game->paddle.x-p_game->paddle.lastx;

	      if (fire)
		{
		  /* The player relases the ball. The following will
		   * clear the HOLDING-bit. It will also shoot the
		   * ball away upwards.
		   */
		  p_game->p_balls[i].dx = 1;
		  p_game->p_balls[i].state &= (0xff ^ BALL_STATE_HOLDING);
		  bounce_ball_paddle(p_game, &p_game->p_balls[i]);
		}
	    }
	  else if (paddle_ball_collide(&p_game->paddle, &p_game->p_balls[i]))
	    {
	      /* Hold the ball if the pad is sticky */
	      if (p_game->paddle.type & SPECIAL_STICKY)
		{
		  p_game->p_balls[i].dy = 0;
		  p_game->p_balls[i].dx = 0;
		  p_game->p_balls[i].state |= BALL_STATE_HOLDING;
		  p_game->paddle.type--; /* Sticky for maximum 3 rounds */
		}
	      else
		bounce_ball_paddle(p_game, &p_game->p_balls[i]);
	    }
	  /* Check collisions against blocks */
	  block_ball_collide(p_game, &p_game->p_balls[i]);

	  draw_ball(&p_game->p_balls[i]);

	  /* Update the ball (and check if it moves out of the playfield) */
	  if (update_ball(p_game, &p_game->p_balls[i]))
	    {
	      /* Ball is out of bounds - Remove it */
	      init_ball(&p_game->p_balls[i], 0, 0, 0);
	      p_game->nr_balls--;
	    }
	}
      /* Handle the specials */
      p_game->free_special = -1;
      for (i=0; i<MAX_SPECIALS; i++)
	{
	  int res;

	  /* Always draw the specials for timing-reasons */
	  draw_special(&p_game->p_specials[i]);
	  /* Inactive special - continue */
	  if (!p_game->p_specials[i].type)
	    {
	      p_game->free_special = i;
	      continue;
	    }

	  /* This moves the special and also checks if it collides with the paddle */
	  res = update_special(p_game, &p_game->p_specials[i]);
	  switch(res)
	    {
	    case 1: /* Player took the special */
	      switch(p_game->p_specials[i].type)
		{
		case SPECIAL_EXTRA_BALL:
		  if (p_game->free_ball != -1) /* Check if there is free space for the ball */
		    {
		      p_game->nr_balls++;
		      init_ball(&p_game->p_balls[p_game->free_ball], p_game->paddle.x+PADDLE_WIDTH/2,
				PADDLE_Y-PADDLE_HEIGHT, BALL_STATE_ACTIVE);
		    }
		  break;
		case SPECIAL_LONG_PADDLE:
		  p_game->paddle.width = PADDLE_LONG_WIDTH;
		  break;
		case SPECIAL_SHORT_PADDLE:
		  p_game->paddle.width = PADDLE_SHORT_WIDTH;
		  break;
		case SPECIAL_EXTRA_LIFE:
		  if (p_game->lives < MAX_LIVES)
		    {
		      p_game->lives++;
		      draw_lives(p_game);
		    }
		  break;
		case SPECIAL_STICKY:
		  /*
		   * For the sticky and destroyers, we use the bits
		   * from the flag and downwards as counters.
		   *
		   * i.e: SPECIAL_STICKY is the third bit, which means
		   * that type becomes 0b00000111. type is then
		   * lowered when the ball hits the paddle and after
		   * zeroing the lower bits, the SPECIAL_STICKY bit is
		   * finally cleared. This gives a maximum of three
		   * sticky rounds.
		   *
		   * These two only adds 30 bytes to the binary :-)
		   */
		  p_game->paddle.type = (SPECIAL_STICKY | (SPECIAL_STICKY-1));
		  break;
		case SPECIAL_DESTROYER:
		  p_game->p_balls[0].state |= (BALL_STATE_DESTROYER | (BALL_STATE_DESTROYER-1));
		  break;
		case SPECIAL_FLOOR:
		  p_game->state |= (SPECIAL_FLOOR | 2); /* Three times */
		  fe_fill_area(0, SCREEN_HEIGHT-FLOOR_HEIGHT, SCREEN_WIDTH, FLOOR_HEIGHT);
		  break;
		}
	      /* Fall through */
	    case -1:
	      /* Remove the special */
	      p_game->nr_specials--;
	      fe_clear_area(p_game->p_specials[i].x, p_game->p_specials[i].y-1, SPECIAL_WIDTH, SPECIAL_HEIGHT+1);
	      p_game->p_specials[i].type = SPECIAL_NONE;
	      break;
	    }
	}

      /* No balls left in play */
      if (!p_game->nr_balls)
	{
	  if (--p_game->lives == 0)
	    exit = TRUE; /* No lives left! */
	  else
	    {
	      /* Restart the game */
	      p_game->nr_balls = 1;
	      draw_screen(p_game);
	      init_paddle(&p_game->paddle, SPECIAL_NONE, SCREEN_WIDTH/2-PADDLE_WIDTH/2);
	      init_ball(&p_game->p_balls[0], p_game->paddle.x+p_game->paddle.width/2,
			PADDLE_Y-PADDLE_HEIGHT, BALL_STATE_HOLDING | BALL_STATE_ACTIVE);
	    }
	}
      /* No blocks left to remove */
      if (!p_game->nr_blocks)
	{
	  fe_sleep(LEVEL_SLEEP_PERIOD);

	  if (handle_level_finished(p_game) < 0)
	    exit = TRUE; /* Last level */
	}

      draw_paddle(&p_game->paddle);
      /* Sleep for a short while. */
#if !defined(TARGET_REX)
      fe_sleep(SLEEP_PERIOD);
#endif /* TARGET_REX */
    }
}