Пример #1
0
static HSHIPFRAG
MatchSupportShip (MENU_STATE *pMS)
{
	POINT *pship_pos;
	HSHIPFRAG hStarShip, hNextShip;

	for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)),
			pship_pos = (POINT*)pMS->flash_frame0;
			hStarShip; hStarShip = hNextShip, ++pship_pos)
	{
		SHIP_FRAGMENT *StarShipPtr;

		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip);

		if (pship_pos->x == pMS->first_item.x
				&& pship_pos->y == pMS->first_item.y)
		{
			UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);
			return hStarShip;
		}

		hNextShip = _GetSuccLink (StarShipPtr);
		UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);
	}

	return 0;
}
Пример #2
0
/*
 * Give the player 'count' ships of the specified race,
 * limited by the number of free slots.
 * Returns the number of ships added.
 */
COUNT
AddEscortShips (COUNT race, SIZE count)
{
	HFLEETINFO hFleet;
	BYTE which_window;
	COUNT i;

	hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race);
	if (!hFleet)
		return 0;

	assert (count > 0);

	which_window = 0;
	for (i = 0; i < (COUNT) count; i++)
	{
		HSHIPFRAG hStarShip;
		HSHIPFRAG hOldShip;
		SHIP_FRAGMENT *StarShipPtr;

		hStarShip = CloneShipFragment (race, &GLOBAL (built_ship_q), 0);
		if (!hStarShip)
			break;

		RemoveQueue (&GLOBAL (built_ship_q), hStarShip);

		/* Find first available escort window */
		while ((hOldShip = GetStarShipFromIndex (
				&GLOBAL (built_ship_q), which_window++)))
		{
			BYTE win_loc;

			StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hOldShip);
			win_loc = StarShipPtr->index;
			UnlockShipFrag (&GLOBAL (built_ship_q), hOldShip);
			if (which_window <= win_loc)
				break;
		}

		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip);
		StarShipPtr->index = which_window - 1;
		UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);

		InsertQueue (&GLOBAL (built_ship_q), hStarShip, hOldShip);
	}

	DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA);
	return i;
}
Пример #3
0
static SHIP_FRAGMENT *
LockSupportShip (ROSTER_STATE *rosterState, HSHIPFRAG *phFrag)
{
	const POINT *pship_pos;
	HSHIPFRAG hStarShip, hNextShip;

	// Lookup the current escort's location in the unsorted points list
	// to find the original escort index
	for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)),
			pship_pos = ship_pos;
			hStarShip; hStarShip = hNextShip, ++pship_pos)
	{
		SHIP_FRAGMENT *StarShipPtr;

		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip);

		if (pointsEqual (*pship_pos, rosterState->curShipPt))
		{
			*phFrag = hStarShip;
			return StarShipPtr;
		}

		hNextShip = _GetSuccLink (StarShipPtr);
		UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);
	}

	return NULL;
}
Пример #4
0
/*
 * Returns the number of ships of the specified race among the
 * escort ships.
 */
COUNT
CountEscortShips (COUNT race)
{
	HFLEETINFO hFleet;
	HSHIPFRAG hStarShip, hNextShip;
	COUNT result = 0;

	hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), race);
	if (!hFleet)
		return 0;

	for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip;
			hStarShip = hNextShip)
	{
		BYTE ship_type;
		SHIP_FRAGMENT *StarShipPtr;

		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip);
		hNextShip = _GetSuccLink (StarShipPtr);
		ship_type = StarShipPtr->race_id;
		UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);

		if (ship_type == race)
			result++;
	}
	return result;
}
Пример #5
0
static void
RosterCleanup (MENU_STATE *pMS)
{
	if (pMS->flash_task)
	{
		UnlockMutex (GraphicsLock);
		ConcludeTask (pMS->flash_task);
		LockMutex (GraphicsLock);
		pMS->flash_task = 0;
	}

	if (pMS->CurFrame)
	{
		STAMP s;
		SHIP_FRAGMENT *StarShipPtr;

		SetContext (StatusContext);
		s.origin = pMS->first_item;
		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q),
				(HSHIPFRAG)pMS->CurFrame);
		s.frame = StarShipPtr->icons;
		UnlockShipFrag (&GLOBAL (built_ship_q), (HSHIPFRAG)pMS->CurFrame);
		if (!(pMS->CurState & SHIP_TOGGLE))
			DrawStamp (&s);
		else
		{
			SetContextForeGroundColor (WHITE_COLOR);
			DrawFilledStamp (&s);
		}
	}
}
Пример #6
0
static void
getSupportShipIcon (ROSTER_STATE *rosterState)
{
	HSHIPFRAG hShipFrag;
	SHIP_FRAGMENT *ShipFragPtr;

	rosterState->curShipFrame = NULL;
	ShipFragPtr = LockSupportShip (rosterState, &hShipFrag);
	if (!ShipFragPtr)
		return;

	rosterState->curShipFrame = ShipFragPtr->icons;
	UnlockShipFrag (&GLOBAL (built_ship_q), hShipFrag);
}
Пример #7
0
static BOOLEAN
DeltaSupportCrew (ROSTER_STATE *rosterState, SIZE crew_delta)
{
	BOOLEAN ret = FALSE;
	UNICODE buf[40];
	HFLEETINFO hTemplate;
	HSHIPFRAG hShipFrag;
	SHIP_FRAGMENT *StarShipPtr;
	FLEET_INFO *TemplatePtr;

	StarShipPtr = LockSupportShip (rosterState, &hShipFrag);
	if (!StarShipPtr)
		return FALSE;

	hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q),
			StarShipPtr->race_id);
	TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hTemplate);

	StarShipPtr->crew_level += crew_delta;

	if (StarShipPtr->crew_level == 0)
		StarShipPtr->crew_level = 1;
	else if (StarShipPtr->crew_level > TemplatePtr->crew_level &&
			crew_delta > 0)
		StarShipPtr->crew_level -= crew_delta;
	else
	{
		if (StarShipPtr->crew_level >= TemplatePtr->crew_level)
			sprintf (buf, "%u", StarShipPtr->crew_level);
		else
			sprintf (buf, "%u/%u",
					StarShipPtr->crew_level,
					TemplatePtr->crew_level);

		PreUpdateFlashRect ();
		DrawStatusMessage (buf);
		PostUpdateFlashRect ();
		DeltaSISGauges (-crew_delta, 0, 0);
		if (crew_delta)
		{
			flashSupportShipCrew ();
		}
		ret = TRUE;
	}

	UnlockFleetInfo (&GLOBAL (avail_race_q), hTemplate);
	UnlockShipFrag (&GLOBAL (built_ship_q), hShipFrag);

	return ret;
}
Пример #8
0
/* Set the crew and captain's name on the first fully-crewed escort
 * ship of race 'which_ship' */
int
SetEscortCrewComplement (COUNT which_ship, COUNT crew_level, BYTE captain)
{
	HFLEETINFO hFleet;
	FLEET_INFO *TemplatePtr;
	HSHIPFRAG hStarShip, hNextShip;
	SHIP_FRAGMENT *StarShipPtr = 0;
	int Index;

	hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), which_ship);
	if (!hFleet)
		return -1;
	TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hFleet);

	/* Find first ship of which_ship race */
	for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)), Index = 0;
			hStarShip; hStarShip = hNextShip, ++Index)
	{
		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip);
		hNextShip = _GetSuccLink (StarShipPtr);
		if (which_ship == StarShipPtr->race_id &&
				StarShipPtr->crew_level == TemplatePtr->crew_level)
			break; /* found one */
		UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);
	}
	if (hStarShip)
	{
		StarShipPtr->crew_level = crew_level;
		StarShipPtr->captains_name_index = captain;
		UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);
	}
	else
		Index = -1;

	UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet);
	return Index;
}
Пример #9
0
HSHIPFRAG
GetEscortByStarShipIndex (COUNT index)
{
	HSHIPFRAG hStarShip;
	HSHIPFRAG hNextShip;
	SHIP_FRAGMENT *StarShipPtr;

	for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q));
			hStarShip; hStarShip = hNextShip)
	{
		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip);

		if (StarShipPtr->index == index)
		{
			UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);
			break;
		}

		hNextShip = _GetSuccLink (StarShipPtr);
		UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);
	}

	return hStarShip;
}
Пример #10
0
// crew_level can be set to INFINITE_FLEET for a ship which is to
// represent an infinite number of ships.
HSHIPFRAG
CloneShipFragment (COUNT shipIndex, QUEUE *pDstQueue, COUNT crew_level)
{
	HFLEETINFO hFleet;
	HSHIPFRAG hBuiltShip;
	FLEET_INFO *TemplatePtr;
	BYTE captains_name_index;

	assert (GetLinkSize (pDstQueue) == sizeof (SHIP_FRAGMENT));

	hFleet = GetStarShipFromIndex (&GLOBAL (avail_race_q), shipIndex);
	if (!hFleet)
		return 0;

	TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hFleet);
	if (shipIndex == SAMATRA_SHIP)
		captains_name_index = 0;
	else
		captains_name_index = NameCaptain (pDstQueue,
				TemplatePtr->SpeciesID);
	hBuiltShip = Build (pDstQueue, TemplatePtr->SpeciesID);
	if (hBuiltShip)
	{
		SHIP_FRAGMENT *ShipFragPtr;

		ShipFragPtr = LockShipFrag (pDstQueue, hBuiltShip);
		ShipFragPtr->captains_name_index = captains_name_index;
		ShipFragPtr->race_strings = TemplatePtr->race_strings;
		ShipFragPtr->icons = TemplatePtr->icons;
		ShipFragPtr->melee_icon = TemplatePtr->melee_icon;
		if (crew_level)
			ShipFragPtr->crew_level = crew_level;
		else
			ShipFragPtr->crew_level = TemplatePtr->crew_level;
		ShipFragPtr->max_crew = TemplatePtr->max_crew;
		ShipFragPtr->energy_level = 0;
		ShipFragPtr->max_energy = TemplatePtr->max_energy;
		ShipFragPtr->race_id = (BYTE)shipIndex;
		ShipFragPtr->index = 0;
		UnlockShipFrag (pDstQueue, hBuiltShip);
	}
	UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet);

	return hBuiltShip;
}
Пример #11
0
void
clearEscorts (void)
{
	HSHIPFRAG hStarShip, hNextShip;

	for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q));
			hStarShip; hStarShip = hNextShip)
	{
		SHIP_FRAGMENT *StarShipPtr;

		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip);
		hNextShip = _GetSuccLink (StarShipPtr);
		UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);

		RemoveQueue (&GLOBAL (built_ship_q), hStarShip);
		FreeShipFrag (&GLOBAL (built_ship_q), hStarShip);
	}

	DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA);
}
Пример #12
0
/*
 * Returns the total value of all the ships escorting the SIS.
 */
COUNT
CalculateEscortsWorth (void)
{
	COUNT ShipCost[] =
	{
		RACE_SHIP_COST
	};
	COUNT total = 0;
	HSHIPFRAG hStarShip, hNextShip;

	for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q));
			hStarShip; hStarShip = hNextShip)
	{
		SHIP_FRAGMENT *StarShipPtr;

		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip);
		hNextShip = _GetSuccLink (StarShipPtr);
		total += ShipCost[StarShipPtr->race_id];
		UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);
	}
	return total;
}
Пример #13
0
static void
LoadShipQueue (DECODE_REF fh, QUEUE *pQueue)
{
	COUNT num_links;

	cread_16 (fh, &num_links);

	while (num_links--)
	{
		HSHIPFRAG hStarShip;
		SHIP_FRAGMENT *FragPtr;
		COUNT Index;
		BYTE tmpb;

		cread_16 (fh, &Index);

		hStarShip = CloneShipFragment (Index, pQueue, 0);
		FragPtr = LockShipFrag (pQueue, hStarShip);

		// Read SHIP_FRAGMENT elements
		cread_16 (fh, NULL); /* unused: was which_side */
		cread_8  (fh, &FragPtr->captains_name_index);
		cread_8  (fh, NULL); /* padding */
		cread_16 (fh, NULL); /* unused: was ship_flags */
		cread_8  (fh, &FragPtr->race_id);
		cread_8  (fh, &FragPtr->index);
		// XXX: reading crew as BYTE to maintain savegame compatibility
		cread_8  (fh, &tmpb);
		FragPtr->crew_level = tmpb;
		cread_8  (fh, &tmpb);
		FragPtr->max_crew = tmpb;
		cread_8  (fh, &FragPtr->energy_level);
		cread_8  (fh, &FragPtr->max_energy);
		cread_16 (fh, NULL); /* unused; was loc.x */
		cread_16 (fh, NULL); /* unused; was loc.y */

		UnlockShipFrag (pQueue, hStarShip);
	}
}
Пример #14
0
static int
flash_ship_task (void *data)
{
	DWORD TimeIn;
	COLOR c;
	Task task = (Task) data;

	c = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x00, 0x00), 0x24);
	TimeIn = GetTimeCounter ();
	while (!Task_ReadState (task, TASK_EXIT))
	{
		STAMP s;
		SHIP_FRAGMENT *StarShipPtr;
		COLOR OldColor;
		CONTEXT OldContext;

		LockMutex (GraphicsLock);
		s.origin = pMenuState->first_item;
		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q),
				(HSHIPFRAG)pMenuState->CurFrame);
		s.frame = StarShipPtr->icons;
		UnlockShipFrag (&GLOBAL (built_ship_q),
				(HSHIPFRAG)pMenuState->CurFrame);
		OldContext = SetContext (StatusContext);
		if (c >= BUILD_COLOR (MAKE_RGB15 (0x1F, 0x19, 0x19), 0x24))
			c = BUILD_COLOR (MAKE_RGB15 (0x1F, 0x00, 0x00), 0x24);
		else
			c += BUILD_COLOR (MAKE_RGB15 (0x00, 0x02, 0x02), 0x00);
		OldColor = SetContextForeGroundColor (c);
		DrawFilledStamp (&s);
		SetContextForeGroundColor (OldColor);
		SetContext (OldContext);
		UnlockMutex (GraphicsLock);
		SleepThreadUntil (TimeIn + ONE_SECOND / 15);
		TimeIn = GetTimeCounter ();
	}
	FinishTask (task);
	return 0;
}
Пример #15
0
/*
 * Remove a number of escort ships of the specified race (if present).
 * Returns the number of escort ships removed.
 */
COUNT
RemoveSomeEscortShips (COUNT race, COUNT count)
{
	HSHIPFRAG hStarShip;
	HSHIPFRAG hNextShip;

	if (count == 0)
		return 0;

	for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip;
			hStarShip = hNextShip)
	{
		BOOLEAN RemoveShip;
		SHIP_FRAGMENT *StarShipPtr;

		StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q), hStarShip);
		hNextShip = _GetSuccLink (StarShipPtr);
		RemoveShip = (StarShipPtr->race_id == race);
		UnlockShipFrag (&GLOBAL (built_ship_q), hStarShip);

		if (RemoveShip)
		{
			RemoveQueue (&GLOBAL (built_ship_q), hStarShip);
			FreeShipFrag (&GLOBAL (built_ship_q), hStarShip);
			count--;
			if (count == 0)
				break;
		}
	}
	
	if (count > 0)
	{
		// Update the display.
		DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA);
	}

	return count;
}
Пример #16
0
static BOOLEAN
DeltaSupportCrew (SIZE crew_delta)
{
	BOOLEAN ret = FALSE;
	UNICODE buf[40];
	HFLEETINFO hTemplate;
	SHIP_FRAGMENT *StarShipPtr;
	FLEET_INFO *TemplatePtr;

	StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q),
			(HSHIPFRAG)pMenuState->CurFrame);
	hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q),
			StarShipPtr->race_id);
	TemplatePtr = LockFleetInfo (&GLOBAL (avail_race_q), hTemplate);

	if (crew_delta > 0)
	{
		while (crew_delta && (StarShipPtr->crew_level + crew_delta) >
				StarShipPtr->max_crew)
			crew_delta--;
	}
	else if (crew_delta < 0)
	{
		while (crew_delta && (StarShipPtr->crew_level + crew_delta) < 1)
			crew_delta++;
	}
	StarShipPtr->crew_level += crew_delta;

	if (StarShipPtr->crew_level == 0)
		StarShipPtr->crew_level = 1;
	else if (StarShipPtr->crew_level > TemplatePtr->crew_level &&
			crew_delta > 0)
		StarShipPtr->crew_level -= crew_delta;
	else
	{
		if (StarShipPtr->crew_level >= TemplatePtr->crew_level)
			sprintf (buf, "%u", StarShipPtr->crew_level);
		else
			sprintf (buf, "%u/%u",
					StarShipPtr->crew_level,
					TemplatePtr->crew_level);

		DrawStatusMessage (buf);
		DeltaSISGauges (-crew_delta, 0, 0);
		if (crew_delta)
		{
			RECT r;

			r.corner.x = 2;
			r.corner.y = 130;
			r.extent.width = STATUS_MESSAGE_WIDTH;
			r.extent.height = STATUS_MESSAGE_HEIGHT;
			SetContext (StatusContext);
			SetFlashRect (&r, (FRAME)0);
		}
		ret = TRUE;
	}

	UnlockFleetInfo (&GLOBAL (avail_race_q), hTemplate);
	UnlockShipFrag (&GLOBAL (built_ship_q), (HSHIPFRAG)pMenuState->CurFrame);

	return ret;
}
Пример #17
0
static BOOLEAN
DoModifyRoster (MENU_STATE *pMS)
{
	BYTE NewState;
	SBYTE sx, sy;
	RECT r;
	STAMP s;
	SHIP_FRAGMENT *StarShipPtr;
	BOOLEAN select, cancel, up, down, pgup, pgdn, horiz;

	if (GLOBAL (CurrentActivity) & CHECK_ABORT)
	{
		LockMutex (GraphicsLock);
		RosterCleanup (pMS);
		UnlockMutex (GraphicsLock);
		pMS->CurFrame = 0;

		return FALSE;
	}

	select = PulsedInputState.menu[KEY_MENU_SELECT];
	cancel = PulsedInputState.menu[KEY_MENU_CANCEL];
	up = PulsedInputState.menu[KEY_MENU_UP];
	down = PulsedInputState.menu[KEY_MENU_DOWN];
	horiz = PulsedInputState.menu[KEY_MENU_LEFT] ||
			PulsedInputState.menu[KEY_MENU_RIGHT];
	pgup = PulsedInputState.menu[KEY_MENU_PAGE_UP];
	pgdn = PulsedInputState.menu[KEY_MENU_PAGE_DOWN];

	if (pMS->Initialized && (pMS->CurState & SHIP_TOGGLE))
	{
		SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN | MENU_SOUND_PAGEUP |
				MENU_SOUND_PAGEDOWN, MENU_SOUND_SELECT | MENU_SOUND_CANCEL);
	}
	else
	{
		SetMenuSounds (MENU_SOUND_ARROWS | MENU_SOUND_PAGEUP |
				MENU_SOUND_PAGEDOWN, MENU_SOUND_SELECT);
	}

	if (!pMS->Initialized)
	{
		pMS->InputFunc = DoModifyRoster;
		pMS->Initialized = TRUE;

		pMS->CurState = NewState = 0;
		LockMutex (GraphicsLock);
		SetContext (StatusContext);
		goto SelectSupport;
	}
	else if (cancel && !(pMS->CurState & SHIP_TOGGLE))
	{
		LockMutex (GraphicsLock);
		SetFlashRect (NULL, (FRAME)0);
		RosterCleanup (pMS);
		pMS->CurFrame = 0;
		DrawStatusMessage (NULL);
		UnlockMutex (GraphicsLock);

		return FALSE;
	}
	else if (select || cancel)
	{
		LockMutex (GraphicsLock);
		pMS->CurState ^= SHIP_TOGGLE;
		if (!(pMS->CurState & SHIP_TOGGLE))
			SetFlashRect (NULL, (FRAME)0);
		else
		{
			RosterCleanup (pMS);

			r.corner.x = 2;
			r.corner.y = 130;
			r.extent.width = STATUS_MESSAGE_WIDTH;
			r.extent.height = STATUS_MESSAGE_HEIGHT;
			SetContext (StatusContext);
			SetFlashRect (&r, (FRAME)0);
		}
		UnlockMutex (GraphicsLock);
	}
	else if (pMS->CurState & SHIP_TOGGLE)
	{
		SIZE delta = 0;
		BOOLEAN failed = FALSE;
		if (up || pgup)
		{
			if (GLOBAL_SIS (CrewEnlisted))
				delta = pgup ? 10 : 1;
			else
				failed = TRUE;
		}
		else if (down || pgdn)
		{
			if (GLOBAL_SIS (CrewEnlisted) < GetCPodCapacity (NULL))
				delta = pgdn ? -10 : -1;
			else
				failed = TRUE;
		}
		
		if (delta != 0)
		{
			LockMutex (GraphicsLock);
			failed = !DeltaSupportCrew (delta);
			UnlockMutex (GraphicsLock);
		}
		if (failed)
		{	// not enough room or crew
			PlayMenuSound (MENU_SOUND_FAILURE);
		}
	}
	else
	{
		POINT *pship_pos;

		NewState = pMS->CurState;
		sx = (SBYTE)((pMS->delta_item + 1) >> 1);
		if (horiz)
		{
			pship_pos = (POINT*)pMS->flash_frame1;
			if (NewState == (BYTE)(sx - 1))
				NewState = (BYTE)(pMS->delta_item - 1);
			else if (NewState >= (BYTE)sx)
			{
				NewState -= sx;
				if (pship_pos[NewState].y < pship_pos[pMS->CurState].y)
					++NewState;
			}
			else
			{
				NewState += sx;
				if (NewState != (BYTE)sx
						&& pship_pos[NewState].y > pship_pos[pMS->CurState].y)
					--NewState;
			}
		}
		else if (down)
		{
			sy = 1;
			if (++NewState == (BYTE)pMS->delta_item)
				NewState = (BYTE)(sx - 1);
			else if (NewState == (BYTE)sx)
				NewState = 0;
		}
		else if (up)
		{
			sy = -1;
			if (NewState == 0)
				NewState += sx - 1;
			else if (NewState == (BYTE)sx)
				NewState = (BYTE)(pMS->delta_item - 1);
			else
				--NewState;
		}

		if (NewState != pMS->CurState)
		{
			LockMutex (GraphicsLock);
			SetContext (StatusContext);
			s.origin = pMS->first_item;
			StarShipPtr = LockShipFrag (&GLOBAL (built_ship_q),
					(HSHIPFRAG)pMS->CurFrame);
			s.frame = StarShipPtr->icons;
			UnlockShipFrag (&GLOBAL (built_ship_q), (HSHIPFRAG)pMS->CurFrame);
			DrawStamp (&s);
SelectSupport:
			pship_pos = (POINT*)pMS->flash_frame1;
			pMS->first_item = pship_pos[NewState];
			pMS->CurFrame = (FRAME)MatchSupportShip (pMS);

			DeltaSupportCrew (0);
			UnlockMutex (GraphicsLock);

			pMS->CurState = NewState;
		}

		if (pMS->flash_task == 0)
			pMS->flash_task = AssignTask (flash_ship_task, 2048,
					"flash roster menu");
	}

	return TRUE;
}