Example #1
0
// Post: the NetState for all players is NetState_interBattle
static BOOLEAN
GetMeleeStarShips (COUNT playerMask, HSTARSHIP *ships)
{
	COUNT playerI;
	BOOLEAN ok;
	GETMELEE_STATE gmstate;
	TimeCount now;
	COUNT i;

#ifdef NETPLAY
	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
	{
		NetConnection *conn;

		if ((playerMask & (1 << playerI)) == 0)
			continue;

		// XXX: This does not have to be done per connection.
		conn = netConnections[playerI];
		if (conn != NULL) {
			BattleStateData *battleStateData;
			battleStateData =
					(BattleStateData *) NetConnection_getStateData (conn);
			battleStateData->getMeleeState = &gmstate;
		}
	}
#endif
	
	ok = true;

	now = GetTimeCounter ();
	gmstate.InputFunc = DoGetMelee;
	gmstate.Initialized = FALSE;
	for (i = 0; i < NUM_PLAYERS; ++i)
	{
		// We have to use TFB_Random() results in specific order
		playerI = GetPlayerOrder (i);
		gmstate.player[playerI].selecting =
				(playerMask & (1 << playerI)) != 0;
		gmstate.player[playerI].ships_left = battle_counter[playerI];

		// We determine in advance which ship would be chosen if the player
		// wants a random ship, to keep it simple to keep network parties
		// synchronised.
		gmstate.player[playerI].randomIndex =
				(COUNT)TFB_Random () % gmstate.player[playerI].ships_left;
		gmstate.player[playerI].done = FALSE;

		if (!gmstate.player[playerI].selecting)
			continue;

		gmstate.player[playerI].timeIn = now;
		gmstate.player[playerI].row = 0;
		gmstate.player[playerI].col = NUM_PICKMELEE_COLUMNS;
#ifdef NETPLAY
		gmstate.player[playerI].remoteSelected = FALSE;
#endif

		gmstate.player[playerI].flashContext =
				Flash_createHighlight (ScreenContext, NULL);
		Flash_setMergeFactors (gmstate.player[playerI].flashContext,
				2, 3, 2);
		Flash_setFrameTime (gmstate.player[playerI].flashContext,
				ONE_SECOND / 16);
#ifdef NETPLAY
		if (PlayerControl[playerI] & NETWORK_CONTROL)
			Flash_setSpeed (gmstate.player[playerI].flashContext,
					ONE_SECOND / 2, 0, ONE_SECOND / 2, 0);
		else
#endif
		{
			Flash_setSpeed (gmstate.player[playerI].flashContext,
					0, ONE_SECOND / 16, 0, ONE_SECOND / 16);
		}
		PickMelee_ChangedSelection (&gmstate, playerI);
		Flash_start (gmstate.player[playerI].flashContext);
	}

#ifdef NETPLAY
	{
		// NB. gmstate.player[].randomIndex and gmstate.player[].done must
		// be initialised before negotiateReadyConnections is completed, to
		// ensure that they are initialised when the SelectShip packet
		// arrives.
		bool allOk = negotiateReadyConnections (true, NetState_selectShip);
		if (!allOk)
		{
			// Some network connection has been reset.
			ok = false;
		}
	}
#endif
	SetDefaultMenuRepeatDelay ();
	
	SetContext (OffScreenContext);


	DoInput (&gmstate, FALSE);
	WaitForSoundEnd (0);


	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
	{
		if (!gmstate.player[playerI].selecting)
			continue;
		
		if (gmstate.player[playerI].done)
		{
			// Flash rectangle is already terminated.
			ships[playerI] = gmstate.player[playerI].hBattleShip;
		}
		else
		{
			Flash_terminate (gmstate.player[playerI].flashContext);
			gmstate.player[playerI].flashContext = NULL;
			ok = false;
		}
	}

#ifdef NETPLAY
	if (ok)
	{
		if (!negotiateReadyConnections (true, NetState_interBattle))
			ok = false;
	}
	else
		setStateConnections (NetState_interBattle);
#endif

	if (!ok)
	{
		// Aborting.
		GLOBAL (CurrentActivity) &= ~IN_BATTLE;
	}

#ifdef NETPLAY
	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
	{
		NetConnection *conn;

		if ((playerMask & (1 << playerI)) == 0)
			continue;

		// XXX: This does not have to be done per connection.
		conn = netConnections[playerI];
		if (conn != NULL && NetConnection_isConnected (conn))
		{
			BattleStateData *battleStateData;
			battleStateData =
					(BattleStateData *) NetConnection_getStateData (conn);
			battleStateData->getMeleeState = NULL;
		}
	}
#endif

	return ok;
}
Example #2
0
static BOOLEAN
RestartMenu (MENU_STATE *pMS)
{
	TimeCount TimeOut;

	ReinitQueue (&race_q[0]);
	ReinitQueue (&race_q[1]);

	SetContext (ScreenContext);

	GLOBAL (CurrentActivity) |= CHECK_ABORT;
	if (GLOBAL_SIS (CrewEnlisted) == (COUNT)~0
			&& GET_GAME_STATE (UTWIG_BOMB_ON_SHIP)
			&& !GET_GAME_STATE (UTWIG_BOMB))
	{	// player blew himself up with Utwig bomb
		SET_GAME_STATE (UTWIG_BOMB_ON_SHIP, 0);

		SleepThreadUntil (FadeScreen (FadeAllToWhite, ONE_SECOND / 8)
				+ ONE_SECOND / 60);
		SetContextBackGroundColor (
				BUILD_COLOR (MAKE_RGB15 (0x1F, 0x1F, 0x1F), 0x0F));
		ClearDrawable ();
		FlushColorXForms ();

		TimeOut = ONE_SECOND / 8;
	}
	else
	{
		TimeOut = ONE_SECOND / 2;

		if (LOBYTE (LastActivity) == WON_LAST_BATTLE)
		{
			GLOBAL (CurrentActivity) = WON_LAST_BATTLE;
			Victory ();
			Credits (TRUE);

			FreeGameData ();
			
			GLOBAL (CurrentActivity) = CHECK_ABORT;
		}
	}

	LastActivity = 0;
	NextActivity = 0;

	// TODO: This fade is not always necessary, especially after a splash
	//   screen. It only makes a user wait.
	SleepThreadUntil (FadeScreen (FadeAllToBlack, TimeOut));
	if (TimeOut == ONE_SECOND / 8)
		SleepThread (ONE_SECOND * 3);

	pMS->CurFrame = CaptureDrawable (LoadGraphic (RESTART_PMAP_ANIM));

	DrawRestartMenuGraphic (pMS);
	GLOBAL (CurrentActivity) &= ~CHECK_ABORT;
	SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);
	SetDefaultMenuRepeatDelay ();
	DoInput (pMS, TRUE);
	
	StopMusic ();
	if (pMS->hMusic)
	{
		DestroyMusic (pMS->hMusic);
		pMS->hMusic = 0;
	}

	Flash_terminate (pMS->flashContext);
	pMS->flashContext = 0;
	DestroyDrawable (ReleaseDrawable (pMS->CurFrame));
	pMS->CurFrame = 0;

	if (GLOBAL (CurrentActivity) == (ACTIVITY)~0)
		return (FALSE); // timed out

	if (GLOBAL (CurrentActivity) & CHECK_ABORT)
		return (FALSE); // quit

	TimeOut = FadeScreen (FadeAllToBlack, ONE_SECOND / 2);
	
	SleepThreadUntil (TimeOut);
	FlushColorXForms ();

	SeedRandomNumbers ();

	return (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE);
}
Example #3
0
/* TODO: Include player timeouts */
static BOOLEAN
DoGetMelee (GETMELEE_STATE *gms)
{
	BOOLEAN done;
	COUNT playerI;

	SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE);

	if (!gms->Initialized)
	{
		gms->Initialized = TRUE;
		return TRUE;
	}

	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
	{
		if (!gms->player[playerI].selecting)
			continue;

		if (!gms->player[playerI].done)
			Flash_process (gms->player[playerI].flashContext);
	}

	SleepThread (ONE_SECOND / 120);

#ifdef NETPLAY
	netInput ();

	if (!allConnected ())
		goto aborted;
#endif
	
	if (GLOBAL (CurrentActivity) & CHECK_ABORT)
		goto aborted;

	done = TRUE;
	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
	{
		if (!gms->player[playerI].selecting)
			continue;

		if (!gms->player[playerI].done) {
			if (!PlayerInput[playerI]->handlers->selectShip (
					PlayerInput[playerI], gms))
				goto aborted;

			if (gms->player[playerI].done)
			{
				Flash_terminate (gms->player[playerI].flashContext);
				gms->player[playerI].flashContext = NULL;
			}
			else
				done = FALSE;
		}
	}

#ifdef NETPLAY
	flushPacketQueues ();
#endif
	return !done;

aborted:
#ifdef NETPLAY
	flushPacketQueues ();
#endif
	for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
	{
		if (!gms->player[playerI].selecting)
			continue;

		gms->player[playerI].choice = 0;
		gms->player[playerI].hBattleShip = 0;
	}
	GLOBAL (CurrentActivity) &= ~CHECK_ABORT;
	return FALSE;
}