summaryrefslogtreecommitdiff
path: root/src/uqm/planets/devices.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/uqm/planets/devices.c')
-rw-r--r--src/uqm/planets/devices.c690
1 files changed, 690 insertions, 0 deletions
diff --git a/src/uqm/planets/devices.c b/src/uqm/planets/devices.c
new file mode 100644
index 0000000..e781d5b
--- /dev/null
+++ b/src/uqm/planets/devices.c
@@ -0,0 +1,690 @@
+//Copyright Paul Reiche, Fred Ford. 1992-2002
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "../build.h"
+#include "../colors.h"
+#include "../gendef.h"
+#include "../starmap.h"
+#include "../encount.h"
+#include "../gamestr.h"
+#include "../controls.h"
+#include "../save.h"
+#include "../settings.h"
+#include "../shipcont.h"
+#include "../setup.h"
+#include "../state.h"
+#include "../sis.h"
+ // for ClearSISRect()
+#include "../grpinfo.h"
+#include "../sounds.h"
+#include "../util.h"
+#include "../hyper.h"
+ // for SaveSisHyperState()
+#include "planets.h"
+ // for SaveSolarSysLocation() and tests
+#include "libs/strlib.h"
+
+
+// If DEBUG_DEVICES is defined, the device list shown in the game will
+// include the pictures of all devices defined, regardless of which
+// devices the player actually possesses.
+//#define DEBUG_DEVICES
+
+#define DEVICE_ICON_WIDTH 16
+#define DEVICE_ICON_HEIGHT 16
+
+#define DEVICE_ORG_Y 33
+#define DEVICE_SPACING_Y (DEVICE_ICON_HEIGHT + 2)
+
+#define DEVICE_COL_0 4
+#define DEVICE_COL_1 40
+
+#define DEVICE_SEL_ORG_X (DEVICE_COL_0 + DEVICE_ICON_WIDTH)
+#define DEVICE_SEL_WIDTH (FIELD_WIDTH + 1 - DEVICE_SEL_ORG_X + 1)
+
+#define ICON_OFS_Y 1
+#define NAME_OFS_Y 2
+#define TEXT_BASELINE 6
+#define TEXT_SPACING_Y 7
+
+#define MAX_VIS_DEVICES ((129 - DEVICE_ORG_Y) / DEVICE_SPACING_Y)
+
+
+typedef enum
+{
+ DEVICE_FAILURE = 0,
+ DEVICE_SUCCESS,
+ DEVICE_SUCCESS_NO_SOUND,
+} DeviceStatus;
+
+typedef struct
+{
+ BYTE list[NUM_DEVICES];
+ // List of all devices player has
+ COUNT count;
+ // Number of devices in the list
+ COUNT topIndex;
+ // Index of the top device displayed
+} DEVICES_STATE;
+
+
+#if 0
+static void
+EraseDevicesBackground (void)
+{
+ RECT r;
+
+ r.corner.x = 2 + 1;
+ r.extent.width = FIELD_WIDTH + 1 - 2;
+ r.corner.y = DEVICE_ORG_Y;
+ r.extent.height = MAX_VIS_DEVICES * DEVICE_SPACING_Y;
+ SetContextForeGroundColor (DEVICES_BACK_COLOR);
+ DrawFilledRectangle (&r);
+}
+#endif
+
+static void
+DrawDevice (COUNT device, COUNT pos, bool selected)
+{
+ RECT r;
+ TEXT t;
+
+ t.align = ALIGN_CENTER;
+ t.baseline.x = DEVICE_COL_1;
+
+ r.extent.width = DEVICE_SEL_WIDTH;
+ r.extent.height = TEXT_SPACING_Y * 2;
+ r.corner.x = DEVICE_SEL_ORG_X;
+
+ // draw line background
+ r.corner.y = DEVICE_ORG_Y + pos * DEVICE_SPACING_Y + NAME_OFS_Y;
+ SetContextForeGroundColor (selected ?
+ DEVICES_SELECTED_BACK_COLOR : DEVICES_BACK_COLOR);
+ DrawFilledRectangle (&r);
+
+ SetContextFont (TinyFont);
+
+ // print device name
+ SetContextForeGroundColor (selected ?
+ DEVICES_SELECTED_NAME_COLOR : DEVICES_NAME_COLOR);
+ t.baseline.y = r.corner.y + TEXT_BASELINE;
+ t.pStr = GAME_STRING (device + DEVICE_STRING_BASE + 1);
+ t.CharCount = utf8StringPos (t.pStr, ' ');
+ font_DrawText (&t);
+ t.baseline.y += TEXT_SPACING_Y;
+ t.pStr = skipUTF8Chars (t.pStr, t.CharCount + 1);
+ t.CharCount = (COUNT)~0;
+ font_DrawText (&t);
+}
+
+static void
+DrawDevicesDisplay (DEVICES_STATE *devState)
+{
+ TEXT t;
+ RECT r;
+ STAMP s;
+ COORD cy;
+ COUNT i;
+
+ r.corner.x = 2;
+ r.corner.y = 20;
+ r.extent.width = FIELD_WIDTH + 1;
+ // XXX: Shouldn't the height be 1 less? This draws the bottom border
+ // 1 pixel too low. Or if not, why do we need another box anyway?
+ r.extent.height = 129 - r.corner.y;
+ DrawStarConBox (&r, 1,
+ SHADOWBOX_MEDIUM_COLOR, SHADOWBOX_DARK_COLOR,
+ TRUE, DEVICES_BACK_COLOR);
+
+ // print the "DEVICES" title
+ SetContextFont (StarConFont);
+ t.baseline.x = (STATUS_WIDTH >> 1) - 1;
+ t.baseline.y = r.corner.y + 7;
+ t.align = ALIGN_CENTER;
+ t.pStr = GAME_STRING (DEVICE_STRING_BASE);
+ t.CharCount = (COUNT)~0;
+ SetContextForeGroundColor (DEVICES_SELECTED_NAME_COLOR);
+ font_DrawText (&t);
+
+ s.origin.x = DEVICE_COL_0;
+ cy = DEVICE_ORG_Y;
+
+ // draw device icons and print names
+ for (i = 0; i < MAX_VIS_DEVICES; ++i, cy += DEVICE_SPACING_Y)
+ {
+ COUNT devIndex = devState->topIndex + i;
+
+ if (devIndex >= devState->count)
+ break;
+
+ // draw device icon
+ s.origin.y = cy + ICON_OFS_Y;
+ s.frame = SetAbsFrameIndex (MiscDataFrame,
+ 77 + devState->list[devIndex]);
+ DrawStamp (&s);
+
+ DrawDevice (devState->list[devIndex], i, false);
+ }
+}
+
+static void
+DrawDevices (DEVICES_STATE *devState, COUNT OldDevice, COUNT NewDevice)
+{
+ BatchGraphics ();
+
+ SetContext (StatusContext);
+
+ if (OldDevice > NUM_DEVICES)
+ { // Asked for the initial display or refresh
+ DrawDevicesDisplay (devState);
+
+ // do not draw unselected again this time
+ OldDevice = NewDevice;
+ }
+
+ if (OldDevice != NewDevice)
+ { // unselect the previous element
+ DrawDevice (devState->list[OldDevice], OldDevice - devState->topIndex,
+ false);
+ }
+
+ if (NewDevice < NUM_DEVICES)
+ { // select the new element
+ DrawDevice (devState->list[NewDevice], NewDevice - devState->topIndex,
+ true);
+ }
+
+ UnbatchGraphics ();
+}
+
+// Returns TRUE if the broadcaster has been successfully activated,
+// and FALSE otherwise.
+static BOOLEAN
+UseCaster (void)
+{
+ if (inHQSpace ())
+ {
+ if (GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1)
+ {
+ SET_GAME_STATE (USED_BROADCASTER, 1);
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ if (LOBYTE (GLOBAL (CurrentActivity)) != IN_INTERPLANETARY
+ || !playerInSolarSystem ())
+ return FALSE;
+
+ if (playerInPlanetOrbit ()
+ && matchWorld (pSolarSysState, pSolarSysState->pOrbitalDesc,
+ 1, MATCH_PLANET)
+ && CurStarDescPtr->Index == CHMMR_DEFINED
+ && !GET_GAME_STATE (CHMMR_UNLEASHED))
+ {
+ // In orbit around the Chenjesu/Mmrnmhrm home planet.
+ NextActivity |= CHECK_LOAD; /* fake a load game */
+ GLOBAL (CurrentActivity) |= START_ENCOUNTER;
+
+ EncounterGroup = 0;
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7);
+ SaveSolarSysLocation ();
+ return TRUE;
+ }
+
+ {
+ BOOLEAN FoundIlwrath;
+ HIPGROUP hGroup;
+
+ FoundIlwrath = (CurStarDescPtr->Index == ILWRATH_DEFINED)
+ && StartSphereTracking (ILWRATH_SHIP);
+ // In the Ilwrath home system and they are alive?
+
+ if (!FoundIlwrath &&
+ (hGroup = GetHeadLink (&GLOBAL (ip_group_q))))
+ {
+ // Is an Ilwrath ship in the system?
+ IP_GROUP *GroupPtr;
+
+ GroupPtr = LockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ FoundIlwrath = (GroupPtr->race_id == ILWRATH_SHIP);
+ UnlockIpGroup (&GLOBAL (ip_group_q), hGroup);
+ }
+
+ if (FoundIlwrath)
+ {
+ NextActivity |= CHECK_LOAD; /* fake a load game */
+ GLOBAL (CurrentActivity) |= START_ENCOUNTER;
+
+ EncounterGroup = 0;
+ PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
+ ReinitQueue (&GLOBAL (ip_group_q));
+ assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0);
+
+ if (CurStarDescPtr->Index == ILWRATH_DEFINED)
+ {
+ // Ilwrath home system.
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 4);
+ }
+ else
+ {
+ // Ilwrath ship.
+ SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 5);
+ }
+
+ if (playerInPlanetOrbit ())
+ SaveSolarSysLocation ();
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+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 (inHQSpace ())
+ {
+ 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 (inHyperSpace ()
+ && 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;
+}
+
+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;
+
+ status = InvokeDevice (devState->list[pMS->CurState]);
+ if (status == DEVICE_FAILURE)
+ PlayMenuSound (MENU_SOUND_FAILURE);
+ else if (status == DEVICE_SUCCESS)
+ PlayMenuSound (MENU_SOUND_INVOKED);
+
+ 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;
+}
+
+SIZE
+InventoryDevices (BYTE *pDeviceMap, COUNT Size)
+{
+ BYTE i;
+ SIZE DevicesOnBoard;
+
+ DevicesOnBoard = 0;
+ for (i = 0; i < NUM_DEVICES && Size > 0; ++i)
+ {
+ BYTE DeviceState;
+
+ DeviceState = 0;
+ switch (i)
+ {
+ case ROSY_SPHERE_DEVICE:
+ DeviceState = GET_GAME_STATE (ROSY_SPHERE_ON_SHIP);
+ break;
+ case ARTIFACT_2_DEVICE:
+ DeviceState = GET_GAME_STATE (ARTIFACT_2_ON_SHIP);
+ break;
+ case ARTIFACT_3_DEVICE:
+ DeviceState = GET_GAME_STATE (ARTIFACT_3_ON_SHIP);
+ break;
+ case SUN_EFFICIENCY_DEVICE:
+ DeviceState = GET_GAME_STATE (SUN_DEVICE_ON_SHIP);
+ break;
+ case UTWIG_BOMB_DEVICE:
+ DeviceState = GET_GAME_STATE (UTWIG_BOMB_ON_SHIP);
+ break;
+ case ULTRON_0_DEVICE:
+ DeviceState = (GET_GAME_STATE (ULTRON_CONDITION) == 1);
+ break;
+ case ULTRON_1_DEVICE:
+ DeviceState = (GET_GAME_STATE (ULTRON_CONDITION) == 2);
+ break;
+ case ULTRON_2_DEVICE:
+ DeviceState = (GET_GAME_STATE (ULTRON_CONDITION) == 3);
+ break;
+ case ULTRON_3_DEVICE:
+ DeviceState = (GET_GAME_STATE (ULTRON_CONDITION) == 4);
+ break;
+ case MAIDENS_DEVICE:
+ DeviceState = GET_GAME_STATE (MAIDENS_ON_SHIP);
+ break;
+ case TALKING_PET_DEVICE:
+ DeviceState = GET_GAME_STATE (TALKING_PET_ON_SHIP);
+ break;
+ case AQUA_HELIX_DEVICE:
+ DeviceState = GET_GAME_STATE (AQUA_HELIX_ON_SHIP);
+ break;
+ case CLEAR_SPINDLE_DEVICE:
+ DeviceState = GET_GAME_STATE (CLEAR_SPINDLE_ON_SHIP);
+ break;
+ case UMGAH_HYPERWAVE_DEVICE:
+ DeviceState = GET_GAME_STATE (UMGAH_BROADCASTERS_ON_SHIP);
+ break;
+ case TAALO_PROTECTOR_DEVICE:
+ DeviceState = GET_GAME_STATE (TAALO_PROTECTOR_ON_SHIP);
+ break;
+ case EGG_CASING0_DEVICE:
+ DeviceState = GET_GAME_STATE (EGG_CASE0_ON_SHIP);
+ break;
+ case EGG_CASING1_DEVICE:
+ DeviceState = GET_GAME_STATE (EGG_CASE1_ON_SHIP);
+ break;
+ case EGG_CASING2_DEVICE:
+ DeviceState = GET_GAME_STATE (EGG_CASE2_ON_SHIP);
+ break;
+ case SYREEN_SHUTTLE_DEVICE:
+ DeviceState = GET_GAME_STATE (SYREEN_SHUTTLE_ON_SHIP);
+ break;
+ case VUX_BEAST_DEVICE:
+ DeviceState = GET_GAME_STATE (VUX_BEAST_ON_SHIP);
+ break;
+ case DESTRUCT_CODE_DEVICE:
+#ifdef NEVER
+ DeviceState = GET_GAME_STATE (DESTRUCT_CODE_ON_SHIP);
+#endif /* NEVER */
+ break;
+ case PORTAL_SPAWNER_DEVICE:
+ DeviceState = GET_GAME_STATE (PORTAL_SPAWNER_ON_SHIP);
+ break;
+ case URQUAN_WARP_DEVICE:
+ DeviceState = GET_GAME_STATE (PORTAL_KEY_ON_SHIP);
+ break;
+ case BURVIX_HYPERWAVE_DEVICE:
+ DeviceState = GET_GAME_STATE (BURV_BROADCASTERS_ON_SHIP);
+ break;
+ case LUNAR_BASE_DEVICE:
+ DeviceState = GET_GAME_STATE (MOONBASE_ON_SHIP);
+ break;
+ }
+
+#ifndef DEBUG_DEVICES
+ if (DeviceState)
+#endif /* DEBUG_DEVICES */
+ {
+ *pDeviceMap++ = i;
+ ++DevicesOnBoard;
+ --Size;
+ }
+ }
+
+ return DevicesOnBoard;
+}
+
+BOOLEAN
+DevicesMenu (void)
+{
+ MENU_STATE MenuState;
+ DEVICES_STATE DevicesState;
+
+ memset (&MenuState, 0, sizeof MenuState);
+ MenuState.privData = &DevicesState;
+
+ memset (&DevicesState, 0, sizeof DevicesState);
+
+ DevicesState.count = InventoryDevices (DevicesState.list, NUM_DEVICES);
+ if (!DevicesState.count)
+ return FALSE;
+
+ DrawDevices (&DevicesState, (COUNT)~0, MenuState.CurState);
+
+ SetMenuSounds (MENU_SOUND_ARROWS | MENU_SOUND_PAGEUP | MENU_SOUND_PAGEDOWN,
+ MENU_SOUND_SELECT);
+
+ MenuState.InputFunc = DoManipulateDevices;
+ DoInput (&MenuState, TRUE);
+
+ SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
+
+ if (GLOBAL_SIS (CrewEnlisted) != (COUNT)~0
+ && !(GLOBAL (CurrentActivity) & CHECK_ABORT))
+ {
+ ClearSISRect (DRAW_SIS_DISPLAY);
+
+ if (!GET_GAME_STATE (PORTAL_COUNTER)
+ && !(GLOBAL (CurrentActivity) & START_ENCOUNTER)
+ && GLOBAL_SIS (CrewEnlisted) != (COUNT)~0)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+