Untangling ship queues, stage 3: Fully unaliased STARSHIP, SHIP_FRAGMENT and EXTENDED_SHIP_FRAGMENT

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2782 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2007-06-23 01:44:11 +00:00
parent 7bea238090
commit 51192258e7
18 changed files with 130 additions and 173 deletions
+58 -37
View File
@@ -26,29 +26,40 @@
// Allocate a new STARSHIP and put it in the queue.
HSTARSHIP
Build (QUEUE *pQueue, DWORD RaceResIndex, COUNT which_player, BYTE
captains_name_index)
Build (QUEUE *pQueue, DWORD RaceResIndex)
{
HSTARSHIP hNewShip;
void *LinkPtr;
hNewShip = AllocStarShip (pQueue);
if (hNewShip != 0)
if (!hNewShip)
return 0;
LinkPtr = LockStarShip (pQueue, hNewShip);
memset (LinkPtr, 0, GetLinkSize (pQueue));
if (GetLinkSize (pQueue) == sizeof (STARSHIP))
{
STARSHIP *StarShipPtr;
// XXX: STARSHIP refactor; The last remaining aliasing between
// STARSHIP and SHIP_FRAGMENT structs
StarShipPtr = LockStarShip (pQueue, hNewShip);
memset (StarShipPtr, 0, GetLinkSize (pQueue));
STARSHIP *StarShipPtr = (STARSHIP *) LinkPtr;
StarShipPtr->RaceResIndex = RaceResIndex;
OwnStarShip (StarShipPtr, which_player, captains_name_index);
}
else if (GetLinkSize (pQueue) == sizeof (SHIP_FRAGMENT))
{
SHIP_FRAGMENT *FragPtr = (SHIP_FRAGMENT *) LinkPtr;
FragPtr->RaceResIndex = RaceResIndex;
}
else if (GetLinkSize (pQueue) == sizeof (EXTENDED_SHIP_FRAGMENT))
{
EXTENDED_SHIP_FRAGMENT *FragPtr = (EXTENDED_SHIP_FRAGMENT *) LinkPtr;
FragPtr->RaceResIndex = RaceResIndex;
}
else
assert (0 && "Build(): unknown queue type!");
UnlockStarShip (pQueue, hNewShip);
PutQueue (pQueue, hNewShip);
}
return (hNewShip);
return hNewShip;
}
HLINK
@@ -325,39 +336,43 @@ BYTE
NameCaptain (QUEUE *pQueue, DWORD RaceResIndex)
{
BYTE name_index;
HSTARSHIP hStarShip;
HLINK hStarShip;
do
{
HSTARSHIP hNextShip;
HLINK hNextShip;
name_index = PickCaptainName ();
for (hStarShip = GetHeadLink (pQueue); hStarShip; hStarShip = hNextShip)
{
STARSHIP *TestShipPtr;
LINK *LinkPtr;
BYTE test_name_index;
TestShipPtr = LockStarShip (pQueue, hStarShip);
hNextShip = _GetSuccLink (TestShipPtr);
if (TestShipPtr->RaceResIndex == RaceResIndex)
LinkPtr = LockLink (pQueue, hStarShip);
hNextShip = _GetSuccLink (LinkPtr);
if (GetLinkSize (pQueue) == sizeof (STARSHIP))
{
BOOLEAN SameName;
// XXX: STARSHIP refactor; The last remaining aliasing between
// STARSHIP and SHIP_FRAGMENT structs
// This hack will not be needed once
// STARSHIP maintains captain/side permanently
if (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE)
SameName = (name_index == TestShipPtr->captains_name_index);
STARSHIP *TestShipPtr = (STARSHIP *) LinkPtr;
if (TestShipPtr->RaceResIndex != RaceResIndex)
continue;
test_name_index = TestShipPtr->captains_name_index;
}
else if (GetLinkSize (pQueue) == sizeof (SHIP_FRAGMENT))
{
SHIP_FRAGMENT *TestShipPtr = (SHIP_FRAGMENT *) LinkPtr;
if (TestShipPtr->RaceResIndex != RaceResIndex)
continue;
test_name_index = TestShipPtr->captains_name_index;
}
else
SameName = (name_index == StarShipCaptain (TestShipPtr));
assert (0 && "NameCaptain(): unknown queue type!");
if (SameName)
if (name_index == test_name_index)
{
UnlockStarShip (pQueue, hStarShip);
UnlockLink (pQueue, hStarShip);
break;
}
}
UnlockStarShip (pQueue, hStarShip);
UnlockLink (pQueue, hStarShip);
}
} while (hStarShip);
@@ -371,6 +386,7 @@ CloneShipFragment (COUNT shipIndex, QUEUE *pDstQueue, COUNT crew_level)
{
HSTARSHIP hStarShip, hBuiltShip;
EXTENDED_SHIP_FRAGMENT *TemplatePtr;
BYTE captains_name_index;
hStarShip = GetStarShipFromIndex (&GLOBAL (avail_race_q), shipIndex);
if (hStarShip == 0)
@@ -378,15 +394,20 @@ CloneShipFragment (COUNT shipIndex, QUEUE *pDstQueue, COUNT crew_level)
TemplatePtr = (EXTENDED_SHIP_FRAGMENT *) LockStarShip (
&GLOBAL (avail_race_q), hStarShip);
hBuiltShip = Build (pDstQueue, TemplatePtr->RaceResIndex,
TemplatePtr->ShipInfo.ship_flags & (GOOD_GUY | BAD_GUY),
(BYTE)(shipIndex == SAMATRA_SHIP ?
0 : NameCaptain (pDstQueue, TemplatePtr->RaceResIndex)));
if (shipIndex == SAMATRA_SHIP)
captains_name_index = 0;
else
captains_name_index = NameCaptain (pDstQueue,
TemplatePtr->RaceResIndex);
hBuiltShip = Build (pDstQueue, TemplatePtr->RaceResIndex);
if (hBuiltShip)
{
SHIP_FRAGMENT *ShipFragPtr;
ShipFragPtr = (SHIP_FRAGMENT*) LockStarShip (pDstQueue, hBuiltShip);
ShipFragPtr->which_side = TemplatePtr->ShipInfo.ship_flags &
(GOOD_GUY | BAD_GUY);
ShipFragPtr->captains_name_index = captains_name_index;
// XXX: SHIP_INFO struct copy
ShipFragPtr->ShipInfo.race_strings = TemplatePtr->ShipInfo.race_strings;
ShipFragPtr->ShipInfo.icons = TemplatePtr->ShipInfo.icons;
@@ -445,7 +466,7 @@ SetEscortCrewComplement (COUNT which_ship, COUNT crew_level, BYTE captain)
if (hStarShip)
{
StarShipPtr->ShipInfo.crew_level = crew_level;
OwnStarShip (StarShipPtr, StarShipPlayer (StarShipPtr), captain);
StarShipPtr->captains_name_index = captain;
UnlockStarShip (&GLOBAL (built_ship_q), hStarShip);
}
else
+1 -10
View File
@@ -33,20 +33,11 @@
#define NAME_OFFSET 5
#define NUM_CAPTAINS_NAMES 16
// XXX: STARSHIP refactor; These three alias STARSHIP and SHIP_FRAGMENT
#define OwnStarShip(S,p,n) \
(S)->s.Player = (p); \
(S)->s.Captain = (n);
#define StarShipCaptain(S) \
(S)->s.Captain
#define StarShipPlayer(S) \
(S)->s.Player
#define PickCaptainName() (((COUNT)TFB_Random () \
& (NUM_CAPTAINS_NAMES - 1)) \
+ NAME_OFFSET)
extern HSTARSHIP Build (QUEUE *pQueue, DWORD RaceResIndex, COUNT
which_player, BYTE captains_name_index);
extern HSTARSHIP Build (QUEUE *pQueue, DWORD RaceResIndex);
extern HSTARSHIP CloneShipFragment (COUNT shipIndex, QUEUE *pDstQueue,
COUNT crew_level);
extern HLINK GetStarShipFromIndex (QUEUE *pShipQ, COUNT Index);
+6 -7
View File
@@ -131,13 +131,12 @@ BuildBattle (COUNT which_player)
hBuiltShip = Build (&race_q[which_player],
GET_RACE_ID (FragPtr) == SAMATRA_SHIP ?
SAMATRA_RES_INDEX : FragPtr->RaceResIndex,
1 << which_player, StarShipCaptain (FragPtr));
SAMATRA_RES_INDEX : FragPtr->RaceResIndex);
if (hBuiltShip)
{
BuiltShipPtr = LockStarShip (&race_q[which_player], hBuiltShip);
BuiltShipPtr->captains_name_index = StarShipCaptain (BuiltShipPtr);
BuiltShipPtr->which_side = StarShipPlayer (BuiltShipPtr);
BuiltShipPtr->captains_name_index = FragPtr->captains_name_index;
BuiltShipPtr->which_side = 1 << which_player;
if (FragPtr->ShipInfo.crew_level != INFINITE_FLEET)
BuiltShipPtr->crew_level = FragPtr->ShipInfo.crew_level;
else /* if infinite ships */
@@ -157,11 +156,11 @@ BuildBattle (COUNT which_player)
}
if (which_player == 0
&& (hBuiltShip = Build (&race_q[0], SIS_RES_INDEX, GOOD_GUY, 0)))
&& (hBuiltShip = Build (&race_q[0], SIS_RES_INDEX)))
{
BuiltShipPtr = LockStarShip (&race_q[0], hBuiltShip);
BuiltShipPtr->captains_name_index = StarShipCaptain (BuiltShipPtr);
BuiltShipPtr->which_side = StarShipPlayer (BuiltShipPtr);
BuiltShipPtr->captains_name_index = 0;
BuiltShipPtr->which_side = GOOD_GUY;
BuiltShipPtr->crew_level = 0;
BuiltShipPtr->max_crew = 0;
// Crew will be copied directly from
+1 -1
View File
@@ -224,7 +224,7 @@ InitSIS (void)
ship_ref = YEHAT_SHIP_INDEX;
else /* (i == num_ships - 1) */
ship_ref = PROBE_RES_INDEX;
hStarShip = Build (&GLOBAL (avail_race_q), ship_ref, 0, 0);
hStarShip = Build (&GLOBAL (avail_race_q), ship_ref);
if (hStarShip)
{
EXTENDED_SHIP_FRAGMENT *FleetPtr;
+12 -8
View File
@@ -91,8 +91,8 @@ ReadShipFragment (void *fp, SHIP_FRAGMENT *FragPtr)
BYTE tmpb;
// Read SHIP_FRAGMENT elements
sread_16 (fp, &FragPtr->s.Player);
sread_8 (fp, &FragPtr->s.Captain);
sread_16 (fp, &FragPtr->which_side);
sread_8 (fp, &FragPtr->captains_name_index);
sread_8 (fp, NULL); /* padding */
// Read SHIP_INFO elements
sread_16 (fp, &FragPtr->ShipInfo.ship_flags);
@@ -112,8 +112,8 @@ static void
WriteShipFragment (void *fp, const SHIP_FRAGMENT *FragPtr)
{
// Write SHIP_FRAGMENT elements
swrite_16 (fp, FragPtr->s.Player);
swrite_8 (fp, FragPtr->s.Captain);
swrite_16 (fp, FragPtr->which_side);
swrite_8 (fp, FragPtr->captains_name_index);
swrite_8 (fp, 0); /* padding */
// Write SHIP_INFO elements
swrite_16 (fp, FragPtr->ShipInfo.ship_flags);
@@ -492,6 +492,7 @@ GetGroupInfo (DWORD offset, BYTE which_group)
}
else
{
/* Read IP groups into npc_built_ship_q */
for (which_group = 1; which_group <= GH.NumGroups;
++which_group)
{
@@ -511,10 +512,13 @@ GetGroupInfo (DWORD offset, BYTE which_group)
&GLOBAL (npc_built_ship_q), 0);
FragPtr = (SHIP_FRAGMENT*) LockStarShip (
&GLOBAL (npc_built_ship_q), hStarShip);
// XXX: STARSHIP refactor; this is probably needed
// because SHIP_INFO.ship_flags is used for
// group_counter
OwnStarShip (FragPtr, BAD_GUY, 0);
// XXX: STARSHIP refactor; Cannot find what might be
// using this info. Looks unused.
FragPtr->which_side = BAD_GUY;
FragPtr->captains_name_index = 0;
// XXX: CloneShipFragment() may set ship_flags in the
// future, and it will collide with group_counter,
// but it is reset a few lines below
SET_GROUP_ID (FragPtr, which_group);
rand_val = TFB_Random ();
+18 -2
View File
@@ -133,6 +133,23 @@ UninitSpace (void)
}
}
HSTARSHIP
BuildSIS (void)
{
HSTARSHIP hStarShip;
STARSHIP *StarShipPtr;
hStarShip = Build (&race_q[0], SIS_RES_INDEX);
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;
}
SIZE
InitShips (void)
{
@@ -151,8 +168,7 @@ InitShips (void)
ReinitQueue (&race_q[0]);
ReinitQueue (&race_q[1]);
Build (&race_q[0], SIS_RES_INDEX, GOOD_GUY, 0);
BuildSIS ();
LoadHyperspace ();
num_ships = 1;
+2 -2
View File
@@ -153,8 +153,8 @@ LoadShipQueue (DECODE_REF fh, QUEUE *pQueue)
FragPtr = (SHIP_FRAGMENT*) LockStarShip (pQueue, hStarShip);
// Read SHIP_FRAGMENT elements
cread_16 (fh, &FragPtr->s.Player);
cread_8 (fh, &FragPtr->s.Captain);
cread_16 (fh, &FragPtr->which_side);
cread_8 (fh, &FragPtr->captains_name_index);
cread_8 (fh, NULL); /* padding */
// Read SHIP_INFO elements
cread_16 (fh, &FragPtr->ShipInfo.ship_flags);
+1 -1
View File
@@ -47,7 +47,7 @@ LoadMasterShipList (void (* YieldProcessing)(void))
SHIP_FRAGMENT *BuiltFragPtr;
RACE_DESC *RDPtr;
hBuiltShip = Build (&master_q, MAKE_RESOURCE (rp++, rt, ri++), 0, 0);
hBuiltShip = Build (&master_q, MAKE_RESOURCE (rp++, rt, ri++));
if (!hBuiltShip)
continue;
+5 -5
View File
@@ -2121,12 +2121,13 @@ BuildAndDrawShipList (MELEE_STATE *pMS)
HSTARSHIP hStarShip, hBuiltShip;
SHIP_FRAGMENT *FragPtr;
STARSHIP *BuiltShipPtr;
BYTE captains_name_index;
hStarShip = GetStarShipFromIndex (&master_q, StarShip);
FragPtr = (SHIP_FRAGMENT *) LockStarShip (&master_q, hStarShip);
hBuiltShip = Build (&race_q[side], FragPtr->RaceResIndex,
1 << side,
NameCaptain (&race_q[side], FragPtr->RaceResIndex));
captains_name_index = NameCaptain (&race_q[side],
FragPtr->RaceResIndex);
hBuiltShip = Build (&race_q[side], FragPtr->RaceResIndex);
// Draw the icon.
row = GetShipRow (index);
@@ -2143,8 +2144,7 @@ BuildAndDrawShipList (MELEE_STATE *pMS)
BuiltShipPtr->index = index;
BuiltShipPtr->ship_cost = ship_cost;
BuiltShipPtr->which_side = 1 << side;
BuiltShipPtr->captains_name_index =
StarShipCaptain (BuiltShipPtr);
BuiltShipPtr->captains_name_index = captains_name_index;
// The next ones are not used in Melee
BuiltShipPtr->crew_level = 0;
BuiltShipPtr->max_crew = 0;
-2
View File
@@ -30,8 +30,6 @@
#include "netplay/proto/ready.h"
#include "netplay/proto/reset.h"
#include "build.h"
// for StarShipPlayer()
#include "controls.h"
// for BATTLE_INPUT_STATE
#include "init.h"
-18
View File
@@ -660,24 +660,6 @@ GetMeleeStarShips (COUNT playerMask, HSTARSHIP *ships)
// Aborting.
GLOBAL (CurrentActivity) &= ~IN_BATTLE;
}
else
{
STARSHIP *StarShipPtr;
// XXX: STARSHIP refactor; This whole thing is probably not needed
// once captain/side are maintained permanently in STARSHIP
for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
{
if (!gmstate.player[playerI].selecting)
continue;
StarShipPtr = LockStarShip (&race_q[playerI], ships[playerI]);
OwnStarShip (StarShipPtr, 1 << playerI,
StarShipPtr->captains_name_index);
StarShipPtr->captains_name_index = 0;
UnlockStarShip (&race_q[playerI], ships[playerI]);
}
}
#ifdef NETPLAY
for (playerI = 0; playerI < NUM_PLAYERS; playerI++)
-10
View File
@@ -434,16 +434,6 @@ GetEncounterStarShip (STARSHIP *LastStarShipPtr, COUNT which_player)
}
}
}
// XXX: STARSHIP refactor; this whole thing is not really needed
// once STARSHIP maintains captain/side permanently
if (hBattleShip)
{
SPtr = LockStarShip (&race_q[which_player], hBattleShip);
OwnStarShip (SPtr, SPtr->which_side,
SPtr->captains_name_index);
UnlockStarShip (&race_q[which_player], hBattleShip);
}
}
return (hBattleShip);
+3 -4
View File
@@ -53,11 +53,10 @@ GenerateColony (BYTE control)
SET_GROUP_MISSION (FragPtr, IN_ORBIT);
SET_GROUP_LOC (FragPtr, 0 + 1); /* orbitting colony */
SET_GROUP_DEST (FragPtr, 0 + 1); /* orbitting colony */
FragPtr->ShipInfo.loc.x = FragPtr->ShipInfo.loc.y = 0;
FragPtr->ShipInfo.loc.x = 0;
FragPtr->ShipInfo.loc.y = 0;
FragPtr->ShipInfo.group_counter = 0;
UnlockStarShip (
&GLOBAL (npc_built_ship_q), hStarShip
);
UnlockStarShip (&GLOBAL (npc_built_ship_q), hStarShip);
}
break;
}
+3 -4
View File
@@ -72,11 +72,10 @@ GenerateShofixti (BYTE control)
{ /* Set old Shofixti name; his brother if Tanaka died */
SHIP_FRAGMENT *FragPtr = (SHIP_FRAGMENT *) LockStarShip (
&GLOBAL (npc_built_ship_q), hStarShip);
// XXX: STARSHIP refactor; setting BAD_GUY here is redundant
// only the captain is needed
OwnStarShip (FragPtr, BAD_GUY, NAME_OFFSET +
/* Name Tanaka or Katana (+1) */
FragPtr->captains_name_index = NAME_OFFSET +
NUM_CAPTAINS_NAMES +
(GET_GAME_STATE (SHOFIXTI_KIA) & 1));
(GET_GAME_STATE (SHOFIXTI_KIA) & 1);
UnlockStarShip (&GLOBAL (npc_built_ship_q), hStarShip);
}
+3 -8
View File
@@ -779,18 +779,13 @@ PickPlanetSide (MENU_STATE *pMS)
&GLOBAL (npc_built_ship_q), 1);
if (hStarShip)
{
BYTE captains_name_index;
COUNT which_player;
SHIP_FRAGMENT *StarShipPtr;
StarShipPtr = (SHIP_FRAGMENT *) LockStarShip (
&GLOBAL (npc_built_ship_q), hStarShip);
// XXX: GOOD_GUY/BAD_GUY was set by CloneShipFragment()
// according to avail_race_q Spathi alliance state
which_player = StarShipPlayer (StarShipPtr);
captains_name_index = NAME_OFFSET + NUM_CAPTAINS_NAMES;
// XXX: STARSHIP refactor; only the captain is needed
OwnStarShip (StarShipPtr, which_player, captains_name_index);
// Name Fwiffo
StarShipPtr->captains_name_index = NAME_OFFSET +
NUM_CAPTAINS_NAMES;
UnlockStarShip (&GLOBAL (npc_built_ship_q), hStarShip);
}
+7 -40
View File
@@ -241,8 +241,6 @@ typedef void (UNINIT_FUNC) (RACE_DESC *pRaceDesc);
struct race_desc
{
/* XXX: SHIP_INFO *must* currently be the first field in the struct.
* See why in comments of EXTENDED_SHIP_FRAGMENT. */
SHIP_INFO ship_info _ALIGNED_ANY;
CHARACTERISTIC_STUFF characteristics _ALIGNED_ANY;
DATA_STUFF ship_data _ALIGNED_ANY;
@@ -263,39 +261,21 @@ struct race_desc
typedef HLINK HSTARSHIP;
/* XXX: STARSHIP and SHIP_FRAGMENT are inter-cast
* to each other in some places. Some of those are unsafe and potentially
* destructive if the code is changed later.
* Currently, the first 4 members of each struct MUST remain the same,
* the first 2 being the queue links. Functions Build() and CloneShipFragment()
* expect these 4 members to be there.
*/
typedef struct
{
// LINK elements; must be first
HSTARSHIP pred;
HSTARSHIP succ;
DWORD RaceResIndex;
/* This field is abused to store other data when the ship
* is in GLOBAL(built_ship_q), GLOBDATA(npc_built_ship_q),
* or race_q[], namely the side this ship is on (accessed
* through StarShipPlayer()), and the captains name for
* the ship (accessed through StarShipCaptain()).
* These values are set using OwnStarShip(). */
union {
RACE_DESC *RaceDescPtr;
struct {
COUNT Player;
BYTE Captain;
} s;
};
// Ship information
UWORD which_side;
// In race_q: side the ship is on
BYTE captains_name_index;
// Also used in full-game to detect if a STARSHIP is an escort
// or the flagship (captains_name_index == 0)
COUNT crew_level;
// In full-game battles: crew left
// In SuperMelee: irrelevant
@@ -303,8 +283,6 @@ typedef struct
BYTE ship_cost;
// In Super Melee ship queue: ship cost
// In full-game: irrelevant
UWORD which_side;
// In race_q: side the ship is on
COUNT index;
// original queue index
STRING race_strings;
@@ -328,32 +306,21 @@ typedef struct
typedef struct
{
// LINK elements; must be first
HSTARSHIP pred;
HSTARSHIP succ;
DWORD RaceResIndex;
/* This field is used to store other data when the ship
* is in GLOBAL(built_ship_q) or GLOBDATA(npc_built_ship_q),
* namely the side this ship is on (accessed
* through StarShipPlayer()), and the captains name for
* the ship (accessed through StarShipCaptain()).
* These values are set using OwnStarShip(). */
union {
// XXX: only needed temporarily to maintain binary compat
// with STARSHIP for Build()
void *__tmp;
struct {
COUNT Player;
BYTE Captain;
} s;
};
COUNT which_side;
BYTE captains_name_index;
SHIP_INFO ShipInfo;
} SHIP_FRAGMENT;
typedef struct
{
// LINK elements; must be first
HSTARSHIP pred;
HSTARSHIP succ;
+2 -2
View File
@@ -135,8 +135,8 @@ SaveShipQueue (DECODE_REF fh, QUEUE *pQueue)
cwrite_16 (fh, Index);
// Write SHIP_FRAGMENT elements
cwrite_16 (fh, FragPtr->s.Player);
cwrite_8 (fh, FragPtr->s.Captain);
cwrite_16 (fh, FragPtr->which_side);
cwrite_8 (fh, FragPtr->captains_name_index);
cwrite_8 (fh, 0); /* padding */
// Write SHIP_INFO elements
cwrite_16 (fh, FragPtr->ShipInfo.ship_flags);
+1 -5
View File
@@ -385,11 +385,7 @@ spawn_ship (STARSHIP *StarShipPtr)
if (!RDPtr)
return FALSE;
// XXX: Ship captain and side are stored in RaceDescPtr, so
// get them first
StarShipPtr->captains_name_index = StarShipCaptain (StarShipPtr);
RDPtr->ship_info.ship_flags |= StarShipPlayer (StarShipPtr);
RDPtr->ship_info.ship_flags |= StarShipPtr->which_side;
StarShipPtr->RaceDescPtr = RDPtr;
StarShipPtr->ship_input_state = 0;