static BOOLEAN DeltaSupportCrew (SIZE crew_delta) { BOOLEAN ret = FALSE; UNICODE buf[40]; HSTARSHIP hTemplate; SHIP_FRAGMENTPTR StarShipPtr, TemplatePtr; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), (HSTARSHIP)pMenuState->CurFrame); hTemplate = GetStarShipFromIndex (&GLOBAL (avail_race_q), GET_RACE_ID (StarShipPtr)); TemplatePtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (avail_race_q), hTemplate); StarShipPtr->ShipInfo.crew_level += crew_delta; if (StarShipPtr->ShipInfo.crew_level == 0) StarShipPtr->ShipInfo.crew_level = 1; else if (StarShipPtr->ShipInfo.crew_level > TemplatePtr->RaceDescPtr->ship_info.crew_level && crew_delta > 0) StarShipPtr->ShipInfo.crew_level -= crew_delta; else { if (StarShipPtr->ShipInfo.crew_level >= TemplatePtr->RaceDescPtr->ship_info.crew_level) sprintf (buf, "%u", StarShipPtr->ShipInfo.crew_level); else sprintf (buf, "%u/%u", StarShipPtr->ShipInfo.crew_level, TemplatePtr->RaceDescPtr->ship_info.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; } UnlockStarShip (&GLOBAL (avail_race_q), hTemplate); UnlockStarShip (&GLOBAL (built_ship_q), (HSTARSHIP)pMenuState->CurFrame); return ret; }
static HSTARSHIP MatchSupportShip (PMENU_STATE pMS) { PPOINT pship_pos; HSTARSHIP hStarShip, hNextShip; for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)), pship_pos = (PPOINT)pMS->flash_frame0; hStarShip; hStarShip = hNextShip, ++pship_pos) { SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hStarShip); if (pship_pos->x == pMS->first_item.x && pship_pos->y == pMS->first_item.y) { UnlockStarShip (&GLOBAL (built_ship_q), hStarShip); return hStarShip; } hNextShip = _GetSuccLink (StarShipPtr); UnlockStarShip (&GLOBAL (built_ship_q), hStarShip); } return 0; }
static void RosterCleanup (PMENU_STATE pMS) { if (pMS->flash_task) { UnlockMutex (GraphicsLock); ConcludeTask (pMS->flash_task); LockMutex (GraphicsLock); pMS->flash_task = 0; } if (pMS->CurFrame) { STAMP s; SHIP_FRAGMENTPTR StarShipPtr; SetContext (StatusContext); s.origin = pMS->first_item; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), (HSTARSHIP)pMS->CurFrame); s.frame = StarShipPtr->ShipInfo.icons; UnlockStarShip (&GLOBAL (built_ship_q), (HSTARSHIP)pMS->CurFrame); if (!(pMS->CurState & SHIP_TOGGLE)) DrawStamp (&s); else { SetContextForeGroundColor (WHITE_COLOR); DrawFilledStamp (&s); } } }
static COUNT queueIndexFromShip (HSTARSHIP hShip) { COUNT result; STARSHIP *StarShipPtr = LockStarShip (queue, hShip); result = StarShipPtr->index; UnlockStarShip (queue, hShip); }
HSTARSHIP CloneShipFragment (COUNT index, PQUEUE pDstQueue, BYTE crew_level) { HSTARSHIP hStarShip, hBuiltShip; SHIP_FRAGMENTPTR TemplatePtr; if ((hStarShip = GetStarShipFromIndex (&GLOBAL (avail_race_q), index)) == 0) return (0); TemplatePtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (avail_race_q), hStarShip ); hBuiltShip = Build (pDstQueue, TemplatePtr->RaceResIndex, TemplatePtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY), (BYTE)(index == SAMATRA_SHIP ? 0 : NameCaptain (pDstQueue, (STARSHIPPTR)TemplatePtr))); if (hBuiltShip) { SHIP_FRAGMENTPTR ShipFragPtr; ShipFragPtr = (SHIP_FRAGMENTPTR)LockStarShip (pDstQueue, hBuiltShip); ShipFragPtr->ShipInfo = TemplatePtr->ShipInfo; if (crew_level) ShipFragPtr->ShipInfo.crew_level = crew_level; ShipFragPtr->ShipInfo.energy_level = 0; ShipFragPtr->ShipInfo.ship_flags = 0; ShipFragPtr->ShipInfo.var1 = ShipFragPtr->ShipInfo.var2 = 0; ShipFragPtr->ShipInfo.loc.x = ShipFragPtr->ShipInfo.loc.y = 0; SET_RACE_ID (ShipFragPtr, (BYTE)index); UnlockStarShip (pDstQueue, hBuiltShip); } UnlockStarShip ( &GLOBAL (avail_race_q), hStarShip ); return (hBuiltShip); }
static void init_probe (void) { BYTE b0, b1, b2, b3; HSTARSHIP hStarShip; b0 = GET_GAME_STATE (URQUAN_PROBE_GRPOFFS0); b1 = GET_GAME_STATE (URQUAN_PROBE_GRPOFFS1); b2 = GET_GAME_STATE (URQUAN_PROBE_GRPOFFS2); b3 = GET_GAME_STATE (URQUAN_PROBE_GRPOFFS3); GLOBAL (BattleGroupRef) = MAKE_DWORD ( MAKE_WORD (b0, b1), MAKE_WORD (b2, b3) ); if (GLOBAL (BattleGroupRef) == 0) { CloneShipFragment (URQUAN_PROBE_SHIP, &GLOBAL (npc_built_ship_q), 0); GLOBAL (BattleGroupRef) = PutGroupInfo (~0L, 1); b0 = LOBYTE (LOWORD (GLOBAL (BattleGroupRef))); b1 = HIBYTE (LOWORD (GLOBAL (BattleGroupRef))); b2 = LOBYTE (HIWORD (GLOBAL (BattleGroupRef))); b3 = HIBYTE (HIWORD (GLOBAL (BattleGroupRef))); SET_GAME_STATE (URQUAN_PROBE_GRPOFFS0, b0); SET_GAME_STATE (URQUAN_PROBE_GRPOFFS1, b1); SET_GAME_STATE (URQUAN_PROBE_GRPOFFS2, b2); SET_GAME_STATE (URQUAN_PROBE_GRPOFFS3, b3); } if (!GET_GAME_STATE (PROBE_MESSAGE_DELIVERED) && GetGroupInfo (GLOBAL (BattleGroupRef), (BYTE)~0) && (hStarShip = GetHeadLink ( &GLOBAL (npc_built_ship_q) ))) { SHIP_FRAGMENTPTR FragPtr; FragPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (npc_built_ship_q), hStarShip ); SET_GROUP_MISSION (FragPtr, IN_ORBIT); SET_GROUP_LOC (FragPtr, 2 + 1); /* orbitting earth */ SET_GROUP_DEST (FragPtr, 2 + 1); /* orbitting earth */ FragPtr->ShipInfo.loc.x = FragPtr->ShipInfo.loc.y = 0; FragPtr->ShipInfo.group_counter = 0; UnlockStarShip ( &GLOBAL (npc_built_ship_q), hStarShip ); } }
static HSTARSHIP BuildSIS (void) { HSTARSHIP hStarShip; STARSHIP *StarShipPtr; hStarShip = Build (&race_q[0], SIS_SHIP_ID); if (!hStarShip) return 0; StarShipPtr = LockStarShip (&race_q[0], hStarShip); StarShipPtr->playerNr = RPG_PLAYER_NUM; StarShipPtr->captains_name_index = 0; UnlockStarShip (&race_q[0], hStarShip); return hStarShip; }
HSTARSHIP BuildSIS (void) { HSTARSHIP hStarShip; STARSHIP *StarShipPtr; hStarShip = Build (&race_q[0], SIS_SHIP_ID); if (!hStarShip) return 0; StarShipPtr = LockStarShip (&race_q[0], hStarShip); StarShipPtr->which_side = GOOD_GUY; StarShipPtr->captains_name_index = 0; UnlockStarShip (&race_q[0], hStarShip); return hStarShip; }
HSTARSHIP GetStarShipFromIndex (PQUEUE pShipQ, COUNT Index) { HSTARSHIP hStarShip, hNextShip; for (hStarShip = GetHeadLink (pShipQ); Index > 0 && hStarShip; hStarShip = hNextShip, --Index) { STARSHIPPTR StarShipPtr; StarShipPtr = LockStarShip (pShipQ, hStarShip); hNextShip = _GetSuccLink (StarShipPtr); UnlockStarShip (pShipQ, hStarShip); } return (hStarShip); }
BYTE NameCaptain (PQUEUE pQueue, STARSHIPPTR StarShipPtr) { BYTE name_index; HSTARSHIP hStarShip; do { HSTARSHIP hNextShip; name_index = PickCaptainName (); for (hStarShip = GetHeadLink (pQueue); hStarShip; hStarShip = hNextShip) { STARSHIPPTR TestShipPtr; TestShipPtr = LockStarShip (pQueue, hStarShip); hNextShip = _GetSuccLink (TestShipPtr); if (TestShipPtr->RaceResIndex == StarShipPtr->RaceResIndex) { BOOLEAN SameName; if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE) SameName = (BOOLEAN)( name_index == TestShipPtr->captains_name_index ); else SameName = (BOOLEAN)( name_index == StarShipCaptain (TestShipPtr) ); if (SameName) { UnlockStarShip (pQueue, hStarShip); break; } } UnlockStarShip (pQueue, hStarShip); } } while (hStarShip); return (name_index); }
// Returns the <index>th available ship in the queue. static HSTARSHIP MeleeShipByUsedIndex (const QUEUE *queue, COUNT index) { HSTARSHIP hShip; HSTARSHIP hNextShip; for (hShip = GetHeadLink (queue); hShip != 0; hShip = hNextShip) { STARSHIP *StarShipPtr = LockStarShip (queue, hShip); if ((StarShipPtr->SpeciesID != NO_ID) && index-- == 0) { UnlockStarShip (queue, hShip); break; } hNextShip = _GetSuccLink (StarShipPtr); UnlockStarShip (queue, hShip); } return hShip; }
COUNT GetIndexFromStarShip (PQUEUE pShipQ, HSTARSHIP hStarShip) { COUNT Index; Index = 0; while (hStarShip != GetHeadLink (pShipQ)) { HSTARSHIP hNextShip; STARSHIPPTR StarShipPtr; StarShipPtr = LockStarShip (pShipQ, hStarShip); hNextShip = _GetPredLink (StarShipPtr); UnlockStarShip (pShipQ, hStarShip); hStarShip = hNextShip; ++Index; } return (Index); }
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_FRAGMENTPTR StarShipPtr; COLOR OldColor; CONTEXT OldContext; LockMutex (GraphicsLock); s.origin = pMenuState->first_item; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), (HSTARSHIP)pMenuState->CurFrame); s.frame = StarShipPtr->ShipInfo.icons; UnlockStarShip (&GLOBAL (built_ship_q), (HSTARSHIP)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; }
HSTARSHIP Build (PQUEUE pQueue, DWORD RaceResIndex, COUNT which_player, BYTE captains_name_index) { HSTARSHIP hNewShip; if ((hNewShip = AllocStarShip (pQueue)) != 0) { STARSHIPPTR StarShipPtr; StarShipPtr = LockStarShip (pQueue, hNewShip); memset (StarShipPtr, 0, GetLinkSize (pQueue)); StarShipPtr->RaceResIndex = RaceResIndex; OwnStarShip (StarShipPtr, which_player, captains_name_index); UnlockStarShip (pQueue, hNewShip); PutQueue (pQueue, hNewShip); } return (hNewShip); }
static COUNT GetRaceQueueValue (const QUEUE *queue) { COUNT result; HSTARSHIP hBattleShip, hNextShip; result = 0; for (hBattleShip = GetHeadLink (queue); hBattleShip != 0; hBattleShip = hNextShip) { STARSHIP *StarShipPtr = LockStarShip (queue, hBattleShip); hNextShip = _GetSuccLink (StarShipPtr); if (StarShipPtr->SpeciesID == NO_ID) continue; // Not active any more. result += StarShipPtr->ship_cost; UnlockStarShip (queue, hBattleShip); } return result; }
// Returns the <index>th ship in the queue, or 0 if it is not available. static HSTARSHIP MeleeShipByQueueIndex (const QUEUE *queue, COUNT index) { HSTARSHIP hShip; HSTARSHIP hNextShip; for (hShip = GetHeadLink (queue); hShip != 0; hShip = hNextShip) { STARSHIP *StarShipPtr = LockStarShip (queue, hShip); if (StarShipPtr->index == index) { hNextShip = hShip; if (StarShipPtr->SpeciesID == NO_ID) hShip = 0; UnlockStarShip (queue, hNextShip); break; } hNextShip = _GetSuccLink (StarShipPtr); UnlockStarShip (queue, hShip); } return hShip; }
// Put the ship icons in the PickMeleeFrame, and create a queue // for each player. // XXX TODO: split off creating the queue into a separate function. void FillPickMeleeFrame (MeleeSetup *setup) { COUNT i; CONTEXT OldContext; OldContext = SetContext (OffScreenContext); for (i = 0; i < NUM_SIDES; ++i) { COUNT side; COUNT sideI; RECT r; TEXT t; STAMP s; UNICODE buf[30]; FleetShipIndex index; sideI = GetPlayerOrder (i); side = !sideI; s.frame = SetAbsFrameIndex (PickMeleeFrame, side); SetContextFGFrame (s.frame); GetFrameRect (s.frame, &r); t.baseline.x = r.extent.width >> 1; t.baseline.y = r.extent.height - NAME_AREA_HEIGHT + RES_SCALE(4); r.corner.x += RES_SCALE(2); r.corner.y += RES_SCALE(2); r.extent.width -= RES_SCALE((2 * 2) + (RES_DESCALE(ICON_WIDTH) + 2) + 1); // JMS_GFX r.extent.height -= RES_SCALE(2 * 2) + NAME_AREA_HEIGHT; // JMS_GFX SetContextForeGroundColor (PICK_BG_COLOR); DrawFilledRectangle (&r); r.corner.x += RES_SCALE(2); // JMS_GFX r.extent.width += RES_SCALE((RES_DESCALE(ICON_WIDTH) + 2) - (2 * 2)); // JMS_GFX r.corner.y += r.extent.height; r.extent.height = NAME_AREA_HEIGHT; DrawFilledRectangle (&r); // Team name at the bottom of the frame: t.align = ALIGN_CENTER; t.pStr = MeleeSetup_getTeamName (setup, sideI); t.CharCount = (COUNT) ~0; SetContextFont (TinyFont); SetContextForeGroundColor (PICKSHIP_TEAM_NAME_TEXT_COLOR); font_DrawText (&t); // Total team value of the starting team: sprintf (buf, "%u", MeleeSetup_getFleetValue (setup, sideI)); t.baseline.x = RES_SCALE(4); t.baseline.y = RES_SCALE(7); t.align = ALIGN_LEFT; t.pStr = buf; t.CharCount = (COUNT)~0; SetContextForeGroundColor (PICKSHIP_TEAM_START_VALUE_COLOR); font_DrawText (&t); assert (CountLinks (&race_q[side]) == 0); for (index = 0; index < MELEE_FLEET_SIZE; index++) { MeleeShip StarShip; StarShip = MeleeSetup_getShip (setup, sideI, index); if (StarShip == MELEE_NONE) continue; { BYTE row, col; BYTE ship_cost; HMASTERSHIP hMasterShip; HSTARSHIP hBuiltShip; MASTER_SHIP_INFO *MasterPtr; STARSHIP *BuiltShipPtr; BYTE captains_name_index; hMasterShip = GetStarShipFromIndex (&master_q, StarShip); MasterPtr = LockMasterShip (&master_q, hMasterShip); captains_name_index = NameCaptain (&race_q[side], MasterPtr->SpeciesID); hBuiltShip = Build (&race_q[side], MasterPtr->SpeciesID); // Draw the icon. row = PickMelee_GetShipRow (index); col = PickMelee_GetShipColumn (index); s.origin.x = RES_SCALE(4) + ((ICON_WIDTH + RES_SCALE(2)) * col); // JMS_GFX s.origin.y = RES_SCALE(10) + ((ICON_HEIGHT + RES_SCALE(2)) * row); s.frame = MasterPtr->ShipInfo.icons; DrawStamp (&s); ship_cost = MasterPtr->ShipInfo.ship_cost; UnlockMasterShip (&master_q, hMasterShip); BuiltShipPtr = LockStarShip (&race_q[side], hBuiltShip); BuiltShipPtr->index = index; BuiltShipPtr->ship_cost = ship_cost; BuiltShipPtr->playerNr = side; BuiltShipPtr->captains_name_index = captains_name_index; // The next ones are not used in Melee BuiltShipPtr->crew_level = 0; BuiltShipPtr->max_crew = 0; BuiltShipPtr->race_strings = 0; BuiltShipPtr->icons = 0; BuiltShipPtr->RaceDescPtr = 0; UnlockStarShip (&race_q[side], hBuiltShip); } } } SetContext (OldContext); }
static void ProcessInput (void) { BOOLEAN CanRunAway; size_t sideI; #ifdef NETPLAY netInput (); #endif CanRunAway = RunAwayAllowed (); for (sideI = 0; sideI < NUM_SIDES; sideI++) { HSTARSHIP hBattleShip, hNextShip; size_t cur_player = battleInputOrder[sideI]; for (hBattleShip = GetHeadLink (&race_q[cur_player]); hBattleShip != 0; hBattleShip = hNextShip) { BATTLE_INPUT_STATE InputState; STARSHIP *StarShipPtr; StarShipPtr = LockStarShip (&race_q[cur_player], hBattleShip); hNextShip = _GetSuccLink (StarShipPtr); if (StarShipPtr->hShip) { // TODO: review and see if we have to do this every frame, or // if we can do this once somewhere StarShipPtr->control = PlayerControl[cur_player]; InputState = PlayerInput[cur_player]->handlers->frameInput ( PlayerInput[cur_player], StarShipPtr); #if CREATE_JOURNAL JournalInput (InputState); #endif /* CREATE_JOURNAL */ #ifdef NETPLAY if (!(PlayerControl[cur_player] & NETWORK_CONTROL)) { BattleInputBuffer *bib = getBattleInputBuffer(cur_player); Netplay_NotifyAll_battleInput (InputState); flushPacketQueues (); BattleInputBuffer_push (bib, InputState); // Add this input to the end of the buffer. BattleInputBuffer_pop (bib, &InputState); // Get the input from the front of the buffer. } #endif StarShipPtr->ship_input_state = 0; if (StarShipPtr->RaceDescPtr->ship_info.crew_level) { if (InputState & BATTLE_LEFT) StarShipPtr->ship_input_state |= LEFT; else if (InputState & BATTLE_RIGHT) StarShipPtr->ship_input_state |= RIGHT; if (InputState & BATTLE_THRUST) StarShipPtr->ship_input_state |= THRUST; if (InputState & BATTLE_WEAPON) StarShipPtr->ship_input_state |= WEAPON; if (InputState & BATTLE_SPECIAL) StarShipPtr->ship_input_state |= SPECIAL; if (InputState & BATTLE_DOWN) StarShipPtr->ship_input_state |= DOWN; // JMS_KEYS: Down key is now in use! if (CanRunAway && cur_player == 0 && (InputState & BATTLE_ESCAPE)) DoRunAway (StarShipPtr); } } UnlockStarShip (&race_q[cur_player], hBattleShip); } } #ifdef NETPLAY flushPacketQueues (); #endif if (GLOBAL (CurrentActivity) & (CHECK_LOAD | CHECK_ABORT)) GLOBAL (CurrentActivity) &= ~IN_BATTLE; }
COUNT ActivateStarShip (COUNT which_ship, SIZE state) { HSTARSHIP hStarShip, hNextShip; hStarShip = GetStarShipFromIndex ( &GLOBAL (avail_race_q), which_ship ); if (hStarShip) { switch (state) { case SPHERE_TRACKING: case SPHERE_KNOWN: { EXTENDED_SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (EXTENDED_SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (avail_race_q), hStarShip ); if (state == SPHERE_KNOWN) which_ship = StarShipPtr->ShipInfo.known_strength; else if (StarShipPtr->ShipInfo.actual_strength == 0) { if (!(StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY))) which_ship = 0; } else if (StarShipPtr->ShipInfo.known_strength == 0 && StarShipPtr->ShipInfo.actual_strength != (COUNT)~0) { StarShipPtr->ShipInfo.known_strength = 1; StarShipPtr->ShipInfo.known_loc = StarShipPtr->ShipInfo.loc; } UnlockStarShip ( &GLOBAL (avail_race_q), hStarShip ); return (which_ship); } case ESCORT_WORTH: which_ship = 0; case ESCORTING_FLAGSHIP: { COUNT ShipCost[] = { RACE_SHIP_COST }; for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip; hStarShip = hNextShip) { BYTE ship_type; SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hStarShip ); hNextShip = _GetSuccLink (StarShipPtr); if (state == ESCORT_WORTH) which_ship += ShipCost[GET_RACE_ID (StarShipPtr)]; else ship_type = GET_RACE_ID (StarShipPtr); UnlockStarShip ( &GLOBAL (built_ship_q), hStarShip ); if (state != ESCORT_WORTH && (COUNT)ship_type == which_ship) return (1); } return (state == ESCORTING_FLAGSHIP ? 0 : which_ship); } case FEASIBILITY_STUDY: return (MAX_BUILT_SHIPS - CountLinks (&GLOBAL (built_ship_q))); default: { SHIP_FRAGMENTPTR StarShipPtr; if (state <= 0) { StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (avail_race_q), hStarShip ); if (state == CHECK_ALLIANCE) { state = StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY); UnlockStarShip ( &GLOBAL (avail_race_q), hStarShip ); return ((COUNT)state); } else if (StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY)) { StarShipPtr->ShipInfo.ship_flags &= ~(GOOD_GUY | BAD_GUY); if (state == 0) StarShipPtr->ShipInfo.ship_flags |= GOOD_GUY; else { StarShipPtr->ShipInfo.ship_flags |= BAD_GUY; if (which_ship == ORZ_SHIP) { BOOLEAN ShipRemoved; ShipRemoved = FALSE; for (hStarShip = GetHeadLink ( &GLOBAL (built_ship_q )); hStarShip; hStarShip = hNextShip) { BOOLEAN RemoveShip; SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hStarShip ); hNextShip = _GetSuccLink (StarShipPtr); RemoveShip = (BOOLEAN)( GET_RACE_ID (StarShipPtr) == ORZ_SHIP ); UnlockStarShip ( &GLOBAL (built_ship_q), hStarShip ); if (RemoveShip) { ShipRemoved = TRUE; RemoveQueue ( &GLOBAL (built_ship_q), hStarShip ); FreeStarShip ( &GLOBAL (built_ship_q), hStarShip ); } } if (ShipRemoved) { SetSemaphore (GraphicsSem); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); ClearSemaphore (GraphicsSem); } } } } UnlockStarShip ( &GLOBAL (avail_race_q), hStarShip ); } else { BYTE which_window; COUNT i; which_window = 0; for ( i = 0; i < (COUNT)state && ( hStarShip = CloneShipFragment ( (COUNT)which_ship, (PQUEUE)(&GLOBAL (built_ship_q)), (BYTE) ( ( which_ship == SPATHI_SHIP && GET_GAME_STATE (FOUND_PLUTO_SPATHI) ) == 1 ? 1 : 0 ) ) ); i++ ) { HSTARSHIP hOldShip; RemoveQueue ( &GLOBAL (built_ship_q), hStarShip ); while ((hOldShip = GetStarShipFromIndex ( &GLOBAL (built_ship_q), which_window++ ))) { BYTE win_loc; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hOldShip ); win_loc = GET_GROUP_LOC (StarShipPtr); UnlockStarShip ( &GLOBAL (built_ship_q), hOldShip ); if (which_window <= win_loc) break; } StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hStarShip ); SET_GROUP_LOC (StarShipPtr, which_window - 1); if (which_ship == SPATHI_SHIP && GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1) { OwnStarShip (StarShipPtr, GOOD_GUY, NAME_OFFSET + NUM_CAPTAINS_NAMES); } UnlockStarShip ( &GLOBAL (built_ship_q), hStarShip ); InsertQueue ( &GLOBAL (built_ship_q), hStarShip, hOldShip ); } SetSemaphore (GraphicsSem); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); ClearSemaphore (GraphicsSem); return (i); } break; } } return (1); } return (0); }
static BOOLEAN DoModifyRoster (PMENU_STATE pMS) { BYTE NewState; SBYTE sx, sy; RECT r; STAMP s; SHIP_FRAGMENTPTR StarShipPtr; BOOLEAN select, cancel, up, down, 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]; if (pMS->Initialized && (pMS->CurState & SHIP_TOGGLE)) { SetMenuSounds (MENU_SOUND_UP | MENU_SOUND_DOWN, MENU_SOUND_SELECT | MENU_SOUND_CANCEL); } else { SetMenuSounds (MENU_SOUND_ARROWS, 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_PTR, (FRAME)0); RosterCleanup (pMS); pMS->CurFrame = 0; DrawStatusMessage (NULL_PTR); UnlockMutex (GraphicsLock); return FALSE; } else if (select || cancel) { LockMutex (GraphicsLock); pMS->CurState ^= SHIP_TOGGLE; if (!(pMS->CurState & SHIP_TOGGLE)) SetFlashRect (NULL_PTR, (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) { sy = -1; if (GLOBAL_SIS (CrewEnlisted)) delta = 1; else failed = TRUE; } else if (down) { sy = 1; if (GLOBAL_SIS (CrewEnlisted) < GetCPodCapacity (NULL_PTR)) delta = -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 { PPOINT pship_pos; NewState = pMS->CurState; sx = (SBYTE)((pMS->delta_item + 1) >> 1); if (horiz) { pship_pos = (PPOINT)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 = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), (HSTARSHIP)pMS->CurFrame ); s.frame = StarShipPtr->ShipInfo.icons; UnlockStarShip ( &GLOBAL (built_ship_q), (HSTARSHIP)pMS->CurFrame ); DrawStamp (&s); SelectSupport: pship_pos = (PPOINT)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; }
/* * What this function does depends on the value of the 'state' argument: * SPHERE_TRACKING: * The sphere of influence for the race for 'which_ship' will be shown * on the starmap in the future. * The value returned is 'which_ship', unless the type of ship is only * available in SuperMelee, in which case 0 is returned. * SPHERE_KNOWN: * The size of the fleet of the race of 'which_ship' when the starmap was * last checked is returned. * ESCORT_WORTH: * The total value of all the ships escorting the SIS is returned. * 'which_ship' is ignored. * ESCORTING_FLAGSHIP: * Test if a ship of type 'which_ship' is among the escorts of the SIS * 0 is returned if false, 1 if true. * FEASIBILITY_STUDY: * Test if the SIS can have an escort of type 'which_ship'. * 0 is returned if 'which_ship' is not available. * Otherwise, the number of ships that can be added is returned. * CHECK_ALLIANCE: * Test the alliance status of the race of 'which_ship'. * Either GOOD_GUY (allied) or BAD_GUY (not allied) is returned. * 0: * Ally with the race of 'which_ship'. This makes their ship available * for building in the shipyard. * -1: * End an alliance with the race of 'which_ship'. This ends the possibility * of building their ships in the shipyard. For the Orz also the ships the * player has with him will disappear. * any other positive number: * Give the player this much ships of type 'which_ship'. If it's */ COUNT ActivateStarShip (COUNT which_ship, SIZE state) { HSTARSHIP hStarShip, hNextShip; hStarShip = GetStarShipFromIndex ( &GLOBAL (avail_race_q), which_ship ); if (hStarShip) { switch (state) { case SPHERE_TRACKING: case SPHERE_KNOWN: { EXTENDED_SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (EXTENDED_SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (avail_race_q), hStarShip); if (state == SPHERE_KNOWN) which_ship = StarShipPtr->ShipInfo.known_strength; else if (StarShipPtr->ShipInfo.actual_strength == 0) { if (!(StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY))) which_ship = 0; } else if (StarShipPtr->ShipInfo.known_strength == 0 && StarShipPtr->ShipInfo.actual_strength != (COUNT)~0) { StarShipPtr->ShipInfo.known_strength = 1; StarShipPtr->ShipInfo.known_loc = StarShipPtr->ShipInfo.loc; } UnlockStarShip (&GLOBAL (avail_race_q), hStarShip); return (which_ship); } case ESCORT_WORTH: { COUNT ShipCost[] = { RACE_SHIP_COST }; COUNT total = 0; for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip; hStarShip = hNextShip) { SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (SHIP_FRAGMENTPTR) LockStarShip ( &GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr); total += ShipCost[GET_RACE_ID (StarShipPtr)]; UnlockStarShip (&GLOBAL (built_ship_q), hStarShip); } return total; } case ESCORTING_FLAGSHIP: { for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)); hStarShip; hStarShip = hNextShip) { BYTE ship_type; SHIP_FRAGMENTPTR StarShipPtr; StarShipPtr = (SHIP_FRAGMENTPTR) LockStarShip ( &GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr); ship_type = GET_RACE_ID (StarShipPtr); UnlockStarShip (&GLOBAL (built_ship_q), hStarShip); if ((COUNT) ship_type == which_ship) return 1; } return 0; } case FEASIBILITY_STUDY: return (MAX_BUILT_SHIPS - CountLinks (&GLOBAL (built_ship_q))); default: { SHIP_FRAGMENTPTR StarShipPtr; if (state <= 0) { StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (avail_race_q), hStarShip ); if (state == CHECK_ALLIANCE) { state = StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY); UnlockStarShip (&GLOBAL (avail_race_q), hStarShip); return ((COUNT)state); } else if (StarShipPtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY)) { StarShipPtr->ShipInfo.ship_flags &= ~(GOOD_GUY | BAD_GUY); if (state == 0) StarShipPtr->ShipInfo.ship_flags |= GOOD_GUY; else { StarShipPtr->ShipInfo.ship_flags |= BAD_GUY; if (which_ship == ORZ_SHIP) { BOOLEAN ShipRemoved; ShipRemoved = FALSE; for (hStarShip = GetHeadLink ( &GLOBAL (built_ship_q)); hStarShip; hStarShip = hNextShip) { BOOLEAN RemoveShip; SHIP_FRAGMENTPTR StarShipPtr2; StarShipPtr2 = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hStarShip); hNextShip = _GetSuccLink (StarShipPtr2); RemoveShip = (BOOLEAN) ( GET_RACE_ID (StarShipPtr2) == ORZ_SHIP); UnlockStarShip (&GLOBAL (built_ship_q), hStarShip); if (RemoveShip) { ShipRemoved = TRUE; RemoveQueue (&GLOBAL (built_ship_q), hStarShip); FreeStarShip (&GLOBAL (built_ship_q), hStarShip); } } if (ShipRemoved) { LockMutex (GraphicsLock); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); UnlockMutex (GraphicsLock); } } } } UnlockStarShip (&GLOBAL (avail_race_q), hStarShip); } else { /* 'state > 0', add ships to the escorts */ BYTE which_window; COUNT i; which_window = 0; for (i = 0; i < (COUNT)state; i++) { HSTARSHIP hOldShip; BYTE crewLevel; if (which_ship == SPATHI_SHIP && GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1) crewLevel = 1; // Only Fwiffo is on board. else crewLevel = 0; // Crewed to the max hStarShip = CloneShipFragment((COUNT) which_ship, &GLOBAL (built_ship_q), crewLevel); if (!hStarShip) break; RemoveQueue (&GLOBAL (built_ship_q), hStarShip); while ((hOldShip = GetStarShipFromIndex ( &GLOBAL (built_ship_q), which_window++))) { BYTE win_loc; StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hOldShip); win_loc = GET_GROUP_LOC (StarShipPtr); UnlockStarShip (&GLOBAL (built_ship_q), hOldShip); if (which_window <= win_loc) break; } StarShipPtr = (SHIP_FRAGMENTPTR)LockStarShip ( &GLOBAL (built_ship_q), hStarShip); SET_GROUP_LOC (StarShipPtr, which_window - 1); if (which_ship == SPATHI_SHIP && GET_GAME_STATE (FOUND_PLUTO_SPATHI) == 1) { OwnStarShip (StarShipPtr, GOOD_GUY, NAME_OFFSET + NUM_CAPTAINS_NAMES); } UnlockStarShip (&GLOBAL (built_ship_q), hStarShip); InsertQueue (&GLOBAL (built_ship_q), hStarShip, hOldShip); } LockMutex (GraphicsLock); DeltaSISGauges (UNDEFINED_DELTA, UNDEFINED_DELTA, UNDEFINED_DELTA); UnlockMutex (GraphicsLock); return (i); } break; } } return 1; } return 0; }