Пример #1
0
static BOOLEAN
DoRestart (MENU_STATE *pMS)
{
	static TimeCount LastInputTime;
	static TimeCount InactTimeOut;
	TimeCount TimeIn = GetTimeCounter ();

	/* Cancel any presses of the Pause key. */
	GamePaused = FALSE;

	if (pMS->Initialized)
		Flash_process(pMS->flashContext);

	if (!pMS->Initialized)
	{
		if (pMS->hMusic)
		{
			StopMusic ();
			DestroyMusic (pMS->hMusic);
			pMS->hMusic = 0;
		}
		pMS->hMusic = LoadMusic (MAINMENU_MUSIC);
		InactTimeOut = (pMS->hMusic ? 120 : 20) * ONE_SECOND;
		pMS->flashContext = Flash_createOverlay (ScreenContext,
				NULL, NULL);
		Flash_setMergeFactors (pMS->flashContext, -3, 3, 16);
		Flash_setSpeed (pMS->flashContext, (6 * ONE_SECOND) / 16, 0,
				(6 * ONE_SECOND) / 16, 0);
		Flash_setFrameTime (pMS->flashContext, ONE_SECOND / 16);
		Flash_setState(pMS->flashContext, FlashState_fadeIn,
				(3 * ONE_SECOND) / 16);
		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame);
		Flash_start (pMS->flashContext);
		PlayMusic (pMS->hMusic, TRUE, 1);
		LastInputTime = GetTimeCounter ();
		pMS->Initialized = TRUE;

		SleepThreadUntil (FadeScreen (FadeAllToColor, ONE_SECOND / 2));
	}
	else if (GLOBAL (CurrentActivity) & CHECK_ABORT)
	{
		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_SELECT])
	{
		switch (pMS->CurState)
		{
			case LOAD_SAVED_GAME:
				LastActivity = CHECK_LOAD;
				GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				break;
			case START_NEW_GAME:
				LastActivity = CHECK_LOAD | CHECK_RESTART;
				GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				break;
			case PLAY_SUPER_MELEE:
				GLOBAL (CurrentActivity) = SUPER_MELEE;
				break;
			case SETUP_GAME:
				Flash_pause(pMS->flashContext);
				Flash_setState(pMS->flashContext, FlashState_fadeIn,
						(3 * ONE_SECOND) / 16);
				SetupMenu ();
				SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN,
						MENU_SOUND_SELECT);
				LastInputTime = GetTimeCounter ();
				SetTransitionSource (NULL);
				BatchGraphics ();
				DrawRestartMenuGraphic (pMS);
				ScreenTransition (3, NULL);
				DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame);
				Flash_continue(pMS->flashContext);
				UnbatchGraphics ();
				return TRUE;
			case QUIT_GAME:
				SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND / 2));
				GLOBAL (CurrentActivity) = CHECK_ABORT;
				break;
		}

		Flash_pause(pMS->flashContext);

		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_UP] ||
			PulsedInputState.menu[KEY_MENU_DOWN])
	{
		BYTE NewState;

		NewState = pMS->CurState;
		if (PulsedInputState.menu[KEY_MENU_UP])
		{
			if (NewState == START_NEW_GAME)
				NewState = QUIT_GAME;
			else
				--NewState;
		}
		else if (PulsedInputState.menu[KEY_MENU_DOWN])
		{
			if (NewState == QUIT_GAME)
				NewState = START_NEW_GAME;
			else
				++NewState;
		}
		if (NewState != pMS->CurState)
		{
			BatchGraphics ();
			DrawRestartMenu (pMS, NewState, pMS->CurFrame);
			UnbatchGraphics ();
			pMS->CurState = NewState;
		}

		LastInputTime = GetTimeCounter ();
	}
	else if (PulsedInputState.menu[KEY_MENU_LEFT] ||
			PulsedInputState.menu[KEY_MENU_RIGHT])
	{	// Does nothing, but counts as input for timeout purposes
		LastInputTime = GetTimeCounter ();
	}
	else if (MouseButtonDown)
	{
		Flash_pause(pMS->flashContext);
		DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 54));
				// Mouse not supported message
		SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
		SetTransitionSource (NULL);
		BatchGraphics ();
		DrawRestartMenuGraphic (pMS);
		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame);
		ScreenTransition (3, NULL);
		UnbatchGraphics ();
		Flash_continue(pMS->flashContext);

		LastInputTime = GetTimeCounter ();
	}
	else
	{	// No input received, check if timed out
		if (GetTimeCounter () - LastInputTime > InactTimeOut)
		{
			SleepThreadUntil (FadeMusic (0, ONE_SECOND));
			StopMusic ();
			FadeMusic (NORMAL_VOLUME, 0);

			GLOBAL (CurrentActivity) = (ACTIVITY)~0;
			return FALSE;
		}
	}

	SleepThreadUntil (TimeIn + ONE_SECOND / 30);

	return TRUE;
}
Пример #2
0
static BOOLEAN
DoRestart (MENU_STATE *pMS)
{
	static TimeCount LastInputTime;
	static TimeCount InactTimeOut;
	TimeCount TimeIn = GetTimeCounter ();

	/* Cancel any presses of the Pause key. */
	GamePaused = FALSE;

	if (pMS->Initialized)
		Flash_process(pMS->flashContext);

	if (!pMS->Initialized)
	{
		if (pMS->hMusic)
		{
			StopMusic ();
			DestroyMusic (pMS->hMusic);
			pMS->hMusic = 0;
		}
		pMS->hMusic = LoadMusic (MAINMENU_MUSIC);
		InactTimeOut = (pMS->hMusic ? 120 : 20) * ONE_SECOND;
		pMS->flashContext = Flash_createOverlay (ScreenContext,
				NULL, NULL);
		Flash_setMergeFactors (pMS->flashContext, -3, 3, 16);
		Flash_setSpeed (pMS->flashContext, (6 * ONE_SECOND) / 16, 0,
				(6 * ONE_SECOND) / 16, 0);
		Flash_setFrameTime (pMS->flashContext, ONE_SECOND / 16);
		Flash_setState(pMS->flashContext, FlashState_fadeIn,
				(3 * ONE_SECOND) / 16);
		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
		Flash_start (pMS->flashContext);
		PlayMusic (pMS->hMusic, TRUE, 1);
		LastInputTime = GetTimeCounter ();
		pMS->Initialized = TRUE;

		SleepThreadUntil (FadeScreen (FadeAllToColor, ONE_SECOND / 2));
	}
	else if (GLOBAL (CurrentActivity) & CHECK_ABORT)
	{
		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_SELECT])
	{
		//BYTE fade_buf[1];
		COUNT oldresfactor;
		BOOLEAN packsInstalled;
		
		if (resolutionFactor == 0)
			packsInstalled = TRUE;
		else if (resolutionFactor == 1 && hires2xPackPresent)
			packsInstalled = TRUE;
		else if (resolutionFactor == 2 && hires4xPackPresent)
			packsInstalled = TRUE;
		else
			packsInstalled = FALSE;
		
		switch (pMS->CurState)
		{
			case LOAD_SAVED_GAME:
				if (resFactorWasChanged)
				{
					LockMutex (GraphicsLock);
					SetFlashRect (NULL);
					UnlockMutex (GraphicsLock);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35));
					// Got to restart -message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					//fade_buf[0] = FadeAllToBlack;
					//SleepThreadUntil (XFormColorMap ((COLORMAPPTR)fade_buf, ONE_SECOND / 2));
					SleepThreadUntil (FadeScreen(FadeAllToBlack, ONE_SECOND / 2));
					GLOBAL (CurrentActivity) = CHECK_ABORT;
				}
				else if (!packsInstalled)
				{
					Flash_pause(pMS->flashContext);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35 + resolutionFactor));
					// Could not find graphics pack - message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					Flash_continue(pMS->flashContext);
					SleepThreadUntil (TimeIn + ONE_SECOND / 30);
					return TRUE;
				}
				else
				{
					LastActivity = CHECK_LOAD;
					GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				}
				break;
			case START_NEW_GAME:
				if (resFactorWasChanged)
				{
					LockMutex (GraphicsLock);
					SetFlashRect (NULL);
					UnlockMutex (GraphicsLock);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35));
					// Got to restart -message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					//fade_buf[0] = FadeAllToBlack;
					//SleepThreadUntil (XFormColorMap ((COLORMAPPTR)fade_buf, ONE_SECOND / 2));
					SleepThreadUntil (FadeScreen(FadeAllToBlack, ONE_SECOND / 2));
					GLOBAL (CurrentActivity) = CHECK_ABORT;
				}
				else if (!packsInstalled)
				{
					Flash_pause(pMS->flashContext);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35 + resolutionFactor));
					// Could not find graphics pack - message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					Flash_continue(pMS->flashContext);
					SleepThreadUntil (TimeIn + ONE_SECOND / 30);
					return TRUE;
				}
				else
				{
					LastActivity = CHECK_LOAD | CHECK_RESTART;
					GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				}				
				break;
			case PLAY_SUPER_MELEE:
				if (resFactorWasChanged)
				{
					LockMutex (GraphicsLock);
					SetFlashRect (NULL);
					UnlockMutex (GraphicsLock);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35));
					// Got to restart -message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					//fade_buf[0] = FadeAllToBlack;
					//SleepThreadUntil (XFormColorMap ((COLORMAPPTR)fade_buf, ONE_SECOND / 2));
					SleepThreadUntil (FadeScreen(FadeAllToBlack, ONE_SECOND / 2));
					GLOBAL (CurrentActivity) = CHECK_ABORT;
				}
				else if (!packsInstalled)
				{
					Flash_pause(pMS->flashContext);
					DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 35 + resolutionFactor));
					// Could not find graphics pack - message
					SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
					SetTransitionSource (NULL);
					BatchGraphics ();
					DrawRestartMenuGraphic (pMS);
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
					ScreenTransition (3, NULL);
					UnbatchGraphics ();
					Flash_continue(pMS->flashContext);
					SleepThreadUntil (TimeIn + ONE_SECOND / 30);
					return TRUE;
				}
				else
				{
					GLOBAL (CurrentActivity) = SUPER_MELEE;
				}
				break;
			case SETUP_GAME:
				oldresfactor = resolutionFactor;
				Flash_pause(pMS->flashContext);
				Flash_setState(pMS->flashContext, FlashState_fadeIn,
						(3 * ONE_SECOND) / 16);
				SetupMenu ();
				SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN,
						MENU_SOUND_SELECT);
				LastInputTime = GetTimeCounter ();
				SetTransitionSource (NULL);
				BatchGraphics ();
				DrawRestartMenuGraphic (pMS);
				ScreenTransition (3, NULL);
				
				// JMS_GFX: This prevents drawing an annoying wrong-sized "Setup" frame when changing resolution. 
				if (oldresfactor < resolutionFactor)
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, TRUE);
				
				DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
				Flash_continue(pMS->flashContext);
				UnbatchGraphics ();
				return TRUE;
			case QUIT_GAME:
				SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND / 2));
				GLOBAL (CurrentActivity) = CHECK_ABORT;
				break;
		}

		Flash_pause(pMS->flashContext);

		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_UP] ||
			PulsedInputState.menu[KEY_MENU_DOWN])
	{
		BYTE NewState;

		NewState = pMS->CurState;
		if (PulsedInputState.menu[KEY_MENU_UP])
		{
			if (NewState == START_NEW_GAME)
				NewState = QUIT_GAME;
			else
				--NewState;
		}
		else if (PulsedInputState.menu[KEY_MENU_DOWN])
		{
			if (NewState == QUIT_GAME)
				NewState = START_NEW_GAME;
			else
				++NewState;
		}
		if (NewState != pMS->CurState)
		{
			BatchGraphics ();
			DrawRestartMenu (pMS, NewState, pMS->CurFrame, FALSE);
			UnbatchGraphics ();
			pMS->CurState = NewState;
		}

		LastInputTime = GetTimeCounter ();
	}
	else if (PulsedInputState.menu[KEY_MENU_LEFT] ||
			PulsedInputState.menu[KEY_MENU_RIGHT])
	{	// Does nothing, but counts as input for timeout purposes
		LastInputTime = GetTimeCounter ();
	}
	else if (MouseButtonDown)
	{
		Flash_pause(pMS->flashContext);
		DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 54));
				// Mouse not supported message
		SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
		SetTransitionSource (NULL);
		BatchGraphics ();
		DrawRestartMenuGraphic (pMS);
		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
		ScreenTransition (3, NULL);
		UnbatchGraphics ();
		Flash_continue(pMS->flashContext);

		LastInputTime = GetTimeCounter ();
	}
	else
	{	// No input received, check if timed out
		if (GetTimeCounter () - LastInputTime > InactTimeOut)
		{
			SleepThreadUntil (FadeMusic (0, ONE_SECOND));
			StopMusic ();
			FadeMusic (NORMAL_VOLUME, 0);

			GLOBAL (CurrentActivity) = (ACTIVITY)~0;
			return FALSE;
		}
	}

	SleepThreadUntil (TimeIn + ONE_SECOND / 30);

	return TRUE;
}
Пример #3
0
static BOOLEAN
DoRestart (MENU_STATE *pMS)
{
	static TimeCount LastInputTime;
	static TimeCount InactTimeOut;
	TimeCount TimeIn = GetTimeCounter ();

	/* Cancel any presses of the Pause key. */
	GamePaused = FALSE;
	
	if(optSuperMelee && !optLoadGame && PacksInstalled()){
		pMS->CurState = PLAY_SUPER_MELEE;
		PulsedInputState.menu[KEY_MENU_SELECT] = 65535;
	}
	if(optLoadGame && !optSuperMelee && PacksInstalled()){
		pMS->CurState = LOAD_SAVED_GAME;
		PulsedInputState.menu[KEY_MENU_SELECT] = 65535;
	}

	if (pMS->Initialized)
		Flash_process(pMS->flashContext);

	if (!pMS->Initialized)
	{
		if (pMS->hMusic && !comingFromInit)
		{
			StopMusic ();
			DestroyMusic (pMS->hMusic);
			pMS->hMusic = 0;
		}
		
		pMS->hMusic = loadMainMenuMusic (Rando);
		InactTimeOut = (optMainMenuMusic ? 60 : 20) * ONE_SECOND;

		pMS->flashContext = Flash_createOverlay (ScreenContext,
				NULL, NULL);
		Flash_setMergeFactors (pMS->flashContext, -3, 3, 16);
		Flash_setSpeed (pMS->flashContext, (6 * ONE_SECOND) / 14, 0,
				(6 * ONE_SECOND) / 14, 0);
		Flash_setFrameTime (pMS->flashContext, ONE_SECOND / 16);
		Flash_setState(pMS->flashContext, FlashState_fadeIn,
				(3 * ONE_SECOND) / 16);

		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
		Flash_start (pMS->flashContext);
		LastInputTime = GetTimeCounter ();
		pMS->Initialized = TRUE;

		SleepThreadUntil (FadeScreen (FadeAllToColor, ONE_SECOND / 2));
		if (!comingFromInit){
			FadeMusic(0,0);
			PlayMusic (pMS->hMusic, TRUE, 1);
		
			if (optMainMenuMusic)
				FadeMusic (NORMAL_VOLUME+70, ONE_SECOND * 3);
		}
	}
	else if (GLOBAL (CurrentActivity) & CHECK_ABORT)
	{
		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_SELECT])
	{
		//BYTE fade_buf[1];
		COUNT oldresfactor;

		switch (pMS->CurState)
		{
			case LOAD_SAVED_GAME:
				if (!RestartMessage(pMS, TimeIn)) {
					LastActivity = CHECK_LOAD;
					GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
					optLoadGame = FALSE;
				} else
					return TRUE;
				break;
			case START_NEW_GAME:
				if (!RestartMessage(pMS, TimeIn)) {
					LastActivity = CHECK_LOAD | CHECK_RESTART;
					GLOBAL (CurrentActivity) = IN_INTERPLANETARY;
				} else
					return TRUE;
				break;
			case PLAY_SUPER_MELEE:
				if (!RestartMessage(pMS, TimeIn)) {
					GLOBAL (CurrentActivity) = SUPER_MELEE;
					optSuperMelee = FALSE;
				} else
					return TRUE;
				break;
			case SETUP_GAME:
				oldresfactor = resolutionFactor;
				
				Flash_pause(pMS->flashContext);
				Flash_setState(pMS->flashContext, FlashState_fadeIn,
						(3 * ONE_SECOND) / 16);
				SetupMenu ();
				SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN,
						MENU_SOUND_SELECT);

				InactTimeOut = (optMainMenuMusic ? 60 : 20) * ONE_SECOND;

				LastInputTime = GetTimeCounter ();
				SetTransitionSource (NULL);
				BatchGraphics ();
				DrawRestartMenuGraphic (pMS);
				ScreenTransition (3, NULL);
				// JMS_GFX: This prevents drawing an annoying wrong-sized "Setup" frame when changing resolution. 
				if (oldresfactor < resolutionFactor)
					DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, TRUE);
				
				DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
				Flash_continue(pMS->flashContext);
				UnbatchGraphics ();
				return TRUE;
			case QUIT_GAME:
				SleepThreadUntil (FadeScreen (FadeAllToBlack, ONE_SECOND / 2));
				GLOBAL (CurrentActivity) = CHECK_ABORT;
				break;
		}

		Flash_pause(pMS->flashContext);

		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_UP] ||
			PulsedInputState.menu[KEY_MENU_DOWN])
	{
		BYTE NewState;

		NewState = pMS->CurState;
		if (PulsedInputState.menu[KEY_MENU_UP])
		{
			if (NewState == START_NEW_GAME)
				NewState = QUIT_GAME;
			else
				--NewState;
		}
		else if (PulsedInputState.menu[KEY_MENU_DOWN])
		{
			if (NewState == QUIT_GAME)
				NewState = START_NEW_GAME;
			else
				++NewState;
		}
		if (NewState != pMS->CurState)
		{
			BatchGraphics ();
			DrawRestartMenu (pMS, NewState, pMS->CurFrame, FALSE);
			UnbatchGraphics ();
			pMS->CurState = NewState;
		}

		LastInputTime = GetTimeCounter ();
	}
	else if (PulsedInputState.menu[KEY_MENU_LEFT] ||
			PulsedInputState.menu[KEY_MENU_RIGHT])
	{	// Does nothing, but counts as input for timeout purposes
		LastInputTime = GetTimeCounter ();
	}
	else if (MouseButtonDown)
	{
		Flash_pause(pMS->flashContext);
		DoPopupWindow (GAME_STRING (MAINMENU_STRING_BASE + 54));
				// Mouse not supported message
		SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT);	
		SetTransitionSource (NULL);
		BatchGraphics ();
		DrawRestartMenuGraphic (pMS);
		DrawRestartMenu (pMS, pMS->CurState, pMS->CurFrame, FALSE);
		ScreenTransition (3, NULL);
		UnbatchGraphics ();
		Flash_continue(pMS->flashContext);

		LastInputTime = GetTimeCounter ();
	}
	else
	{	// No input received, check if timed out
		// JMS: After changing resolution mode, prevent displaying credits
		// (until the next time the game is restarted). This is to prevent
		// showing the credits with the wrong resolution mode's font&background.
		if (GetTimeCounter () - LastInputTime > InactTimeOut
			&& !optRequiresRestart && PacksInstalled())
		{
			SleepThreadUntil (FadeMusic (0, ONE_SECOND/2));
			StopMusic ();
			FadeMusic (NORMAL_VOLUME, 0);

			GLOBAL (CurrentActivity) = (ACTIVITY)~0;
			return FALSE;
		}
	}
	comingFromInit = FALSE;
	SleepThreadUntil (TimeIn + ONE_SECOND / 30);

	return TRUE;
}
Пример #4
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;
}