Пример #1
0
// Only returns false when there is no ship for the choice.
bool
setShipSelected(GETMELEE_STATE *gms, COUNT playerI, COUNT choice,
		bool reportNetwork)
{
	HSTARSHIP ship;

	assert (!gms->player[playerI].done);

	if (choice == (COUNT) ~0)
	{
		// Random ship selection.
		ship = MeleeShipByUsedIndex (&race_q[playerI],
				gms->player[playerI].randomIndex);
	}
	else
	{
		// Explicit ship selection.
		ship = MeleeShipByQueueIndex (&race_q[playerI], choice);
	}

	if (ship == 0)
		return false;

	gms->player[playerI].choice = choice;
	gms->player[playerI].hBattleShip = ship;
	PlayMenuSound (MENU_SOUND_SUCCESS);
#ifdef NETPLAY
	if (reportNetwork)
		reportShipSelected (gms, choice);
#else
	(void) reportNetwork;
#endif
	gms->player[playerI].done = true;
	return true;
}
Пример #2
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;
}
Пример #3
0
static BOOLEAN
DoModifyRoster (MENU_STATE *pMS)
{
	ROSTER_STATE *rosterState = pMS->privData;
	BOOLEAN select, cancel, up, down, horiz;

	if (GLOBAL (CurrentActivity) & CHECK_ABORT)
		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];
	// Left or right produces the same effect because there are 2 columns
	horiz = PulsedInputState.menu[KEY_MENU_LEFT] ||
			PulsedInputState.menu[KEY_MENU_RIGHT];

	if (cancel && !rosterState->modifyingCrew)
	{
		return FALSE;
	}
	else if (select || cancel)
	{
		rosterState->modifyingCrew ^= true;
		if (!rosterState->modifyingCrew)
		{
			SetFlashRect (NULL);
			SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
		}
		else
		{
			drawModifiedSupportShip (rosterState);
			flashSupportShipCrew ();
			SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN,
					MENU_SOUND_SELECT | MENU_SOUND_CANCEL);
		}
	}
	else if (rosterState->modifyingCrew)
	{
		SIZE delta = 0;
		BOOLEAN failed = FALSE;

		if (up)
		{
			if (GLOBAL_SIS (CrewEnlisted))
				delta = 1;
			else
				failed = TRUE;
		}
		else if (down)
		{
			if (GLOBAL_SIS (CrewEnlisted) < GetCrewPodCapacity ())
				delta = -1;
			else
				failed = TRUE;
		}
		
		if (delta != 0)
		{
			failed = !DeltaSupportCrew (rosterState, delta);
		}

		if (failed)
		{	// not enough room or crew
			PlayMenuSound (MENU_SOUND_FAILURE);
		}
	}
	else
	{
		COUNT NewState;
		POINT *pship_pos = rosterState->shipPos;
		COUNT top_right = (rosterState->count + 1) >> 1;

		NewState = pMS->CurState;
		
		if (rosterState->count < 2)
		{
			// no navigation allowed
		}
		else if (horiz)
		{
			if (NewState == top_right - 1)
				NewState = rosterState->count - 1;
			else if (NewState >= top_right)
			{
				NewState -= top_right;
				if (pship_pos[NewState].y < pship_pos[pMS->CurState].y)
					++NewState;
			}
			else
			{
				NewState += top_right;
				if (NewState != top_right
						&& pship_pos[NewState].y > pship_pos[pMS->CurState].y)
					--NewState;
			}
		}
		else if (down)
		{
			++NewState;
			if (NewState == rosterState->count)
				NewState = top_right;
			else if (NewState == top_right)
				NewState = 0;
		}
		else if (up)
		{
			if (NewState == 0)
				NewState = top_right - 1;
			else if (NewState == top_right)
				NewState = rosterState->count - 1;
			else
				--NewState;
		}

		BatchGraphics ();
		SetContext (StatusContext);

		if (NewState != pMS->CurState)
		{
			// Draw the previous escort in unselected state
			drawSupportShip (rosterState, FALSE);
			// Select the new one
			selectSupportShip (rosterState, NewState);
			pMS->CurState = NewState;
		}

		flashSupportShip (rosterState);

		UnbatchGraphics ();
	}

	SleepThread (ONE_SECOND / 30);

	return TRUE;
}
Пример #4
0
static BOOLEAN
DoManipulateDevices (MENU_STATE *pMS)
{
	DEVICES_STATE *devState = pMS->privData;
	BOOLEAN select, cancel, back, forward;
	BOOLEAN pagefwd, pageback;
	
	select = PulsedInputState.menu[KEY_MENU_SELECT];
	cancel = PulsedInputState.menu[KEY_MENU_CANCEL];
	back = PulsedInputState.menu[KEY_MENU_UP] ||
			PulsedInputState.menu[KEY_MENU_LEFT];
	forward = PulsedInputState.menu[KEY_MENU_DOWN]
			|| PulsedInputState.menu[KEY_MENU_RIGHT];
	pagefwd = PulsedInputState.menu[KEY_MENU_PAGE_DOWN];
	pageback = PulsedInputState.menu[KEY_MENU_PAGE_UP];

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

	if (cancel)
	{
		return FALSE;
	}
	else if (select)
	{
		DeviceStatus status;

		LockMutex (GraphicsLock);
		status = InvokeDevice (devState->list[pMS->CurState]);
		if (status == DEVICE_FAILURE)
			PlayMenuSound (MENU_SOUND_FAILURE);
		else if (status == DEVICE_SUCCESS)
			PlayMenuSound (MENU_SOUND_INVOKED);
		UnlockMutex (GraphicsLock);

		return (status == DEVICE_FAILURE);
	}
	else
	{
		SIZE NewTop;
		SIZE NewState;

		NewTop = devState->topIndex;
		NewState = pMS->CurState;
		
		if (back)
			--NewState;
		else if (forward)
			++NewState;
		else if (pagefwd)
			NewState += MAX_VIS_DEVICES;
		else if (pageback)
			NewState -= MAX_VIS_DEVICES;

		if (NewState < 0)
			NewState = 0;
		else if (NewState >= devState->count)
			NewState = devState->count - 1;

		if (NewState < NewTop || NewState >= NewTop + MAX_VIS_DEVICES)
			NewTop = NewState - NewState % MAX_VIS_DEVICES;

		if (NewState != pMS->CurState)
		{
			if (NewTop != devState->topIndex)
			{	// redraw the display
				devState->topIndex = NewTop;
				DrawDevices (devState, (COUNT)~0, NewState);
			}
			else
			{	// move selection to new device
				DrawDevices (devState, pMS->CurState, NewState);
			}
			pMS->CurState = NewState;
		}

		SleepThread (ONE_SECOND / 30);
	}

	return TRUE;
}
Пример #5
0
static DeviceStatus
InvokeDevice (BYTE which_device)
{
	BYTE val;

	switch (which_device)
	{
		case ROSY_SPHERE_DEVICE:
			val = GET_GAME_STATE (ULTRON_CONDITION);
			if (val)
			{
				SET_GAME_STATE (ULTRON_CONDITION, val + 1);
				SET_GAME_STATE (ROSY_SPHERE_ON_SHIP, 0);
				SET_GAME_STATE (DISCUSSED_ULTRON, 0);
				SET_GAME_STATE (SUPOX_ULTRON_HELP, 0);
				return DEVICE_SUCCESS;
			}
			break;
		case ARTIFACT_2_DEVICE:
			break;
		case ARTIFACT_3_DEVICE:
			break;
		case SUN_EFFICIENCY_DEVICE:
			if (LOBYTE (GLOBAL (CurrentActivity)) == IN_INTERPLANETARY
					&& playerInPlanetOrbit ())
			{
				PlayMenuSound (MENU_SOUND_INVOKED);
				SleepThreadUntil (FadeScreen (FadeAllToWhite, ONE_SECOND * 1)
						+ (ONE_SECOND * 2));
				if (CurStarDescPtr->Index != CHMMR_DEFINED
						|| !matchWorld (pSolarSysState,
								pSolarSysState->pOrbitalDesc,
								1, MATCH_PLANET))
				{
					FadeScreen (FadeAllToColor, ONE_SECOND * 2);
				}
				else
				{
					SET_GAME_STATE (CHMMR_EMERGING, 1);

					EncounterGroup = 0;
					GLOBAL (CurrentActivity) |= START_ENCOUNTER;

					PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
					ReinitQueue (&GLOBAL (ip_group_q));
					assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);

					CloneShipFragment (CHMMR_SHIP,
							&GLOBAL (npc_built_ship_q), 0);
				}
				return DEVICE_SUCCESS_NO_SOUND;
			}
			break;
		case UTWIG_BOMB_DEVICE:
			SET_GAME_STATE (UTWIG_BOMB, 0);
			GLOBAL (CurrentActivity) &= ~IN_BATTLE;
			GLOBAL_SIS (CrewEnlisted) = (COUNT)~0;
			return DEVICE_SUCCESS;
		case ULTRON_0_DEVICE:
			break;
		case ULTRON_1_DEVICE:
			break;
		case ULTRON_2_DEVICE:
			break;
		case ULTRON_3_DEVICE:
			break;
		case MAIDENS_DEVICE:
			break;
		case TALKING_PET_DEVICE:
			NextActivity |= CHECK_LOAD; /* fake a load game */
			GLOBAL (CurrentActivity) |= START_ENCOUNTER;
			SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 0);
			if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE)
			{
				if (GetHeadEncounter ())
				{
					SET_GAME_STATE (SHIP_TO_COMPEL, 1);
				}
				GLOBAL (CurrentActivity) &= ~IN_BATTLE;

				SaveSisHyperState ();
			}
			else
			{
				EncounterGroup = 0;
				if (GetHeadLink (&GLOBAL (ip_group_q)))
				{
					SET_GAME_STATE (SHIP_TO_COMPEL, 1);

					PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
					ReinitQueue (&GLOBAL (ip_group_q));
					assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
				}

				if (CurStarDescPtr->Index == SAMATRA_DEFINED)
				{
					SET_GAME_STATE (READY_TO_CONFUSE_URQUAN, 1);
				}
				if (playerInPlanetOrbit ())
					SaveSolarSysLocation ();
			}
			return DEVICE_SUCCESS;
		case AQUA_HELIX_DEVICE:
			val = GET_GAME_STATE (ULTRON_CONDITION);
			if (val)
			{
				SET_GAME_STATE (ULTRON_CONDITION, val + 1);
				SET_GAME_STATE (AQUA_HELIX_ON_SHIP, 0);
				SET_GAME_STATE (DISCUSSED_ULTRON, 0);
				SET_GAME_STATE (SUPOX_ULTRON_HELP, 0);
				return DEVICE_SUCCESS;
			}
			break;
		case CLEAR_SPINDLE_DEVICE:
			val = GET_GAME_STATE (ULTRON_CONDITION);
			if (val)
			{
				SET_GAME_STATE (ULTRON_CONDITION, val + 1);
				SET_GAME_STATE (CLEAR_SPINDLE_ON_SHIP, 0);
				SET_GAME_STATE (DISCUSSED_ULTRON, 0);
				SET_GAME_STATE (SUPOX_ULTRON_HELP, 0);
				return DEVICE_SUCCESS;
			}
			break;
		case UMGAH_HYPERWAVE_DEVICE:
		case BURVIX_HYPERWAVE_DEVICE:
			if (UseCaster ())
				return DEVICE_SUCCESS;
			break;
		case TAALO_PROTECTOR_DEVICE:
			break;
		case EGG_CASING0_DEVICE:
		case EGG_CASING1_DEVICE:
		case EGG_CASING2_DEVICE:
			break;
		case SYREEN_SHUTTLE_DEVICE:
			break;
		case VUX_BEAST_DEVICE:
			break;
		case DESTRUCT_CODE_DEVICE:
			break;
		case PORTAL_SPAWNER_DEVICE:
#define PORTAL_FUEL_COST (10 * FUEL_TANK_SCALE)
			if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE
					&& GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1
					&& GLOBAL_SIS (FuelOnBoard) >= PORTAL_FUEL_COST)
			{
				/* No DeltaSISGauges because the flagship picture
				 * is currently obscured.
				 */
				GLOBAL_SIS (FuelOnBoard) -= PORTAL_FUEL_COST;
				SET_GAME_STATE (PORTAL_COUNTER, 1);
				return DEVICE_SUCCESS;
			}
			break;
		case URQUAN_WARP_DEVICE:
			break;
		case LUNAR_BASE_DEVICE:
			break;
	}

	return DEVICE_FAILURE;
}
Пример #6
0
BOOLEAN
DoConfirmExit (void)
{
	BOOLEAN result;

	if (PlayingTrack ())
		PauseTrack ();

	LockMutex (GraphicsLock);
	{
		RECT r;
		STAMP s;
		RECT ctxRect;
		CONTEXT oldContext;
		RECT oldRect;
		BOOLEAN response = FALSE, done;

		oldContext = SetContext (ScreenContext);
		GetContextClipRect (&oldRect);
		SetContextClipRect (NULL);

		GetContextClipRect (&ctxRect);
		r.extent.width = CONFIRM_WIN_WIDTH + 4;
		r.extent.height = CONFIRM_WIN_HEIGHT + 4;
		r.corner.x = (ctxRect.extent.width - r.extent.width) >> 1;
		r.corner.y = (ctxRect.extent.height - r.extent.height) >> 1;
		s = SaveContextFrame (&r);
		SetSystemRect (&r);

		DrawConfirmationWindow (response);
		FlushGraphics ();

		FlushInput ();
		done = FALSE;
		
		do {
			// Forbid recursive calls or pausing here!
			ExitRequested = FALSE;
			GamePaused = FALSE;
			UpdateInputState ();
			if (GLOBAL (CurrentActivity) & CHECK_ABORT)
			{	// something else triggered an exit
				done = TRUE;
				response = TRUE;
			}
			else if (PulsedInputState.menu[KEY_MENU_SELECT])
			{
				done = TRUE;
				PlayMenuSound (MENU_SOUND_SUCCESS);
			}
			else if (PulsedInputState.menu[KEY_MENU_CANCEL])
			{
				done = TRUE;
				response = FALSE;
			}
			else if (PulsedInputState.menu[KEY_MENU_LEFT] || PulsedInputState.menu[KEY_MENU_RIGHT])
			{
				response = !response;
				DrawConfirmationWindow (response);
				PlayMenuSound (MENU_SOUND_MOVE);
			}
			SleepThread (ONE_SECOND / 30);
		} while (!done);

		// Restore the screen under the confirmation window
		DrawStamp (&s);
		DestroyDrawable (ReleaseDrawable (s.frame));
		ClearSystemRect ();
		if (response || (GLOBAL (CurrentActivity) & CHECK_ABORT))
		{
			result = TRUE;
			GLOBAL (CurrentActivity) |= CHECK_ABORT;
		}		
		else
		{
			result = FALSE;
		}
		ExitRequested = FALSE;
		GamePaused = FALSE;
		FlushInput ();
		SetContextClipRect (&oldRect);
		SetContext (oldContext);
	}
	UnlockMutex (GraphicsLock);

	if (PlayingTrack ())
		ResumeTrack ();

	return (result);
}
Пример #7
0
BOOLEAN
DoTextEntry (PTEXTENTRY_STATE pTES)
{
	wchar_t ch;
	UNICODE *pStr;
	UNICODE *CacheInsPt;
	int CacheCursorPos;
	int len;
	BOOLEAN changed = FALSE;

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

	if (!pTES->Initialized)
	{	// init basic vars
		int lwlen;

		pTES->InputFunc = DoTextEntry;
		pTES->Success = FALSE;
		pTES->Initialized = TRUE;
		pTES->JoystickMode = FALSE;
		pTES->UpperRegister = TRUE;
	
		// init insertion point
		if ((size_t)pTES->CursorPos > utf8StringCount (pTES->BaseStr))
			pTES->CursorPos = utf8StringCount (pTES->BaseStr);
		pTES->InsPt = skipUTF8Chars (pTES->BaseStr, pTES->CursorPos);

		// load joystick alphabet
		pTES->JoyAlphaString = CaptureStringTable (
				LoadStringTable (JOYSTICK_ALPHA_STRTAB));
		pTES->JoyAlpha = LoadJoystickAlpha (
				SetAbsStringTableIndex (pTES->JoyAlphaString, 0),
				&pTES->JoyAlphaLength);
		pTES->JoyUpper = LoadJoystickAlpha (
				SetAbsStringTableIndex (pTES->JoyAlphaString, 1),
				&pTES->JoyRegLength);
		pTES->JoyLower = LoadJoystickAlpha (
				SetAbsStringTableIndex (pTES->JoyAlphaString, 2),
				&lwlen);
		if (lwlen != pTES->JoyRegLength)
		{
			if (lwlen < pTES->JoyRegLength)
				pTES->JoyRegLength = lwlen;
			log_add (log_Warning, "Warning: Joystick upper-lower registers"
					" size mismatch; using the smallest subset (%d)",
					pTES->JoyRegLength);
		}

		pTES->CacheStr = HMalloc (pTES->MaxSize * sizeof (*pTES->CacheStr));
		
		DoInput (pTES, TRUE);

		if (pTES->CacheStr)
			HFree (pTES->CacheStr);
		if (pTES->JoyLower)
			HFree (pTES->JoyLower);
		if (pTES->JoyUpper)
			HFree (pTES->JoyUpper);
		if (pTES->JoyAlpha)
			HFree (pTES->JoyAlpha);
		DestroyStringTable ( ReleaseStringTable (pTES->JoyAlphaString));

		return pTES->Success;
	}

	pStr = pTES->InsPt;
	len = strlen (pStr);
	// save a copy of string
	CacheInsPt = pTES->InsPt;
	CacheCursorPos = pTES->CursorPos;
	memcpy (pTES->CacheStr, pTES->BaseStr, pTES->MaxSize);

	// process the pending character buffer
	ch = GetNextCharacter ();
	if (!ch && PulsedInputState.menu[KEY_MENU_ANY])
	{	// keyboard repeat, but only when buffer empty
		ch = GetLastCharacter ();
	}
	while (ch)
	{
		UNICODE chbuf[8];
		int chsize;

		pTES->JoystickMode = FALSE;

		chsize = getStringFromChar (chbuf, sizeof (chbuf), ch);
		if (isWidePrintChar (ch) && chsize > 0)
		{
			if (pStr + len - pTES->BaseStr + chsize < pTES->MaxSize)
			{	// insert character, when fits
				memmove (pStr + chsize, pStr, len + 1);
				memcpy (pStr, chbuf, chsize);
				pStr += chsize;
				++pTES->CursorPos;
				changed = TRUE;
			}
			else
			{	// does not fit
				PlayMenuSound (MENU_SOUND_FAILURE);
			}
		}
		ch = GetNextCharacter ();
	}

	if (PulsedInputState.menu[KEY_MENU_DELETE])
	{
		if (len)
		{
			joy_char_t ch;
			
			ReadOneChar (&ch, pStr);
			memmove (pStr, pStr + ch.len, len - ch.len + 1);
			len -= ch.len;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_BACKSPACE])
	{
		if (pStr > pTES->BaseStr)
		{
			UNICODE *prev = skipUTF8Chars (pTES->BaseStr,
					pTES->CursorPos - 1);
			
			memmove (prev, pStr, len + 1);
			pStr = prev;
			--pTES->CursorPos;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_LEFT])
	{
		if (pStr > pTES->BaseStr)
		{
			UNICODE *prev = skipUTF8Chars (pTES->BaseStr,
					pTES->CursorPos - 1);

			pStr = prev;
			len += (prev - pStr);
			--pTES->CursorPos;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_RIGHT])
	{
		if (len > 0)
		{
			joy_char_t ch;
			
			ReadOneChar (&ch, pStr);
			pStr += ch.len;
			len -= ch.len;
			++pTES->CursorPos;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_HOME])
	{
		if (pStr > pTES->BaseStr)
		{
			pStr = pTES->BaseStr;
			len = strlen (pStr);
			pTES->CursorPos = 0;
			changed = TRUE;
		}
	}
	else if (PulsedInputState.menu[KEY_MENU_END])
	{
		if (len > 0)
		{
			pTES->CursorPos += utf8StringCount (pStr);
			pStr += len;
			len = 0;
			changed = TRUE;
		}
	}
	
	if (pTES->JoyAlpha && (
			PulsedInputState.menu[KEY_MENU_UP] ||
			PulsedInputState.menu[KEY_MENU_DOWN] ||
			PulsedInputState.menu[KEY_MENU_PAGE_UP] ||
			PulsedInputState.menu[KEY_MENU_PAGE_DOWN]) )
	{	// do joystick text
		joy_char_t ch;
		joy_char_t newch;
		joy_char_t cmpch;
		int i;

		pTES->JoystickMode = TRUE;

		if (len)
			ReadOneChar (&ch, pStr);
		else
			ch = pTES->JoyAlpha[0];
		
		newch = ch;
		JoyCharToUpper (&cmpch, &ch, pTES);

		// find current char in the alphabet
		i = JoyCharFindIn (&cmpch, pTES->JoyAlpha, pTES->JoyAlphaLength);

		if (PulsedInputState.menu[KEY_MENU_UP])
		{
			--i;
			if (i < 0)
				i = pTES->JoyAlphaLength - 1;
			newch = pTES->JoyAlpha[i];
		}
		else if (PulsedInputState.menu[KEY_MENU_DOWN])
		{
			++i;
			if (i >= pTES->JoyAlphaLength)
				i = 0;
			newch = pTES->JoyAlpha[i];
		}

		if (PulsedInputState.menu[KEY_MENU_PAGE_UP] ||
				PulsedInputState.menu[KEY_MENU_PAGE_DOWN])
		{
			if (len)
			{	// single char change
				if (JoyCharIsLower (&newch, pTES))
					JoyCharToUpper (&newch, &newch, pTES);
				else
					JoyCharToLower (&newch, &newch, pTES);
			}
			else
			{	// register change
				pTES->UpperRegister = !pTES->UpperRegister;
			}
		}
		else
		{	// check register
			if (pTES->UpperRegister)
				JoyCharToUpper (&newch, &newch, pTES);
			else
				JoyCharToLower (&newch, &newch, pTES);
		}

		if (strcmp (newch.enc, ch.enc) != 0)
		{	// new char is different, put it in
			if (len)
			{	// change current -- this is messy with utf8
				int l = len - ch.len;
				if (pStr + l - pTES->BaseStr + newch.len < pTES->MaxSize)
				{
					// adjust other chars if necessary
					if (newch.len != ch.len)
						memmove (pStr + newch.len, pStr + ch.len, l + 1);

					memcpy (pStr, newch.enc, newch.len);
					len = l + newch.len;
					changed = TRUE;
				}
			}
			else
			{	// append
				if (pStr + len - pTES->BaseStr + newch.len < pTES->MaxSize)
				{
					memcpy (pStr, newch.enc, newch.len);
					pStr[newch.len] = '\0';
					len += newch.len;
					changed = TRUE;
				}
				else
				{	// does not fit
					PlayMenuSound (MENU_SOUND_FAILURE);
				}
			}
		}
	}
	
	if (PulsedInputState.menu[KEY_MENU_SELECT])
	{	// done entering
		pTES->Success = TRUE;
		return FALSE;
	}
	else if (PulsedInputState.menu[KEY_MENU_EDIT_CANCEL])
	{	// canceled entering
		pTES->Success = FALSE;
		return FALSE;
	}

	pTES->InsPt = pStr;

	if (changed && pTES->ChangeCallback)
	{
		if (!pTES->ChangeCallback (pTES))
		{	// changes not accepted - revert
			memcpy (pTES->BaseStr, pTES->CacheStr, pTES->MaxSize);
			pTES->InsPt = CacheInsPt;
			pTES->CursorPos = CacheCursorPos;

			PlayMenuSound (MENU_SOUND_FAILURE);
		}
	}
		
	if (pTES->FrameCallback)
		return pTES->FrameCallback (pTES);

	return TRUE;
}
Пример #8
0
/* This code assumes that you aren't in Character Mode.  This is
 * currently safe because VControl doesn't see keystrokes when you
 * are, and thus cannot conclude that an exit is necessary. */
BOOLEAN
DoConfirmExit (void)
{
	BOOLEAN result;
	static BOOLEAN in_confirm = FALSE;
	if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE &&
			LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE &&
			!(LastActivity & CHECK_RESTART))
		SuspendGameClock ();
	if (CommData.ConversationPhrases && PlayingTrack ())
		PauseTrack ();

	LockMutex (GraphicsLock);
	if (in_confirm)
	{
		result = FALSE;
		ExitRequested = FALSE;
	}
	else
	{
		RECT r;
		STAMP s;
		FRAME F;
		CONTEXT oldContext;
		RECT oldRect;
		BOOLEAN response = FALSE, done;

		in_confirm = TRUE;
		oldContext = SetContext (ScreenContext);
		GetContextClipRect (&oldRect);
		SetContextClipRect (NULL_PTR);

		r.extent.width = CONFIRM_WIN_WIDTH + 4;
		r.extent.height = CONFIRM_WIN_HEIGHT + 4;
		r.corner.x = (SCREEN_WIDTH - r.extent.width) >> 1;
		r.corner.y = (SCREEN_HEIGHT - r.extent.height) >> 1;
		s.origin = r.corner;
		F = CaptureDrawable (LoadDisplayPixmap (&r, (FRAME)0));

		SetSystemRect (&r);

		DrawConfirmationWindow (response);

		// Releasing the lock lets the rotate_planet_task
		// draw a frame.  PauseRotate can still allow one more frame
		// to be drawn, so it is safer to just not release the lock
		//UnlockMutex (GraphicsLock);
		FlushGraphics ();
		//LockMutex (GraphicsLock);

		GLOBAL (CurrentActivity) |= CHECK_ABORT;
		FlushInput ();
		done = FALSE;

		do {
			// Forbid recursive calls or pausing here!
			ExitRequested = FALSE;
			GamePaused = FALSE;
			UpdateInputState ();
			if (PulsedInputState.menu[KEY_MENU_SELECT])
			{
				done = TRUE;
				PlayMenuSound (MENU_SOUND_SUCCESS);
			}
			else if (PulsedInputState.menu[KEY_MENU_CANCEL])
			{
				done = TRUE;
				response = FALSE;
			}
			else if (PulsedInputState.menu[KEY_MENU_LEFT] || PulsedInputState.menu[KEY_MENU_RIGHT])
			{
				response = !response;
				DrawConfirmationWindow (response);
				PlayMenuSound (MENU_SOUND_MOVE);
			}
			TaskSwitch ();
		} while (!done);

		s.frame = F;
		DrawStamp (&s);
		DestroyDrawable (ReleaseDrawable (s.frame));
		ClearSystemRect ();
		if (response)
		{
			result = TRUE;
		}		
		else
		{
			result = FALSE;
			GLOBAL (CurrentActivity) &= ~CHECK_ABORT;
		}
		ExitRequested = FALSE;
		GamePaused = FALSE;
		FlushInput ();
		SetContextClipRect (&oldRect);
		SetContext (oldContext);
	}
	UnlockMutex (GraphicsLock);

	if (LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE &&
			LOBYTE (GLOBAL (CurrentActivity)) != WON_LAST_BATTLE &&
			!(LastActivity & CHECK_RESTART))
		ResumeGameClock ();
	if (CommData.ConversationPhrases && PlayingTrack ())
	{
		ResumeTrack ();
		if (CommData.AlienTransitionDesc.AnimFlags & TALK_DONE)
			do_subtitles ((void *)~0);
	}

	in_confirm = FALSE;
	return (result);
}
Пример #9
0
// Returns FALSE if aborted.
static BOOLEAN
SelectShip_processInput (GETMELEE_STATE *gms, COUNT playerI,
		BATTLE_INPUT_STATE inputState)
{
	if (inputState & BATTLE_WEAPON)
	{
		if (gms->player[playerI].col == NUM_PICKMELEE_COLUMNS &&
				gms->player[playerI].row == 0)
		{
			// Random ship
			(void) setShipSelected (gms, playerI, (COUNT) ~0, TRUE);
		}
		else if (gms->player[playerI].col == NUM_PICKMELEE_COLUMNS &&
				gms->player[playerI].row == 1)
		{
			// Selected exit
			if (ConfirmExit ())
				return FALSE;
		}
		else
		{
			// Selection is on a ship slot.
			COUNT slotNr = PickMelee_GetShipIndex (gms->player[playerI].row,
					gms->player[playerI].col);
			(void) setShipSelected (gms, playerI, slotNr, TRUE);
					// If the choice is not valid, setShipSelected()
					// will not set .done.
		}
	}
	else
	{
		// Process motion commands.
		COUNT new_row, new_col;
		
		new_row = gms->player[playerI].row;
		new_col = gms->player[playerI].col;
		if (inputState & BATTLE_LEFT)
		{
			if (new_col-- == 0)
				new_col = NUM_PICKMELEE_COLUMNS;
		}
		else if (inputState & BATTLE_RIGHT)
		{
			if (new_col++ == NUM_PICKMELEE_COLUMNS)
				new_col = 0;
		}
		if (inputState & BATTLE_THRUST)
		{
			if (new_row-- == 0)
				new_row = NUM_PICKMELEE_ROWS - 1;
		}
		else if (inputState & BATTLE_DOWN)
		{
			if (++new_row == NUM_PICKMELEE_ROWS)
				new_row = 0;
		}
		
		if (new_row != gms->player[playerI].row ||
				new_col != gms->player[playerI].col)
		{
			gms->player[playerI].row = new_row;
			gms->player[playerI].col = new_col;
			
			PlayMenuSound (MENU_SOUND_MOVE);
			PickMelee_ChangedSelection (gms, playerI);
		}
	}

	return TRUE;
}
Пример #10
0
static BOOLEAN
DoDiscardCargo (MENU_STATE *pMS)
{
	BYTE NewState;
	BOOLEAN select, cancel, back, forward;
	
	select = PulsedInputState.menu[KEY_MENU_SELECT];
	cancel = PulsedInputState.menu[KEY_MENU_CANCEL];
	back = PulsedInputState.menu[KEY_MENU_UP] || PulsedInputState.menu[KEY_MENU_LEFT];
	forward = PulsedInputState.menu[KEY_MENU_DOWN] || PulsedInputState.menu[KEY_MENU_RIGHT];

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

	if (cancel)
	{
		return FALSE;
	}
	else if (select)
	{
		if (GLOBAL_SIS (ElementAmounts[pMS->CurState]))
		{
			--GLOBAL_SIS (ElementAmounts[pMS->CurState]);
			DrawCargoStrings (pMS->CurState, pMS->CurState);

			--GLOBAL_SIS (TotalElementMass);
			ShowRemainingCapacity ();
		}
		else
		{	// no element left in cargo hold
			PlayMenuSound (MENU_SOUND_FAILURE);
		}
	}
	else
	{
		NewState = pMS->CurState;
		if (back)
		{
			if (NewState == 0)
				NewState += NUM_ELEMENT_CATEGORIES;
			--NewState;
		}
		else if (forward)
		{
			++NewState;
			if (NewState == NUM_ELEMENT_CATEGORIES)
				NewState = 0;
		}

		if (NewState != pMS->CurState)
		{
			DrawCargoStrings (pMS->CurState, NewState);
			DrawElementDescription (NewState);
			pMS->CurState = NewState;
		}
	}

	SleepThread (ONE_SECOND / 30);

	return (TRUE);
}