Exemplo n.º 1
0
void panelbar_trigger_sprite(struct widget *self,s32 type,union trigparam *param) {
  bool force = 0;
  struct widget *boundwidget;
  int s;

  switch (type) {

  case PG_TRIGGER_ENTER:
    DATA->over = 1;
    break;

  case PG_TRIGGER_LEAVE:
    /* If we're dragging, the mouse didn't REALLY leave */
    if (DATA->on) return;
    DATA->over=0;
    break;

  case PG_TRIGGER_DOWN:
    if (param->mouse.chbtn != 1) return;

    /* If we're bound to another widget (we should be) save its current size */
    if (!iserror(rdhandle((void**)&boundwidget,PG_TYPE_WIDGET,self->owner,
			  DATA->bindto)) && boundwidget) {
      DATA->oldsize = widget_get(boundwidget,PG_WP_SIZE);

      /* If we're not rolled up, save this as the unrolled split */
      if (DATA->oldsize > DATA->minimum)
	DATA->unrolled = DATA->oldsize;
    }

    DATA->on = 1;
    DATA->x = param->mouse.x;
    DATA->y = param->mouse.y;
    DATA->draglen = 0;
     
    /* Update the screen now, so we have an up-to-date picture
       of the panelbar stored in DATA->s */
    themeify_panelbar(self,1);

    VID(sprite_hideall) ();   /* This line combined with the zero flag on */
    update(NULL,0);             /*  the next gets a clean spriteless grab */

    /* In case there was no release trigger (bug in input driver) */
    if (DATA->s) {
       free_sprite(DATA->s);
       DATA->s = NULL;
    }
    if (DATA->sbit) {
       VID(bitmap_free) (DATA->sbit);
       DATA->sbit = NULL;
    }
     
    /* Allocate the new sprite */
    if(iserror(new_sprite(&DATA->s,self->dt,DATA->panelbar->r.w,DATA->panelbar->r.h))) {
       DATA->s = NULL;
       return;
    }
    if (iserror(VID(bitmap_new) (&DATA->sbit,DATA->panelbar->r.w,DATA->panelbar->r.h,vid->bpp))) {
       free_sprite(DATA->s);
       DATA->s = NULL;
       DATA->sbit = NULL;
       return;
    }
    DATA->s->bitmap = &DATA->sbit;
    
    /* Grab a bitmap of the panelbar to use as the sprite */
    VID(blit) (DATA->sbit,0,0,DATA->panelbar->r.w,DATA->panelbar->r.h,
	       self->dt->display,DATA->s->x = DATA->panelbar->r.x,DATA->s->y = DATA->panelbar->r.y,
	       PG_LGOP_NONE);

    /* Clip the sprite to the travel allowed by boundwidget's parent */
    if (!iserror(rdhandle((void**)&boundwidget,PG_TYPE_WIDGET,self->owner,
			  DATA->bindto)) && boundwidget) {
      DATA->s->clip_to = boundwidget->in;
    }

    return;

  case PG_TRIGGER_UP:
  case PG_TRIGGER_RELEASE:
    if (!DATA->on) return;
    if (!(param->mouse.chbtn & 1)) return;

    if (!iserror(rdhandle((void**)&boundwidget,PG_TYPE_WIDGET,self->owner,
			  DATA->bindto)) && boundwidget) {

      s = panel_calcsplit(self,param->mouse.x,param->mouse.y,
			  widget_get(boundwidget,PG_WP_SIDE));
      
      if (DATA->draglen < MINDRAGLEN) {
	/* This was a click, not a drag */
	DATA->over = 0;
	
	widget_set(boundwidget,PG_WP_SIZEMODE,PG_SZMODE_PIXEL);
	if (DATA->oldsize > DATA->minimum)
	  /* Roll up the panel */
	  widget_set(boundwidget,PG_WP_SIZE,DATA->minimum);
	else
	  /* Unroll the panel */
	  widget_set(boundwidget,PG_WP_SIZE,DATA->unrolled);
      }
      else {
	s += panel_effective_split(boundwidget->in);

	/* Save this as the new unrolled split,
	 * Unless the user manually rolled up the panel */
	if ((s-DATA->minimum) > MAXROLLUP) 
	  DATA->unrolled = s;
	else
	  s = DATA->minimum;
	
	widget_set(boundwidget,PG_WP_SIZEMODE,PG_SZMODE_PIXEL);
	widget_set(boundwidget,PG_WP_SIZE,s);

	DATA->over = 1;
      }
    }

    VID(bitmap_free) (DATA->sbit);
    free_sprite(DATA->s);
    DATA->s = NULL;
    DATA->sbit = NULL;
    force = 1;           /* Definitely draw the new position */
     
    DATA->on = 0;
    break;

  case PG_TRIGGER_MOVE:
  case PG_TRIGGER_DRAG:
    if (!DATA->on) return;
     /* Ok, button 1 is dragging through our widget... */
     
    if (panel_throttle(self))
      return;
     
     /* Race condition prevention?
      * Without this, sometimes segfaults because DATA->s is NULL.
      * Possibly events_pending() triggered another event? */
     if (!DATA->s) return;
      
     /* Determine where to blit the bar to... */
     switch (self->in->flags & (~SIDEMASK)) {
     case PG_S_TOP:
     case PG_S_BOTTOM:
       DATA->s->x = DATA->panelbar->r.x;
       DATA->draglen += abs(param->mouse.y - DATA->y + DATA->panelbar->r.y - DATA->s->y);
       DATA->s->y = param->mouse.y - DATA->y + DATA->panelbar->r.y;
       break;
     case PG_S_LEFT:
     case PG_S_RIGHT:
       DATA->s->y = DATA->panelbar->r.y;
       DATA->draglen += abs(param->mouse.x - DATA->x + DATA->panelbar->r.x - DATA->s->x);
       DATA->s->x = param->mouse.x - DATA->x + DATA->panelbar->r.x;
       break;
     }

    /* Reposition sprite */
    VID(sprite_update) (DATA->s);
    return;
  }

  themeify_panelbar(self,force);
}
Exemplo n.º 2
0
// Essa funcao eh executada apenas uma vez, no final, te dando a chance
// de liberar a memoria das variaveis alocadas no jogo
void fim()
{
	free_sprite(enterprise);
	free_sprite(stars);
	free_sprite(dots);
}
Exemplo n.º 3
0
/*
 * Main function to run one tick of the game
 */
int run_game()
{
	cli();

	/* Movement phase */
	if(game_state == 1)
	{
		/* Move the reticule based on readings from the rotary encoder */
		int16_t newRX = (playersX[current_player] + (RETICULE_DISTANCE * ml_cos(position))/100);
		int16_t newRY = (playersY[current_player] + (RETICULE_DISTANCE * ml_sin(position))/100);
		
		rectangle reticuleOld = {reticuleX - reticule_SPR->width / 2, reticuleX + reticule_SPR->width / 2 - 1, reticuleY - reticule_SPR->height / 2, reticuleY + reticule_SPR->height / 2 - 1};
		draw_background(level_map, SILVER, reticuleOld, HEIGHT_NO_UI, WIDTH);

		//fill_rectangle(reticuleOld, BLACK);
		if(newRX >= 0 && newRX < WIDTH && newRY >= 0 && newRY < HEIGHT)
			fill_sprite(reticule_SPR, newRX, newRY, HEIGHT_NO_UI, WIDTH);
	
		reticuleX = newRX;
		reticuleY = newRY;

		/* Read firing input */
		if (get_switch_long(_BV(SWC)))
		{
			game_state = 3;
			return 0;
		}		

		/* Read directional input.*/
		if (get_switch_rpt(_BV(SWE))) 
		{
			direction = 4;
			free_sprite(player_SPR);
			player_SPR = botright(current_player);
		}
		else if (get_switch_rpt(_BV(SWW)))
		{
			direction = -4;
			free_sprite(player_SPR);
			player_SPR = botleft(current_player);
		}
		else
		{
			direction = 0;
			return 0;
		}

		/* Move the player */
		int16_t newX = playersX[current_player] + direction;
		int16_t newY = ml_min(level_map[newX - PLAYER_WIDTH], level_map[newX + PLAYER_WIDTH - 1]) - PLAYER_HEIGHT;

		int8_t i;
		int8_t player_collision = 0;
		for(i = 0; i < players; i++)
		{
			if(players_HP[i] != 0 && i != current_player && newX >= playersX[i] - PLAYER_WIDTH && newX <= playersX[i] + PLAYER_WIDTH - 1)
			{
				player_collision = 1;
				break;
			}				
		}

		/* Cancel movement if trying to climb to high or off the sides of the screen */
		if(player_collision || playersY[current_player] - newY > MAX_CLIMB_HEIGHT || newX <= PLAYER_WIDTH || newX + PLAYER_WIDTH > WIDTH)
		{
			/* DEBUGGING prints: */
			//display_string_xy("Error\n", 10, 10);
			//ml_printf("Cannot move there... (%u,%u) to (%u,%u)", playersX[0], playersY[0], newX, newY);
			return 0;
		}
		
		rectangle playerOld = {playersX[current_player] - PLAYER_WIDTH, playersX[current_player] + PLAYER_WIDTH - 1, playersY[current_player] - PLAYER_HEIGHT, playersY[current_player] + PLAYER_HEIGHT - 1};

		fill_rectangle(playerOld, BLACK);
		fill_sprite(player_SPR, newX, newY, HEIGHT_NO_UI, WIDTH);
		
		playersX[current_player] = newX;
		playersY[current_player] = newY;
	}
	/* Projectile phase (missile in the air) */
	else if(game_state == 2)
	{
		/* Find the new position of the projectile */
		int16_t newX = projectileX + proVelX/1000;
		int16_t newY = projectileY + proVelY/1000;
		
		rectangle projectileOld = {projectileX, projectileX, projectileY, projectileY};
		fill_rectangle(projectileOld, BLACK);

		/* End turn if projectile goes off the sides of the level */
		if(newX < 0 || newX > WIDTH)
		{
			start_turn();
			return 0;
		}
		
		/* If the new position is in the ground, EXPLODE!
		 * (Also, if off the bottom of the level) */
		if(newY >= level_map[newX] || newY > HEIGHT_NO_UI)
		{
			int i;
			for(i = -EXPLOSION_RADIUS; i <= EXPLOSION_RADIUS; i++)
			{
				/* Make sure that terrain is on screen */
				if(newX + i >= 0 && newX + i < WIDTH)
				{
					uint16_t new_ground_level = newY + ml_sqrt(EXPLOSION_RADIUS * EXPLOSION_RADIUS - i * i);
					if(new_ground_level >= HEIGHT_NO_UI)
						level_map[newX + i] = HEIGHT_NO_UI - 1; //Clamp to bottom of level
					else if(new_ground_level > level_map[newX + i]) //Don't raise the ground level!
						level_map[newX + i] = new_ground_level; 
				}
			}

			draw_level(level_map, SILVER, newX - EXPLOSION_RADIUS, newX + EXPLOSION_RADIUS);

			/* Check players for damage + redraw them */
			for(i = 0; i < players; i++)
			{
				int16_t deltaX = playersX[i] - newX;
				int16_t deltaY = playersY[i] - newY;
				int16_t distance = ml_sqrt(deltaX * deltaX + deltaY * deltaY);
				if(distance < BLAST_RADIUS)
				{
					int16_t damage = ml_clamp(0, players_HP[i], MAX_EXPLOSION_DAMAGE - (distance * MAX_EXPLOSION_DAMAGE / BLAST_RADIUS));
					players_HP[i] -= damage;
				}

				rectangle playerOld = {playersX[i] - PLAYER_WIDTH, playersX[i] + PLAYER_WIDTH - 1, playersY[i] - PLAYER_HEIGHT, playersY[i] + PLAYER_HEIGHT - 1};
				fill_rectangle(playerOld, BLACK);

				/* If the player is still alive, redraw them */
				if(players_HP[i] != 0)
				{
					free_sprite(player_SPR);
					player_SPR = botleft(i);
					playersY[i] = ml_min(level_map[playersX[i] - PLAYER_WIDTH], level_map[playersX[i] + PLAYER_WIDTH - 1]) - PLAYER_HEIGHT;
					fill_sprite(player_SPR, playersX[i], playersY[i], HEIGHT_NO_UI, WIDTH);
				}
			}

			start_turn();
			return 0;
		}	

		rectangle projectileNew = {newX, newX, newY, newY};
		
		/* Continue turn if off top of level, but only draw if projectile onscreen */
		if(newY >= 0)
		{
			fill_rectangle(projectileNew, RED);
		}

		projectileX = newX;
		projectileY = newY;		

		/* Apply gravity and wind */
		proVelY += 500;
		proVelX += (wind_velocity - 10) * 50;
	}
	/* Charging phase */
	else if(game_state == 3)
	{
		/* Increase the launch speed while the fire button is held */
		if (get_switch_state(_BV(SWC)))
		{
			launch_speed++;
			rectangle bar = {POWER_BAR_START, POWER_BAR_START + launch_speed, 231, 236};
			fill_rectangle(bar, WHITE);

			/* Fire once max power is reached */
			if(launch_speed == 100)
				fire_projectile();
		}
		else
		{
			fire_projectile();
		}
	}	
	/* Menu phase */
	else if(game_state == 4)
	{
		if (get_switch_press(_BV(SWE)))
		{
			if(players == 4)
				players = 2;
			else
				players++;
		}
		else if (get_switch_press(_BV(SWW)))
		{
			if(players == 2)
				players = 4;
			else
				players--;
		}

		ml_printf_at("< %u Players >", 5, 115, players);
		
		if (get_switch_long(_BV(SWC)))
		{
			start_game();
		}
	}
	/* End game phase */
	else if(game_state == 5)
	{
		if (get_switch_long(_BV(SWC)))
		{
			start_menu();
		}
	}

	sei();
	
	return 0;
}
Exemplo n.º 4
0
/* Free the sprites for the font */
void font_quit() {
	for (int i = 0; i < N_SEGMENTS; i++) {
		free_sprite(segments[i]);
	}
}
Exemplo n.º 5
0
/*
 * Checks to see if there are enough alive players to continue the game
 * If so, control switches to the next player
 */
void start_turn()
{
	/* Update the HP UI */
	draw_HP_UI();

	/* Reset the power bar */
	launch_speed = 0;
	fill_rectangle(power_empty, BLACK);

	/* If only one player remains, declare them winner. */
	uint8_t i;
	uint8_t player_left; //Record last player left (meaningless if more than 1 survivor)
	uint8_t players_alive = 0;
	for(i = 0; i < players; i++)
	{
		if(players_HP[i] != 0)
		{
			players_alive++;
			player_left = i;
		}
	}
	if(players_alive == 1)
	{
		switch(player_left)
		{
			case 0:
				display_color(BLUE, BLACK);
				ml_printf_at("To the victor, the spoils! BLUE WINS!", 5, 20);
				break;
			case 1:
				display_color(RED, BLACK);
				ml_printf_at("And the win goes to RED! Congratulations!", 5, 20);
				break;
			case 2:
				display_color(YELLOW, BLACK);
				ml_printf_at("Who's the best? YELLOW's the best!", 5, 20);
				break;
			default:
				display_color(GREEN, BLACK);
				ml_printf_at("Looks like the others are GREEN with envy! (GREEN WINS)", 5, 20);
				break;
		}

		end_game();
		return;
	}
	else if(players_alive == 0)
	{
		display_color(WHITE, BLACK);
		ml_printf_at("Oh dear, it looks like a DRAW!", 5, 20);

		end_game();
		return;
	}

	/* Rotate through the players */
	current_player = (current_player + 1) % players;
	while(players_HP[current_player] == 0)
	{
		current_player = (current_player + 1) % players;
	}

	/* Re-colour the reticule for the current player */
	free_sprite(reticule_SPR);
	reticule_SPR = reticule(current_player);

	/* Change to movement phase */
	game_state = 1;

	/* Generate a random(ish) wind for the turn */
	wind_velocity = rand() % 21;

	rectangle *wind_bar = malloc(sizeof(rectangle));
	uint16_t wind_colour;
	fill_rectangle(wind_empty, BLACK);
	
	if(wind_velocity < 10)
	{
		wind_bar->left = WIND_BAR_START + wind_velocity * 10;
		wind_bar->right = WIND_BAR_END;
		wind_bar->top = 231;
		wind_bar->bottom = 236;
		wind_colour = RED;
	}
	else if (wind_velocity > 10)
	{
		wind_bar->left = WIND_BAR_START;
		wind_bar->right = WIND_BAR_START + (wind_velocity - 10) * 10;
		wind_bar->top = 231;
		wind_bar->bottom = 236;
		wind_colour = BLUE;
	}
	else
	{
		free(wind_bar);
		return;
	}
	fill_rectangle(*wind_bar, wind_colour);

	free(wind_bar);
}