Beispiel #1
0
static void move_mouse(void)
{
    if ((MOUINFO->xpos != MSCURSOR->xcord) ||
        (MOUINFO->ypos != MSCURSOR->ycord)) {
        int check  = MOUINFO->docheck;
        int dospec = SPECIALMODE && MSCURSOR->displayed;
        MOUINFO->docheck = FALSE;
        if (dospec) draw_special();
        GrMoveCursor(MSCURSOR, MOUINFO->xpos, MOUINFO->ypos);
        if (dospec) draw_special();
        MOUINFO->docheck = check;
    }
}
Beispiel #2
0
static void erase_mouse(void)
{
    int check = MOUINFO->docheck;
    MOUINFO->docheck = FALSE;
    if(SPECIALMODE) draw_special();
    GrEraseCursor(MSCURSOR);
    MOUINFO->docheck = check;
}
Beispiel #3
0
static void draw_mouse(void)
{
    int check = MOUINFO->docheck;
    MOUINFO->docheck = FALSE;
    GrDisplayCursor(MSCURSOR);
    if(SPECIALMODE) draw_special();
    MOUINFO->docheck = check;
}
Beispiel #4
0
/* Animate special objects */
void animate_specials (void) {
    struct dllist *list = special_list,*next;
    while (list) {
        struct SpecialObj *obj=list->data;

        /* Check for collisions */
        if(obj->hitship)
            ship_hit_special (obj);
        if(obj->hitprojectile)
            projectile_hit_special(obj);

        /* Animate */
        if(obj->animate)
            obj->animate(obj);
        if (obj->timer > 0)
            obj->timer--;

        /* Draw the object on all viewports */
        draw_special (obj);

        /* Check if the object has expired.
         * If life < 0, the object has no time limit */
        next = list->next;
        if(obj->life > 0) obj->life--;
        else if (obj->life == 0) {
            if(obj->destroy)
                obj->destroy(obj);
            free (obj);
            if(list==special_list)
                special_list=dllist_remove(list);
            else
                dllist_remove(list);
        }
        list = next;
    }
}
Beispiel #5
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 */
    }
}