Restructed and normalized savegame and game-state reading/writing code; not reading/writing pointers and useless values anymore
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2390 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -924,13 +924,17 @@ typedef struct
|
||||
VELOCITY_DESC velocity;
|
||||
|
||||
DWORD BattleGroupRef;
|
||||
QUEUE avail_race_q, npc_built_ship_q;
|
||||
QUEUE avail_race_q;
|
||||
QUEUE npc_built_ship_q;
|
||||
// Non-player-character list of ships (during encounter)
|
||||
// or list of groups present in solarsys (during IP)
|
||||
QUEUE encounter_q;
|
||||
QUEUE built_ship_q;
|
||||
/* Queue of SIS escort ships */
|
||||
|
||||
BYTE GameState[(NUM_GAME_STATE_BITS + 7) >> 3];
|
||||
} GAME_STATE;
|
||||
typedef GAME_STATE *PGAME_STATE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
+116
-37
@@ -38,11 +38,95 @@ static BYTE LastEncGroup;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE NumGroups, day_index, month_index;
|
||||
BYTE NumGroups;
|
||||
BYTE day_index, month_index;
|
||||
COUNT star_index, year_index;
|
||||
// day_index, month_index, year_index specify when
|
||||
// random groups expire (if you were to leave the system
|
||||
// by going to HSpace and stay there till such time)
|
||||
// star_index is the index of a star this group header
|
||||
// applies to; ~0 means uninited
|
||||
DWORD GroupOffset[MAX_BATTLE_GROUPS + 1];
|
||||
// Absolute offsets of group definitions in a state file
|
||||
// Group 0 is actually a list of groups present in solarsys
|
||||
// Groups 1..max are definitions of actual battle groups
|
||||
// containing ships composition and status
|
||||
|
||||
// Each group has the following format:
|
||||
// 1 byte, RaceType (LastEncGroup in Group 0)
|
||||
// 1 byte, NumShips
|
||||
// Ships follow:
|
||||
// 1 byte, RaceType
|
||||
// 16 bytes, part of SHIP_FRAGMENT struct
|
||||
|
||||
} GROUP_HEADER;
|
||||
|
||||
static void
|
||||
ReadGroupHeader (PVOID fp, GROUP_HEADER* pGH)
|
||||
{
|
||||
sread_8 (fp, &pGH->NumGroups);
|
||||
sread_8 (fp, &pGH->day_index);
|
||||
sread_8 (fp, &pGH->month_index);
|
||||
sread_8 (fp, NULL); /* padding */
|
||||
sread_16 (fp, &pGH->star_index);
|
||||
sread_16 (fp, &pGH->year_index);
|
||||
sread_a32 (fp, pGH->GroupOffset, MAX_BATTLE_GROUPS + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
WriteGroupHeader (PVOID fp, GROUP_HEADER* pGH)
|
||||
{
|
||||
swrite_8 (fp, pGH->NumGroups);
|
||||
swrite_8 (fp, pGH->day_index);
|
||||
swrite_8 (fp, pGH->month_index);
|
||||
swrite_8 (fp, 0); /* padding */
|
||||
swrite_16 (fp, pGH->star_index);
|
||||
swrite_16 (fp, pGH->year_index);
|
||||
swrite_a32 (fp, pGH->GroupOffset, MAX_BATTLE_GROUPS + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
ReadShipFragment (PVOID fp, SHIP_FRAGMENTPTR FragPtr)
|
||||
{
|
||||
BYTE tmpb;
|
||||
|
||||
// Read SHIP_FRAGMENT elements
|
||||
sread_16 (fp, &FragPtr->s.Player);
|
||||
sread_8 (fp, &FragPtr->s.Captain);
|
||||
sread_8 (fp, NULL); /* padding */
|
||||
// Read SHIP_INFO elements
|
||||
sread_16 (fp, &FragPtr->ShipInfo.ship_flags);
|
||||
sread_8 (fp, &FragPtr->ShipInfo.var1);
|
||||
sread_8 (fp, &FragPtr->ShipInfo.var2);
|
||||
sread_8 (fp, &tmpb);
|
||||
FragPtr->ShipInfo.crew_level = tmpb;
|
||||
sread_8 (fp, &tmpb);
|
||||
FragPtr->ShipInfo.max_crew = tmpb;
|
||||
sread_8 (fp, &FragPtr->ShipInfo.energy_level);
|
||||
sread_8 (fp, &FragPtr->ShipInfo.max_energy);
|
||||
sread_16 (fp, &FragPtr->ShipInfo.loc.x);
|
||||
sread_16 (fp, &FragPtr->ShipInfo.loc.y);
|
||||
}
|
||||
|
||||
static void
|
||||
WriteShipFragment (PVOID fp, SHIP_FRAGMENTPTR FragPtr)
|
||||
{
|
||||
// Write SHIP_FRAGMENT elements
|
||||
swrite_16 (fp, FragPtr->s.Player);
|
||||
swrite_8 (fp, FragPtr->s.Captain);
|
||||
swrite_8 (fp, 0); /* padding */
|
||||
// Write SHIP_INFO elements
|
||||
swrite_16 (fp, FragPtr->ShipInfo.ship_flags);
|
||||
swrite_8 (fp, FragPtr->ShipInfo.var1);
|
||||
swrite_8 (fp, FragPtr->ShipInfo.var2);
|
||||
swrite_8 (fp, FragPtr->ShipInfo.crew_level);
|
||||
swrite_8 (fp, FragPtr->ShipInfo.max_crew);
|
||||
swrite_8 (fp, FragPtr->ShipInfo.energy_level);
|
||||
swrite_8 (fp, FragPtr->ShipInfo.max_energy);
|
||||
swrite_16 (fp, FragPtr->ShipInfo.loc.x);
|
||||
swrite_16 (fp, FragPtr->ShipInfo.loc.y);
|
||||
}
|
||||
|
||||
void
|
||||
InitGroupInfo (BOOLEAN FirstTime)
|
||||
{
|
||||
@@ -56,14 +140,16 @@ InitGroupInfo (BOOLEAN FirstTime)
|
||||
GH.NumGroups = 0;
|
||||
GH.star_index = (COUNT)~0;
|
||||
GH.GroupOffset[0] = 0;
|
||||
WriteStateFile (&GH, sizeof (GH), 1, fp);
|
||||
WriteGroupHeader (fp, &GH);
|
||||
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
|
||||
if (FirstTime && (fp = OpenStateFile (DEFGRPINFO_FILE, "wb")))
|
||||
{
|
||||
PutStateFileChar (0, fp);
|
||||
// Group headers cannot start with offset 0 in
|
||||
// defined group info file, so bump it
|
||||
swrite_8 (fp, 0);
|
||||
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
@@ -297,11 +383,11 @@ FlushGroupInfo (GROUP_HEADER *pGH, DWORD offset, BYTE which_group, PVOID fp)
|
||||
&GLOBAL (npc_built_ship_q), hStarShip);
|
||||
RaceType = GET_RACE_ID (FragPtr);
|
||||
SeekStateFile (fp, pGH->GroupOffset[which_group], SEEK_SET);
|
||||
WriteStateFile (&RaceType, sizeof (RaceType), 1, fp);
|
||||
swrite_8 (fp, RaceType);
|
||||
UnlockStarShip (&GLOBAL (npc_built_ship_q), hStarShip);
|
||||
}
|
||||
SeekStateFile (fp, offset, SEEK_SET);
|
||||
WriteStateFile (pGH, sizeof (*pGH), 1, fp);
|
||||
WriteGroupHeader (fp, pGH);
|
||||
#ifdef DEBUG_GROUPS
|
||||
log_add (log_Debug, "1)FlushGroupInfo(%lu): WG = %u(%lu), NG = %u, "
|
||||
"SI = %u", offset, which_group, pGH->GroupOffset[which_group],
|
||||
@@ -311,22 +397,20 @@ FlushGroupInfo (GROUP_HEADER *pGH, DWORD offset, BYTE which_group, PVOID fp)
|
||||
NumShips = (BYTE)CountLinks (&GLOBAL (npc_built_ship_q));
|
||||
|
||||
if (which_group != GROUP_LIST)
|
||||
{
|
||||
SeekStateFile (fp, pGH->GroupOffset[which_group]
|
||||
+ sizeof (LastEncGroup), SEEK_SET);
|
||||
{ // skip RaceType
|
||||
SeekStateFile (fp, pGH->GroupOffset[which_group] + 1, SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
SeekStateFile (fp, pGH->GroupOffset[0], SEEK_SET);
|
||||
WriteStateFile (&LastEncGroup, sizeof (LastEncGroup), 1, fp);
|
||||
swrite_8 (fp, LastEncGroup);
|
||||
}
|
||||
WriteStateFile (&NumShips, sizeof (NumShips), 1, fp);
|
||||
swrite_8 (fp, NumShips);
|
||||
|
||||
hStarShip = GetHeadLink (&GLOBAL (npc_built_ship_q));
|
||||
while (NumShips--)
|
||||
{
|
||||
HSTARSHIP hNextShip;
|
||||
PBYTE Ptr;
|
||||
|
||||
FragPtr = (SHIP_FRAGMENTPTR)LockStarShip (
|
||||
&GLOBAL (npc_built_ship_q), hStarShip
|
||||
@@ -334,7 +418,7 @@ FlushGroupInfo (GROUP_HEADER *pGH, DWORD offset, BYTE which_group, PVOID fp)
|
||||
hNextShip = _GetSuccLink (FragPtr);
|
||||
|
||||
RaceType = GET_RACE_ID (FragPtr);
|
||||
WriteStateFile (&RaceType, sizeof (RaceType), 1, fp);
|
||||
swrite_8 (fp, RaceType);
|
||||
|
||||
#ifdef DEBUG_GROUPS
|
||||
if (which_group == GROUP_LIST)
|
||||
@@ -346,9 +430,7 @@ FlushGroupInfo (GROUP_HEADER *pGH, DWORD offset, BYTE which_group, PVOID fp)
|
||||
GET_GROUP_MISSION (FragPtr),
|
||||
GET_GROUP_DEST (FragPtr));
|
||||
#endif /* DEBUG_GROUPS */
|
||||
Ptr = (PBYTE)&FragPtr->RaceDescPtr;
|
||||
WriteStateFile (Ptr,
|
||||
((PBYTE)&FragPtr->ShipInfo.race_strings) - Ptr, 1, fp);
|
||||
WriteShipFragment (fp, FragPtr);
|
||||
UnlockStarShip (&GLOBAL (npc_built_ship_q), hStarShip);
|
||||
hStarShip = hNextShip;
|
||||
}
|
||||
@@ -372,7 +454,7 @@ GetGroupInfo (DWORD offset, BYTE which_group)
|
||||
SHIP_FRAGMENTPTR FragPtr;
|
||||
|
||||
SeekStateFile (fp, offset, SEEK_SET);
|
||||
ReadStateFile (&GH, sizeof (GH), 1, fp);
|
||||
ReadGroupHeader (fp, &GH);
|
||||
#ifdef DEBUG_GROUPS
|
||||
log_add (log_Debug, "GetGroupInfo(%lu): %u(%lu) out of %u", offset,
|
||||
which_group, GH.GroupOffset[which_group], GH.NumGroups);
|
||||
@@ -402,11 +484,12 @@ GetGroupInfo (DWORD offset, BYTE which_group)
|
||||
"date %u/%u/%u!", month_index, day_index,
|
||||
year_index);
|
||||
#endif /* DEBUG_GROUPS */
|
||||
// Erase random groups (out of date)
|
||||
fp = OpenStateFile (RANDGRPINFO_FILE, "wb");
|
||||
GH.NumGroups = 0;
|
||||
GH.star_index = (COUNT)~0;
|
||||
GH.GroupOffset[0] = 0;
|
||||
WriteStateFile (&GH, sizeof (GH), 1, fp);
|
||||
WriteGroupHeader (fp, &GH);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -417,8 +500,8 @@ GetGroupInfo (DWORD offset, BYTE which_group)
|
||||
continue;
|
||||
|
||||
SeekStateFile (fp, GH.GroupOffset[which_group], SEEK_SET);
|
||||
ReadStateFile (&RaceType, sizeof (RaceType), 1, fp);
|
||||
ReadStateFile (&NumShips, sizeof (NumShips), 1, fp);
|
||||
sread_8 (fp, &RaceType);
|
||||
sread_8 (fp, &NumShips);
|
||||
|
||||
if (NumShips)
|
||||
{
|
||||
@@ -516,7 +599,7 @@ GetGroupInfo (DWORD offset, BYTE which_group)
|
||||
if (which_group == GROUP_LIST)
|
||||
{
|
||||
SeekStateFile (fp, GH.GroupOffset[0], SEEK_SET);
|
||||
ReadStateFile (&LastEncGroup, sizeof (LastEncGroup), 1, fp);
|
||||
sread_8 (fp, &LastEncGroup);
|
||||
|
||||
if (LastEncGroup)
|
||||
{
|
||||
@@ -536,25 +619,20 @@ GetGroupInfo (DWORD offset, BYTE which_group)
|
||||
}
|
||||
ReinitQueue (&GLOBAL (npc_built_ship_q));
|
||||
|
||||
SeekStateFile (fp, GH.GroupOffset[which_group]
|
||||
+ sizeof (LastEncGroup), SEEK_SET);
|
||||
|
||||
ReadStateFile (&NumShips, sizeof (NumShips), 1, fp);
|
||||
// skip RaceType
|
||||
SeekStateFile (fp, GH.GroupOffset[which_group] + 1, SEEK_SET);
|
||||
|
||||
sread_8 (fp, &NumShips);
|
||||
while (NumShips--)
|
||||
{
|
||||
PBYTE Ptr;
|
||||
|
||||
ReadStateFile (&RaceType, sizeof (RaceType), 1, fp);
|
||||
sread_8 (fp, &RaceType);
|
||||
|
||||
hStarShip = CloneShipFragment (RaceType,
|
||||
&GLOBAL (npc_built_ship_q), 0);
|
||||
|
||||
FragPtr = (SHIP_FRAGMENTPTR)LockStarShip (
|
||||
&GLOBAL (npc_built_ship_q), hStarShip);
|
||||
Ptr = (PBYTE)&FragPtr->RaceDescPtr;
|
||||
ReadStateFile (Ptr,
|
||||
((PBYTE)&FragPtr->ShipInfo.race_strings) - Ptr, 1,
|
||||
fp);
|
||||
ReadShipFragment (fp, FragPtr);
|
||||
|
||||
#ifdef DEBUG_GROUPS
|
||||
if (which_group == GROUP_LIST)
|
||||
@@ -625,12 +703,13 @@ PutGroupInfo (DWORD offset, BYTE which_group)
|
||||
if (offset == GROUPS_ADD_NEW)
|
||||
{
|
||||
offset = LengthStateFile (fp);
|
||||
GH.NumGroups = 0;
|
||||
GH.GroupOffset[0] = 0;
|
||||
SeekStateFile (fp, offset, SEEK_SET);
|
||||
WriteStateFile (&GH, sizeof (GH), 1, fp);
|
||||
// XXX: It seems that GH is not completely initialised.
|
||||
// Some garbage is saved. -- SvdB
|
||||
// XXX: All important fields are inited here, and the
|
||||
// rest are inited below
|
||||
GH.NumGroups = 0;
|
||||
GH.star_index = (COUNT)~0;
|
||||
GH.GroupOffset[0] = 0;
|
||||
WriteGroupHeader (fp, &GH);
|
||||
}
|
||||
|
||||
if (which_group != GROUP_LIST)
|
||||
@@ -642,7 +721,7 @@ PutGroupInfo (DWORD offset, BYTE which_group)
|
||||
which_group = GROUP_LIST;
|
||||
}
|
||||
}
|
||||
ReadStateFile (&GH, sizeof (GH), 1, fp);
|
||||
ReadGroupHeader (fp, &GH);
|
||||
|
||||
#ifdef NEVER
|
||||
if (GetHeadLink (&GLOBAL (npc_built_ship_q))
|
||||
|
||||
+566
-290
@@ -16,6 +16,8 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "load.h"
|
||||
|
||||
#include "build.h"
|
||||
@@ -35,62 +37,166 @@
|
||||
|
||||
ACTIVITY NextActivity;
|
||||
|
||||
static BOOLEAN LoadSummary (uio_Stream *in_fp);
|
||||
// XXX: these should handle endian conversions later
|
||||
static inline COUNT
|
||||
cread_8 (DECODE_REF fh, PBYTE v)
|
||||
{
|
||||
BYTE t;
|
||||
if (!v) /* read value ignored */
|
||||
v = &t;
|
||||
return cread (v, 1, 1, fh);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
cread_16 (DECODE_REF fh, PUWORD v)
|
||||
{
|
||||
UWORD t;
|
||||
if (!v) /* read value ignored */
|
||||
v = &t;
|
||||
return cread (v, 2, 1, fh);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
cread_32 (DECODE_REF fh, PDWORD v)
|
||||
{
|
||||
DWORD t;
|
||||
if (!v) /* read value ignored */
|
||||
v = &t;
|
||||
return cread (v, 4, 1, fh);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
cread_ptr (DECODE_REF fh)
|
||||
{
|
||||
DWORD t;
|
||||
return cread_32 (fh, &t); /* ptrs are useless in saves */
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
cread_a8 (DECODE_REF fh, PBYTE ar, COUNT count)
|
||||
{
|
||||
assert (ar != NULL);
|
||||
return cread (ar, 1, count, fh) == count;
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
read_8 (PVOID fp, PBYTE v)
|
||||
{
|
||||
BYTE t;
|
||||
if (!v) /* read value ignored */
|
||||
v = &t;
|
||||
return ReadResFile (v, 1, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
read_16 (PVOID fp, PUWORD v)
|
||||
{
|
||||
UWORD t;
|
||||
if (!v) /* read value ignored */
|
||||
v = &t;
|
||||
return ReadResFile (v, 2, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
read_32 (PVOID fp, PDWORD v)
|
||||
{
|
||||
DWORD t;
|
||||
if (!v) /* read value ignored */
|
||||
v = &t;
|
||||
return ReadResFile (v, 4, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
read_ptr (PVOID fp)
|
||||
{
|
||||
DWORD t;
|
||||
return read_32 (fp, &t); /* ptrs are useless in saves */
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
read_a8 (PVOID fp, PBYTE ar, COUNT count)
|
||||
{
|
||||
assert (ar != NULL);
|
||||
return ReadResFile (ar, 1, count, fp) == count;
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
read_a16 (PVOID fp, PUWORD ar, COUNT count)
|
||||
{
|
||||
assert (ar != NULL);
|
||||
|
||||
for ( ; count > 0; --count, ++ar)
|
||||
{
|
||||
if (read_16 (fp, ar) != 1)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
LoadShipQueue (DECODE_REF fh, PQUEUE pQueue, BOOLEAN MakeQ)
|
||||
{
|
||||
COUNT num_links;
|
||||
|
||||
cread ((PBYTE)&num_links, sizeof (num_links), 1, fh);
|
||||
if (num_links)
|
||||
cread_16 (fh, &num_links);
|
||||
if (num_links && MakeQ)
|
||||
InitQueue (pQueue, num_links, sizeof (SHIP_FRAGMENT));
|
||||
|
||||
while (num_links--)
|
||||
{
|
||||
if (MakeQ)
|
||||
InitQueue (pQueue, num_links, sizeof (SHIP_FRAGMENT));
|
||||
HSTARSHIP hStarShip;
|
||||
SHIP_FRAGMENTPTR FragPtr;
|
||||
COUNT Index;
|
||||
BYTE tmpb;
|
||||
|
||||
do
|
||||
cread_16 (fh, &Index);
|
||||
|
||||
if (pQueue == &GLOBAL (avail_race_q))
|
||||
hStarShip = GetStarShipFromIndex (pQueue, Index);
|
||||
else
|
||||
hStarShip = CloneShipFragment (Index, pQueue, 0);
|
||||
|
||||
FragPtr = (SHIP_FRAGMENTPTR)LockStarShip (pQueue, hStarShip);
|
||||
|
||||
if (pQueue != &GLOBAL (avail_race_q))
|
||||
{ // queues other than avail_race_q save SHIP_FRAGMENT elements
|
||||
// Read SHIP_FRAGMENT elements
|
||||
cread_16 (fh, &FragPtr->s.Player);
|
||||
cread_8 (fh, &FragPtr->s.Captain);
|
||||
cread_8 (fh, NULL); /* padding */
|
||||
}
|
||||
// Read SHIP_INFO elements
|
||||
cread_16 (fh, &FragPtr->ShipInfo.ship_flags);
|
||||
cread_8 (fh, &FragPtr->ShipInfo.var1);
|
||||
cread_8 (fh, &FragPtr->ShipInfo.var2);
|
||||
cread_8 (fh, &tmpb);
|
||||
FragPtr->ShipInfo.crew_level = tmpb;
|
||||
cread_8 (fh, &tmpb);
|
||||
FragPtr->ShipInfo.max_crew = tmpb;
|
||||
cread_8 (fh, &FragPtr->ShipInfo.energy_level);
|
||||
cread_8 (fh, &FragPtr->ShipInfo.max_energy);
|
||||
cread_16 (fh, &FragPtr->ShipInfo.loc.x);
|
||||
cread_16 (fh, &FragPtr->ShipInfo.loc.y);
|
||||
|
||||
if (pQueue == &GLOBAL (avail_race_q))
|
||||
{
|
||||
HSTARSHIP hStarShip;
|
||||
SHIP_FRAGMENTPTR FragPtr;
|
||||
COUNT Index, Offset;
|
||||
PBYTE Ptr;
|
||||
// avail_race_q contains information not about specific ships,
|
||||
// but about a race.
|
||||
EXTENDED_SHIP_FRAGMENTPTR ExtFragPtr =
|
||||
(EXTENDED_SHIP_FRAGMENTPTR) FragPtr;
|
||||
|
||||
cread ((PBYTE)&Index, sizeof (Index), 1, fh);
|
||||
cread_16 (fh, &ExtFragPtr->ShipInfo.actual_strength);
|
||||
cread_16 (fh, &ExtFragPtr->ShipInfo.known_strength);
|
||||
cread_16 (fh, &ExtFragPtr->ShipInfo.known_loc.x);
|
||||
cread_16 (fh, &ExtFragPtr->ShipInfo.known_loc.y);
|
||||
cread_8 (fh, &ExtFragPtr->ShipInfo.growth_err_term);
|
||||
cread_8 (fh, &ExtFragPtr->ShipInfo.func_index);
|
||||
cread_16 (fh, &ExtFragPtr->ShipInfo.dest_loc.x);
|
||||
cread_16 (fh, &ExtFragPtr->ShipInfo.dest_loc.y);
|
||||
cread_16 (fh, NULL); /* alignment padding */
|
||||
}
|
||||
|
||||
if (pQueue == &GLOBAL (avail_race_q))
|
||||
{
|
||||
hStarShip = GetStarShipFromIndex (pQueue, Index);
|
||||
FragPtr = (SHIP_FRAGMENTPTR)LockStarShip (pQueue, hStarShip);
|
||||
Offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
hStarShip = CloneShipFragment (Index, pQueue, 0);
|
||||
FragPtr = (SHIP_FRAGMENTPTR)LockStarShip (pQueue, hStarShip);
|
||||
Offset = (PBYTE)&FragPtr->ShipInfo
|
||||
- (PBYTE)&FragPtr->RaceDescPtr;
|
||||
}
|
||||
|
||||
Ptr = ((PBYTE)&FragPtr->ShipInfo) - Offset;
|
||||
cread ((PBYTE)Ptr,
|
||||
((PBYTE)&FragPtr->ShipInfo.race_strings) - Ptr, 1, fh);
|
||||
|
||||
// Hack to retain savegame backwards compatibility, after
|
||||
// increasing crew_level and max_crew from BYTE to COUNT.
|
||||
// For the queues that are saved here, a BYTE is large enough.
|
||||
FragPtr->ShipInfo.max_crew = FragPtr->ShipInfo.dummy_max_crew;
|
||||
FragPtr->ShipInfo.crew_level = FragPtr->ShipInfo.dummy_crew_level;
|
||||
|
||||
if (Offset == 0)
|
||||
{
|
||||
EXTENDED_SHIP_FRAGMENTPTR ExtFragPtr;
|
||||
|
||||
ExtFragPtr = (EXTENDED_SHIP_FRAGMENTPTR)FragPtr;
|
||||
Ptr = (PBYTE)&ExtFragPtr->ShipInfo.actual_strength;
|
||||
cread ((PBYTE)Ptr, ((PBYTE)&ExtFragPtr[1]) - Ptr, 1, fh);
|
||||
}
|
||||
UnlockStarShip (pQueue, hStarShip);
|
||||
} while (--num_links);
|
||||
UnlockStarShip (pQueue, hStarShip);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,278 +204,448 @@ static void
|
||||
LoadEncounter (ENCOUNTERPTR EncounterPtr, DECODE_REF fh)
|
||||
{
|
||||
COUNT i;
|
||||
#define LOAD_BLOCK(file, start, end) \
|
||||
cread((PBYTE) (start), (PBYTE) (end) - (PBYTE) start, \
|
||||
1, (file))
|
||||
// An ENCOUNTER structure (indirectly) contains an array of
|
||||
// SHIP_INFO structure, which is bigger now because of the
|
||||
// larger type for crew.
|
||||
// This hack makes sure the savegames format is unchanged.
|
||||
// The original code consisted of just one line:
|
||||
// cread ((PBYTE)EncounterPtr, sizeof (*EncounterPtr), 1, fh);
|
||||
|
||||
// Load the stuff before the SHIP_INFO array:
|
||||
LOAD_BLOCK(fh, EncounterPtr, EncounterPtr->SD.ShipList);
|
||||
cread_ptr (fh); /* useless ptr; HENCOUNTER pred */
|
||||
EncounterPtr->pred = 0;
|
||||
cread_ptr (fh); /* useless ptr; HENCOUNTER succ */
|
||||
EncounterPtr->succ = 0;
|
||||
cread_ptr (fh); /* useless ptr; HELEMENT hElement */
|
||||
EncounterPtr->hElement = 0;
|
||||
cread_16 (fh, &EncounterPtr->transition_state);
|
||||
cread_16 (fh, &EncounterPtr->origin.x);
|
||||
cread_16 (fh, &EncounterPtr->origin.y);
|
||||
cread_16 (fh, &EncounterPtr->radius);
|
||||
// EXTENDED_STAR_DESC fields
|
||||
cread_16 (fh, &EncounterPtr->SD.star_pt.x);
|
||||
cread_16 (fh, &EncounterPtr->SD.star_pt.y);
|
||||
cread_8 (fh, &EncounterPtr->SD.Type);
|
||||
cread_8 (fh, &EncounterPtr->SD.Index);
|
||||
cread_16 (fh, NULL); /* alignment padding */
|
||||
|
||||
// Load each entry in the SHIP_INFO array:
|
||||
for (i = 0; i < MAX_HYPER_SHIPS; i++)
|
||||
{
|
||||
SHIP_INFO *ShipInfo = &EncounterPtr->SD.ShipList[i];
|
||||
LOAD_BLOCK(fh, ShipInfo, &ShipInfo->crew_level);
|
||||
ShipInfo->crew_level = ShipInfo->dummy_crew_level;
|
||||
ShipInfo->max_crew = ShipInfo->dummy_max_crew;
|
||||
SHIP_INFOPTR ShipInfo = &EncounterPtr->SD.ShipList[i];
|
||||
BYTE tmpb;
|
||||
|
||||
cread_16 (fh, &ShipInfo->ship_flags);
|
||||
cread_8 (fh, &ShipInfo->var1);
|
||||
cread_8 (fh, &ShipInfo->var2);
|
||||
cread_8 (fh, &tmpb);
|
||||
ShipInfo->crew_level = tmpb;
|
||||
cread_8 (fh, &tmpb);
|
||||
ShipInfo->max_crew = tmpb;
|
||||
cread_8 (fh, &ShipInfo->energy_level);
|
||||
cread_8 (fh, &ShipInfo->max_energy);
|
||||
cread_16 (fh, &ShipInfo->loc.x);
|
||||
cread_16 (fh, &ShipInfo->loc.y);
|
||||
cread_32 (fh, NULL); /* useless val; STRING race_strings */
|
||||
ShipInfo->race_strings = 0;
|
||||
cread_ptr (fh); /* useless ptr; FRAME icons */
|
||||
ShipInfo->icons = 0;
|
||||
cread_ptr (fh); /* useless ptr; FRAME melee_icon */
|
||||
ShipInfo->melee_icon = 0;
|
||||
}
|
||||
|
||||
// Load the stuff after the SHIP_INFO array:
|
||||
LOAD_BLOCK(fh, &EncounterPtr->log_x, &EncounterPtr[1]);
|
||||
cread_32 (fh, &EncounterPtr->log_x);
|
||||
cread_32 (fh, &EncounterPtr->log_y);
|
||||
}
|
||||
|
||||
static void
|
||||
LoadEvent (EVENTPTR EventPtr, DECODE_REF fh)
|
||||
{
|
||||
cread_ptr (fh); /* useless ptr; HEVENT pred */
|
||||
EventPtr->pred = 0;
|
||||
cread_ptr (fh); /* useless ptr; HEVENT succ */
|
||||
EventPtr->succ = 0;
|
||||
cread_8 (fh, &EventPtr->day_index);
|
||||
cread_8 (fh, &EventPtr->month_index);
|
||||
cread_16 (fh, &EventPtr->year_index);
|
||||
cread_8 (fh, &EventPtr->func_index);
|
||||
cread_8 (fh, NULL); /* padding */
|
||||
cread_16 (fh, NULL); /* padding */
|
||||
}
|
||||
|
||||
static void
|
||||
DummyLoadQueue (PQUEUE QueuePtr, DECODE_REF fh)
|
||||
{
|
||||
/* QUEUE should never actually be loaded since it contains
|
||||
* purely internal representation and the lists
|
||||
* involved are actually loaded separately */
|
||||
(void)QueuePtr; /* silence compiler */
|
||||
|
||||
/* QUEUE format with QUEUE_TABLE defined -- UQM default */
|
||||
cread_ptr (fh); /* HLINK head */
|
||||
cread_ptr (fh); /* HLINK tail */
|
||||
cread_ptr (fh); /* PBYTE pq_tab */
|
||||
cread_ptr (fh); /* HLINK free_list */
|
||||
cread_16 (fh, NULL); /* MEM_HANDLE hq_tab */
|
||||
cread_16 (fh, NULL); /* COUNT object_size */
|
||||
cread_8 (fh, NULL); /* BYTE num_objects */
|
||||
|
||||
cread_8 (fh, NULL); /* padding */
|
||||
cread_16 (fh, NULL); /* padding */
|
||||
}
|
||||
|
||||
static void
|
||||
LoadClockState (PCLOCK_STATE ClockPtr, DECODE_REF fh)
|
||||
{
|
||||
cread_8 (fh, &ClockPtr->day_index);
|
||||
cread_8 (fh, &ClockPtr->month_index);
|
||||
cread_16 (fh, &ClockPtr->year_index);
|
||||
cread_16 (fh, &ClockPtr->tick_count);
|
||||
cread_16 (fh, &ClockPtr->day_in_ticks);
|
||||
cread_ptr (fh); /* not loading ptr; Semaphore clock_sem */
|
||||
cread_ptr (fh); /* not loading ptr; Task clock_task */
|
||||
cread_32 (fh, &ClockPtr->TimeCounter); /* theoretically useless */
|
||||
|
||||
DummyLoadQueue (&ClockPtr->event_q, fh);
|
||||
}
|
||||
|
||||
static void
|
||||
LoadGameState (PGAME_STATE GSPtr, DECODE_REF fh)
|
||||
{
|
||||
DWORD tmpd;
|
||||
|
||||
cread_8 (fh, &GSPtr->cur_state); /* obsolete */
|
||||
cread_8 (fh, &GSPtr->glob_flags);
|
||||
cread_8 (fh, &GSPtr->CrewCost);
|
||||
cread_8 (fh, &GSPtr->FuelCost);
|
||||
cread_a8 (fh, GSPtr->ModuleCost, NUM_MODULES);
|
||||
cread_a8 (fh, GSPtr->ElementWorth, NUM_ELEMENT_CATEGORIES);
|
||||
cread_ptr (fh); /* not loading ptr; PPRIMITIVE DisplayArray */
|
||||
cread_16 (fh, &GSPtr->CurrentActivity);
|
||||
|
||||
cread_16 (fh, NULL); /* CLOCK_STATE alignment padding */
|
||||
LoadClockState (&GSPtr->GameClock, fh);
|
||||
|
||||
cread_16 (fh, &GSPtr->autopilot.x);
|
||||
cread_16 (fh, &GSPtr->autopilot.y);
|
||||
cread_16 (fh, &GSPtr->ip_location.x);
|
||||
cread_16 (fh, &GSPtr->ip_location.y);
|
||||
/* STAMP ShipStamp */
|
||||
cread_16 (fh, &GSPtr->ShipStamp.origin.x);
|
||||
cread_16 (fh, &GSPtr->ShipStamp.origin.y);
|
||||
cread_32 (fh, &tmpd); /* abused ptr to store DWORD */
|
||||
GSPtr->ShipStamp.frame = (FRAME)tmpd;
|
||||
|
||||
/* VELOCITY_DESC velocity */
|
||||
cread_16 (fh, &GSPtr->velocity.TravelAngle);
|
||||
cread_16 (fh, &GSPtr->velocity.vector.width);
|
||||
cread_16 (fh, &GSPtr->velocity.vector.height);
|
||||
cread_16 (fh, &GSPtr->velocity.fract.width);
|
||||
cread_16 (fh, &GSPtr->velocity.fract.height);
|
||||
cread_16 (fh, &GSPtr->velocity.error.width);
|
||||
cread_16 (fh, &GSPtr->velocity.error.height);
|
||||
cread_16 (fh, &GSPtr->velocity.incr.width);
|
||||
cread_16 (fh, &GSPtr->velocity.incr.height);
|
||||
cread_16 (fh, NULL); /* VELOCITY_DESC padding */
|
||||
|
||||
cread_32 (fh, &GSPtr->BattleGroupRef);
|
||||
|
||||
DummyLoadQueue (&GSPtr->avail_race_q, fh);
|
||||
DummyLoadQueue (&GSPtr->npc_built_ship_q, fh);
|
||||
DummyLoadQueue (&GSPtr->encounter_q, fh);
|
||||
DummyLoadQueue (&GSPtr->built_ship_q, fh);
|
||||
|
||||
cread_a8 (fh, GSPtr->GameState, sizeof (GSPtr->GameState));
|
||||
|
||||
assert (sizeof (GSPtr->GameState) % 4 == 3);
|
||||
cread_8 (fh, NULL); /* GAME_STATE alignment padding */
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
LoadSummary (uio_Stream *in_fp)
|
||||
LoadSisState (PSIS_STATE SSPtr, PVOID fp)
|
||||
{
|
||||
// XXX: This function seems to be unused.
|
||||
SUMMARY_DESC S;
|
||||
if (
|
||||
read_32 (fp, &SSPtr->log_x) != 1 ||
|
||||
read_32 (fp, &SSPtr->log_y) != 1 ||
|
||||
read_32 (fp, &SSPtr->ResUnits) != 1 ||
|
||||
read_32 (fp, &SSPtr->FuelOnBoard) != 1 ||
|
||||
read_16 (fp, &SSPtr->CrewEnlisted) != 1 ||
|
||||
read_16 (fp, &SSPtr->TotalElementMass) != 1 ||
|
||||
read_16 (fp, &SSPtr->TotalBioMass) != 1 ||
|
||||
read_a8 (fp, SSPtr->ModuleSlots, NUM_MODULE_SLOTS) != 1 ||
|
||||
read_a8 (fp, SSPtr->DriveSlots, NUM_DRIVE_SLOTS) != 1 ||
|
||||
read_a8 (fp, SSPtr->JetSlots, NUM_JET_SLOTS) != 1 ||
|
||||
read_8 (fp, &SSPtr->NumLanders) != 1 ||
|
||||
read_a16 (fp, SSPtr->ElementAmounts, NUM_ELEMENT_CATEGORIES) != 1 ||
|
||||
|
||||
return (ReadResFile (&S, sizeof (S), 1, in_fp) == sizeof (S));
|
||||
read_a8 (fp, SSPtr->ShipName, SIS_NAME_SIZE) != 1 ||
|
||||
read_a8 (fp, SSPtr->CommanderName, SIS_NAME_SIZE) != 1 ||
|
||||
read_a8 (fp, SSPtr->PlanetName, SIS_NAME_SIZE) != 1 ||
|
||||
|
||||
read_16 (fp, NULL) != 1 /* padding */
|
||||
)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
LoadSummary (SUMMARY_DESC *SummPtr, PVOID fp)
|
||||
{
|
||||
if (!LoadSisState (&SummPtr->SS, fp))
|
||||
return FALSE;
|
||||
|
||||
if (
|
||||
read_8 (fp, &SummPtr->Activity) != 1 ||
|
||||
read_8 (fp, &SummPtr->Flags) != 1 ||
|
||||
read_8 (fp, &SummPtr->day_index) != 1 ||
|
||||
read_8 (fp, &SummPtr->month_index) != 1 ||
|
||||
read_16 (fp, &SummPtr->year_index) != 1 ||
|
||||
read_8 (fp, &SummPtr->MCreditLo) != 1 ||
|
||||
read_8 (fp, &SummPtr->MCreditHi) != 1 ||
|
||||
read_8 (fp, &SummPtr->NumShips) != 1 ||
|
||||
read_8 (fp, &SummPtr->NumDevices) != 1 ||
|
||||
read_a8 (fp, SummPtr->ShipList, MAX_BUILT_SHIPS) != 1 ||
|
||||
read_a8 (fp, SummPtr->DeviceList, MAX_EXCLUSIVE_DEVICES) != 1 ||
|
||||
|
||||
read_16 (fp, NULL) != 1 /* padding */
|
||||
)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
LoadStarDesc (STAR_DESCPTR SDPtr, DECODE_REF fh)
|
||||
{
|
||||
cread_16 (fh, &SDPtr->star_pt.x);
|
||||
cread_16 (fh, &SDPtr->star_pt.y);
|
||||
cread_8 (fh, &SDPtr->Type);
|
||||
cread_8 (fh, &SDPtr->Index);
|
||||
cread_8 (fh, &SDPtr->Prefix);
|
||||
cread_8 (fh, &SDPtr->Postfix);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
LoadGame (COUNT which_game, SUMMARY_DESC *summary_desc)
|
||||
LoadGame (COUNT which_game, SUMMARY_DESC *SummPtr)
|
||||
{
|
||||
uio_Stream *in_fp;
|
||||
char buf[256], file[PATH_MAX];
|
||||
char file[PATH_MAX];
|
||||
char buf[256];
|
||||
SUMMARY_DESC loc_sd;
|
||||
GAME_STATE_FILE *fp;
|
||||
DECODE_REF fh;
|
||||
COUNT num_links;
|
||||
STAR_DESC SD;
|
||||
ACTIVITY Activity;
|
||||
|
||||
sprintf (file, "starcon2.%02u", which_game);
|
||||
in_fp = res_OpenResFile (saveDir, file, "rb");
|
||||
if (in_fp)
|
||||
if (!in_fp)
|
||||
return FALSE;
|
||||
|
||||
if (!LoadSummary (&loc_sd, in_fp))
|
||||
{
|
||||
GAME_STATE_FILE *fp;
|
||||
DECODE_REF fh;
|
||||
COUNT num_links;
|
||||
Semaphore clock_sem;
|
||||
Task clock_task;
|
||||
QUEUE event_q, encounter_q, avail_q, npc_q, player_q;
|
||||
STAR_DESC SD;
|
||||
ACTIVITY Activity;
|
||||
|
||||
ReadResFile (buf, sizeof (*summary_desc), 1, in_fp);
|
||||
|
||||
if (summary_desc == 0)
|
||||
summary_desc = (SUMMARY_DESC *)buf;
|
||||
else
|
||||
{
|
||||
memcpy (summary_desc, buf, sizeof (*summary_desc));
|
||||
res_CloseResFile (in_fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Crude check for big-endian/little-endian incompatibilities.
|
||||
// year_index is suitable as it's a multi-byte value within
|
||||
// a specific recognisable range.
|
||||
if (summary_desc->year_index < START_YEAR ||
|
||||
summary_desc->year_index >= START_YEAR +
|
||||
YEARS_TO_KOHRAH_VICTORY + 1 /* Utwig intervention */ +
|
||||
1 /* time to destroy all races, plenty */ +
|
||||
25 /* for cheaters */)
|
||||
{
|
||||
log_add (log_Always, "Warning: Savegame corrupt or from an "
|
||||
"an incompatible platform.");
|
||||
res_CloseResFile (in_fp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GlobData.SIS_state = summary_desc->SS;
|
||||
|
||||
if ((fh = copen (in_fp, FILE_STREAM, STREAM_READ)) == 0)
|
||||
{
|
||||
res_CloseResFile (in_fp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ReinitQueue (&GLOBAL (GameClock.event_q));
|
||||
ReinitQueue (&GLOBAL (encounter_q));
|
||||
ReinitQueue (&GLOBAL (npc_built_ship_q));
|
||||
ReinitQueue (&GLOBAL (built_ship_q));
|
||||
|
||||
clock_sem = GLOBAL (GameClock.clock_sem);
|
||||
clock_task = GLOBAL (GameClock.clock_task);
|
||||
event_q = GLOBAL (GameClock.event_q);
|
||||
encounter_q = GLOBAL (encounter_q);
|
||||
avail_q = GLOBAL (avail_race_q);
|
||||
npc_q = GLOBAL (npc_built_ship_q);
|
||||
player_q = GLOBAL (built_ship_q);
|
||||
|
||||
memset ((PBYTE)&GLOBAL (GameState[0]),
|
||||
0, sizeof (GLOBAL (GameState)));
|
||||
Activity = GLOBAL (CurrentActivity);
|
||||
cread ((PBYTE)&GlobData.Game_state, sizeof (GlobData.Game_state), 1,
|
||||
fh);
|
||||
NextActivity = GLOBAL (CurrentActivity);
|
||||
GLOBAL (CurrentActivity) = Activity;
|
||||
|
||||
GLOBAL (GameClock.clock_sem) = clock_sem;
|
||||
GLOBAL (GameClock.clock_task) = clock_task;
|
||||
GLOBAL (GameClock.event_q) = event_q;
|
||||
GLOBAL (encounter_q) = encounter_q;
|
||||
GLOBAL (avail_race_q) = avail_q;
|
||||
GLOBAL (npc_built_ship_q) = npc_q;
|
||||
GLOBAL (built_ship_q) = player_q;
|
||||
// It shouldn't be possible to ever save with TimeCounter != 0
|
||||
// But if it does happen, it needs to be reset to 0, since on load
|
||||
// the clock semaphore is gauranteed to be 0
|
||||
if (GLOBAL (GameClock.TimeCounter) != 0)
|
||||
log_add (log_Always, "Warning: Game clock wasn't stopped during "
|
||||
"save, Savegame may be corrupt!\n");
|
||||
GLOBAL (GameClock.TimeCounter) = 0;
|
||||
|
||||
LoadShipQueue (fh, &GLOBAL (avail_race_q), FALSE);
|
||||
if (!(NextActivity & START_INTERPLANETARY))
|
||||
LoadShipQueue (fh, &GLOBAL (npc_built_ship_q), FALSE);
|
||||
LoadShipQueue (fh, &GLOBAL (built_ship_q), FALSE);
|
||||
|
||||
cread ((PBYTE)&num_links, sizeof (num_links), 1, fh);
|
||||
{
|
||||
#ifdef DEBUG_LOAD
|
||||
log_add (log_Debug, "EVENTS:");
|
||||
#endif /* DEBUG_LOAD */
|
||||
while (num_links--)
|
||||
{
|
||||
HEVENT hEvent;
|
||||
EVENTPTR EventPtr;
|
||||
|
||||
hEvent = AllocEvent ();
|
||||
LockEvent (hEvent, &EventPtr);
|
||||
|
||||
cread ((PBYTE)EventPtr, sizeof (*EventPtr), 1, fh);
|
||||
|
||||
#ifdef DEBUG_LOAD
|
||||
log_add (log_Debug, "\t%u/%u/%u -- %u",
|
||||
EventPtr->month_index,
|
||||
EventPtr->day_index,
|
||||
EventPtr->year_index,
|
||||
EventPtr->func_index);
|
||||
#endif /* DEBUG_LOAD */
|
||||
UnlockEvent (hEvent);
|
||||
PutEvent (hEvent);
|
||||
}
|
||||
}
|
||||
|
||||
cread ((PBYTE)&num_links, sizeof (num_links), 1, fh);
|
||||
{
|
||||
while (num_links--)
|
||||
{
|
||||
BYTE i, NumShips;
|
||||
HENCOUNTER hEncounter;
|
||||
ENCOUNTERPTR EncounterPtr;
|
||||
|
||||
hEncounter = AllocEncounter ();
|
||||
LockEncounter (hEncounter, &EncounterPtr);
|
||||
|
||||
LoadEncounter(EncounterPtr, fh);
|
||||
EncounterPtr->hElement = 0;
|
||||
NumShips = LONIBBLE (EncounterPtr->SD.Index);
|
||||
for (i = 0; i < NumShips; ++i)
|
||||
{
|
||||
HSTARSHIP hStarShip;
|
||||
SHIP_FRAGMENTPTR TemplatePtr;
|
||||
|
||||
hStarShip = GetStarShipFromIndex (
|
||||
&GLOBAL (avail_race_q),
|
||||
EncounterPtr->SD.ShipList[i].var1);
|
||||
TemplatePtr = (SHIP_FRAGMENTPTR)LockStarShip (
|
||||
&GLOBAL (avail_race_q), hStarShip);
|
||||
EncounterPtr->SD.ShipList[i].race_strings =
|
||||
TemplatePtr->ShipInfo.race_strings;
|
||||
EncounterPtr->SD.ShipList[i].icons =
|
||||
TemplatePtr->ShipInfo.icons;
|
||||
EncounterPtr->SD.ShipList[i].melee_icon =
|
||||
TemplatePtr->ShipInfo.melee_icon;
|
||||
UnlockStarShip (&GLOBAL (avail_race_q), hStarShip);
|
||||
}
|
||||
|
||||
UnlockEncounter (hEncounter);
|
||||
PutEncounter (hEncounter);
|
||||
}
|
||||
}
|
||||
|
||||
fp = OpenStateFile (STARINFO_FILE, "wb");
|
||||
if (fp)
|
||||
{
|
||||
DWORD flen;
|
||||
|
||||
cread ((PBYTE)&flen, sizeof (flen), 1, fh);
|
||||
while (flen)
|
||||
{
|
||||
COUNT num_bytes;
|
||||
|
||||
num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
|
||||
cread ((PBYTE)buf, num_bytes, 1, fh);
|
||||
WriteStateFile (buf, num_bytes, 1, fp);
|
||||
|
||||
flen -= num_bytes;
|
||||
}
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
|
||||
fp = OpenStateFile (DEFGRPINFO_FILE, "wb");
|
||||
if (fp)
|
||||
{
|
||||
DWORD flen;
|
||||
|
||||
cread ((PBYTE)&flen, sizeof (flen), 1, fh);
|
||||
while (flen)
|
||||
{
|
||||
COUNT num_bytes;
|
||||
|
||||
num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
|
||||
cread ((PBYTE)buf, num_bytes, 1, fh);
|
||||
WriteStateFile (buf, num_bytes, 1, fp);
|
||||
|
||||
flen -= num_bytes;
|
||||
}
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
|
||||
fp = OpenStateFile (RANDGRPINFO_FILE, "wb");
|
||||
if (fp)
|
||||
{
|
||||
DWORD flen;
|
||||
|
||||
cread ((PBYTE)&flen, sizeof (flen), 1, fh);
|
||||
while (flen)
|
||||
{
|
||||
COUNT num_bytes;
|
||||
|
||||
num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
|
||||
cread ((PBYTE)buf, num_bytes, 1, fh);
|
||||
WriteStateFile (buf, num_bytes, 1, fp);
|
||||
|
||||
flen -= num_bytes;
|
||||
}
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
|
||||
cread ((PBYTE)&SD, sizeof (SD), 1, fh);
|
||||
|
||||
cclose (fh);
|
||||
log_add (log_Always, "Warning: Savegame is corrupt");
|
||||
res_CloseResFile (in_fp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
EncounterGroup = 0;
|
||||
EncounterRace = -1;
|
||||
|
||||
ReinitQueue (&race_q[0]);
|
||||
ReinitQueue (&race_q[1]);
|
||||
CurStarDescPtr = FindStar (NULL_PTR, &SD.star_pt, 0, 0);
|
||||
if (!(NextActivity & START_ENCOUNTER)
|
||||
&& LOBYTE (NextActivity) == IN_INTERPLANETARY)
|
||||
NextActivity |= START_INTERPLANETARY;
|
||||
|
||||
GLOBAL (DisplayArray) = DisplayArray;
|
||||
|
||||
if (!SummPtr)
|
||||
{
|
||||
SummPtr = &loc_sd;
|
||||
}
|
||||
else
|
||||
{ // only need summary for displaying to user
|
||||
memcpy (SummPtr, &loc_sd, sizeof (*SummPtr));
|
||||
res_CloseResFile (in_fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
// Crude check for big-endian/little-endian incompatibilities.
|
||||
// year_index is suitable as it's a multi-byte value within
|
||||
// a specific recognisable range.
|
||||
if (SummPtr->year_index < START_YEAR ||
|
||||
SummPtr->year_index >= START_YEAR +
|
||||
YEARS_TO_KOHRAH_VICTORY + 1 /* Utwig intervention */ +
|
||||
1 /* time to destroy all races, plenty */ +
|
||||
25 /* for cheaters */)
|
||||
{
|
||||
log_add (log_Always, "Warning: Savegame corrupt or from an "
|
||||
"an incompatible platform.");
|
||||
res_CloseResFile (in_fp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GlobData.SIS_state = SummPtr->SS;
|
||||
|
||||
if ((fh = copen (in_fp, FILE_STREAM, STREAM_READ)) == 0)
|
||||
{
|
||||
res_CloseResFile (in_fp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ReinitQueue (&GLOBAL (GameClock.event_q));
|
||||
ReinitQueue (&GLOBAL (encounter_q));
|
||||
ReinitQueue (&GLOBAL (npc_built_ship_q));
|
||||
ReinitQueue (&GLOBAL (built_ship_q));
|
||||
|
||||
memset (&GLOBAL (GameState[0]), 0, sizeof (GLOBAL (GameState)));
|
||||
Activity = GLOBAL (CurrentActivity);
|
||||
LoadGameState (&GlobData.Game_state, fh);
|
||||
NextActivity = GLOBAL (CurrentActivity);
|
||||
GLOBAL (CurrentActivity) = Activity;
|
||||
|
||||
// It shouldn't be possible to ever save with TimeCounter != 0
|
||||
// But if it does happen, it needs to be reset to 0, since on load
|
||||
// the clock semaphore is gauranteed to be 0
|
||||
if (GLOBAL (GameClock.TimeCounter) != 0)
|
||||
log_add (log_Always, "Warning: Game clock wasn't stopped during "
|
||||
"save, Savegame may be corrupt!\n");
|
||||
GLOBAL (GameClock.TimeCounter) = 0;
|
||||
|
||||
LoadShipQueue (fh, &GLOBAL (avail_race_q), FALSE);
|
||||
if (!(NextActivity & START_INTERPLANETARY))
|
||||
LoadShipQueue (fh, &GLOBAL (npc_built_ship_q), FALSE);
|
||||
LoadShipQueue (fh, &GLOBAL (built_ship_q), FALSE);
|
||||
|
||||
// Load the game events (compressed)
|
||||
cread_16 (fh, &num_links);
|
||||
{
|
||||
#ifdef DEBUG_LOAD
|
||||
log_add (log_Debug, "EVENTS:");
|
||||
#endif /* DEBUG_LOAD */
|
||||
while (num_links--)
|
||||
{
|
||||
HEVENT hEvent;
|
||||
EVENTPTR EventPtr;
|
||||
|
||||
hEvent = AllocEvent ();
|
||||
LockEvent (hEvent, &EventPtr);
|
||||
|
||||
LoadEvent (EventPtr, fh);
|
||||
|
||||
#ifdef DEBUG_LOAD
|
||||
log_add (log_Debug, "\t%u/%u/%u -- %u",
|
||||
EventPtr->month_index,
|
||||
EventPtr->day_index,
|
||||
EventPtr->year_index,
|
||||
EventPtr->func_index);
|
||||
#endif /* DEBUG_LOAD */
|
||||
UnlockEvent (hEvent);
|
||||
PutEvent (hEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// Load the encounters (black globes in HS/QS (compressed))
|
||||
cread_16 (fh, &num_links);
|
||||
{
|
||||
while (num_links--)
|
||||
{
|
||||
BYTE i, NumShips;
|
||||
HENCOUNTER hEncounter;
|
||||
ENCOUNTERPTR EncounterPtr;
|
||||
|
||||
hEncounter = AllocEncounter ();
|
||||
LockEncounter (hEncounter, &EncounterPtr);
|
||||
|
||||
LoadEncounter (EncounterPtr, fh);
|
||||
|
||||
NumShips = LONIBBLE (EncounterPtr->SD.Index);
|
||||
for (i = 0; i < NumShips; ++i)
|
||||
{
|
||||
HSTARSHIP hStarShip;
|
||||
SHIP_FRAGMENTPTR TemplatePtr;
|
||||
|
||||
hStarShip = GetStarShipFromIndex (
|
||||
&GLOBAL (avail_race_q),
|
||||
EncounterPtr->SD.ShipList[i].var1);
|
||||
TemplatePtr = (SHIP_FRAGMENTPTR)LockStarShip (
|
||||
&GLOBAL (avail_race_q), hStarShip);
|
||||
EncounterPtr->SD.ShipList[i].race_strings =
|
||||
TemplatePtr->ShipInfo.race_strings;
|
||||
EncounterPtr->SD.ShipList[i].icons =
|
||||
TemplatePtr->ShipInfo.icons;
|
||||
EncounterPtr->SD.ShipList[i].melee_icon =
|
||||
TemplatePtr->ShipInfo.melee_icon;
|
||||
UnlockStarShip (&GLOBAL (avail_race_q), hStarShip);
|
||||
}
|
||||
|
||||
UnlockEncounter (hEncounter);
|
||||
PutEncounter (hEncounter);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the star info file from the compressed stream
|
||||
fp = OpenStateFile (STARINFO_FILE, "wb");
|
||||
if (fp)
|
||||
{
|
||||
DWORD flen;
|
||||
|
||||
cread_32 (fh, &flen);
|
||||
while (flen)
|
||||
{
|
||||
COUNT num_bytes;
|
||||
|
||||
num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
|
||||
cread (buf, num_bytes, 1, fh);
|
||||
WriteStateFile (buf, num_bytes, 1, fp);
|
||||
|
||||
flen -= num_bytes;
|
||||
}
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
|
||||
// Copy the defined groupinfo file from the compressed stream
|
||||
fp = OpenStateFile (DEFGRPINFO_FILE, "wb");
|
||||
if (fp)
|
||||
{
|
||||
DWORD flen;
|
||||
|
||||
cread_32 (fh, &flen);
|
||||
while (flen)
|
||||
{
|
||||
COUNT num_bytes;
|
||||
|
||||
num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
|
||||
cread (buf, num_bytes, 1, fh);
|
||||
WriteStateFile (buf, num_bytes, 1, fp);
|
||||
|
||||
flen -= num_bytes;
|
||||
}
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
|
||||
// Copy the random groupinfo file from the compressed stream
|
||||
fp = OpenStateFile (RANDGRPINFO_FILE, "wb");
|
||||
if (fp)
|
||||
{
|
||||
DWORD flen;
|
||||
|
||||
cread_32 (fh, &flen);
|
||||
while (flen)
|
||||
{
|
||||
COUNT num_bytes;
|
||||
|
||||
num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
|
||||
cread (buf, num_bytes, 1, fh);
|
||||
WriteStateFile (buf, num_bytes, 1, fp);
|
||||
|
||||
flen -= num_bytes;
|
||||
}
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
|
||||
LoadStarDesc (&SD, fh);
|
||||
|
||||
cclose (fh);
|
||||
res_CloseResFile (in_fp);
|
||||
|
||||
EncounterGroup = 0;
|
||||
EncounterRace = -1;
|
||||
|
||||
ReinitQueue (&race_q[0]);
|
||||
ReinitQueue (&race_q[1]);
|
||||
CurStarDescPtr = FindStar (NULL, &SD.star_pt, 0, 0);
|
||||
if (!(NextActivity & START_ENCOUNTER)
|
||||
&& LOBYTE (NextActivity) == IN_INTERPLANETARY)
|
||||
NextActivity |= START_INTERPLANETARY;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+6
-14
@@ -101,10 +101,9 @@ typedef struct
|
||||
{
|
||||
UWORD ship_flags;
|
||||
BYTE var1, var2;
|
||||
BYTE dummy_crew_level, dummy_max_crew;
|
||||
/* Necessary for savegame backwards compatibility.
|
||||
* Unused during the game, only used during save/load.
|
||||
*/
|
||||
COUNT crew_level, max_crew;
|
||||
/* For ships in npc_built_ship_q, the value INFINITE_FLEET for
|
||||
* crew_level indicates an infinite number of ships. */
|
||||
BYTE energy_level, max_energy;
|
||||
POINT loc;
|
||||
|
||||
@@ -115,9 +114,6 @@ typedef struct
|
||||
|
||||
STRING race_strings;
|
||||
FRAME icons, melee_icon;
|
||||
COUNT crew_level, max_crew;
|
||||
/* For ships in npc_built_ship_q, the value INFINITE_FLEET for
|
||||
* crew_level indicates an infinite number of ships. */
|
||||
#define INFINITE_FLEET ((COUNT) ~0)
|
||||
} SHIP_INFO;
|
||||
typedef SHIP_INFO *PSHIP_INFO;
|
||||
@@ -164,10 +160,9 @@ typedef struct
|
||||
BYTE days_left;
|
||||
/* Days left before the fleet reachers 'dest_loc'. */
|
||||
BYTE growth_fract;
|
||||
BYTE dummy_crew_level, dummy_max_crew;
|
||||
/* Necessary for savegame backwards compatibility.
|
||||
* Unused during the game, only used during save/load.
|
||||
*/
|
||||
COUNT crew_level, max_crew;
|
||||
/* For ships in npc_built_ship_q, the value INFINITE_FLEET for
|
||||
* crew_level indicates an infinite number of ships. */
|
||||
BYTE energy_level, max_energy;
|
||||
POINT loc;
|
||||
/* Location of the fleet (center) */
|
||||
@@ -175,9 +170,6 @@ typedef struct
|
||||
STRING race_strings;
|
||||
/* Race specific strings, see doc/devel/racestrings. */
|
||||
FRAME icons, melee_icon;
|
||||
COUNT crew_level, max_crew;
|
||||
/* For ships in npc_built_ship_q, the value INFINITE_FLEET for
|
||||
* crew_level indicates an infinite number of ships. */
|
||||
|
||||
/* -== The fields below this line are included in savegames. ==- */
|
||||
|
||||
|
||||
+341
-98
@@ -16,6 +16,8 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "save.h"
|
||||
|
||||
#include "build.h"
|
||||
@@ -35,6 +37,78 @@
|
||||
#include "libs/log.h"
|
||||
|
||||
|
||||
// XXX: these should handle endian conversions later
|
||||
static inline COUNT
|
||||
cwrite_8 (DECODE_REF fh, BYTE v)
|
||||
{
|
||||
return cwrite (&v, 1, 1, fh);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
cwrite_16 (DECODE_REF fh, UWORD v)
|
||||
{
|
||||
return cwrite (&v, 2, 1, fh);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
cwrite_32 (DECODE_REF fh, DWORD v)
|
||||
{
|
||||
return cwrite (&v, 4, 1, fh);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
cwrite_ptr (DECODE_REF fh)
|
||||
{
|
||||
return cwrite_32 (fh, 0); /* ptrs are useless in saves */
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
cwrite_a8 (DECODE_REF fh, PBYTE ar, COUNT count)
|
||||
{
|
||||
return cwrite (ar, 1, count, fh) == count;
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
write_8 (PVOID fp, BYTE v)
|
||||
{
|
||||
return WriteResFile (&v, 1, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
write_16 (PVOID fp, UWORD v)
|
||||
{
|
||||
return WriteResFile (&v, 2, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
write_32 (PVOID fp, DWORD v)
|
||||
{
|
||||
return WriteResFile (&v, 4, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
write_ptr (PVOID fp)
|
||||
{
|
||||
return write_32 (fp, 0); /* ptrs are useless in saves */
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
write_a8 (PVOID fp, PBYTE ar, COUNT count)
|
||||
{
|
||||
return WriteResFile (ar, 1, count, fp) == count;
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
write_a16 (PVOID fp, PUWORD ar, COUNT count)
|
||||
{
|
||||
for ( ; count > 0; --count, ++ar)
|
||||
{
|
||||
if (write_16 (fp, *ar) != 1)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
SaveShipQueue (DECODE_REF fh, PQUEUE pQueue)
|
||||
{
|
||||
@@ -43,67 +117,62 @@ SaveShipQueue (DECODE_REF fh, PQUEUE pQueue)
|
||||
|
||||
// Write the number of entries in the queue.
|
||||
num_links = CountLinks (pQueue);
|
||||
cwrite ((PBYTE)&num_links, sizeof (num_links), 1, fh);
|
||||
cwrite_16 (fh, num_links);
|
||||
|
||||
hStarShip = GetHeadLink (pQueue);
|
||||
while (num_links--)
|
||||
{
|
||||
HSTARSHIP hNextShip;
|
||||
SHIP_FRAGMENTPTR FragPtr;
|
||||
COUNT Index, Offset;
|
||||
PBYTE Ptr;
|
||||
COUNT Index;
|
||||
|
||||
FragPtr = (SHIP_FRAGMENTPTR)LockStarShip (pQueue, hStarShip);
|
||||
hNextShip = _GetSuccLink (FragPtr);
|
||||
|
||||
if (pQueue == &GLOBAL (avail_race_q))
|
||||
{
|
||||
Index = GetIndexFromStarShip (pQueue, hStarShip);
|
||||
// The index is the position in the queue.
|
||||
Offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Index = GET_RACE_ID (FragPtr);
|
||||
Offset = (PBYTE)&FragPtr->ShipInfo
|
||||
- (PBYTE)&FragPtr->RaceDescPtr;
|
||||
}
|
||||
|
||||
// Write the number identifying this ship type.
|
||||
// See races.h; look for the enum containing NUM_AVAILABLE_RACES.
|
||||
cwrite ((PBYTE)&Index, sizeof (Index), 1, fh);
|
||||
cwrite_16 (fh, Index);
|
||||
|
||||
// Hack to retain savegame backwards compatibility, after
|
||||
// increasing crew_level and max_crew from BYTE to COUNT.
|
||||
// For the queues that are saved here, a BYTE is large enough.
|
||||
FragPtr->ShipInfo.dummy_max_crew = FragPtr->ShipInfo.max_crew;
|
||||
FragPtr->ShipInfo.dummy_crew_level = FragPtr->ShipInfo.crew_level;
|
||||
|
||||
// Write part of FragPtr, starting with FragPtr->ShipInfo for
|
||||
// GLOBAL(avail_race_q), and FragPtr->RaceDescPtr for other queues.
|
||||
// When FragPtr->RaceDescPtr is saved, it does not actually
|
||||
// contain a pointer (see the definition of SHIP_FRAGMENT).
|
||||
// This is only so because SaveShipQueue() is only ever called with
|
||||
// GLOBAL_avail_race_q), GLOBAL(built_ship_q) and
|
||||
// GLOBAL(npc_built_ship_q).
|
||||
Ptr = ((PBYTE)&FragPtr->ShipInfo) - Offset;
|
||||
cwrite ((PBYTE)Ptr, ((PBYTE)&FragPtr->ShipInfo.race_strings) - Ptr,
|
||||
1, fh);
|
||||
if (pQueue != &GLOBAL (avail_race_q))
|
||||
{ // queues other than avail_race_q save SHIP_FRAGMENT elements
|
||||
// Write SHIP_FRAGMENT elements
|
||||
cwrite_16 (fh, FragPtr->s.Player);
|
||||
cwrite_8 (fh, FragPtr->s.Captain);
|
||||
cwrite_8 (fh, 0); /* padding */
|
||||
}
|
||||
// Write SHIP_INFO elements
|
||||
cwrite_16 (fh, FragPtr->ShipInfo.ship_flags);
|
||||
cwrite_8 (fh, FragPtr->ShipInfo.var1);
|
||||
cwrite_8 (fh, FragPtr->ShipInfo.var2);
|
||||
cwrite_8 (fh, FragPtr->ShipInfo.crew_level);
|
||||
cwrite_8 (fh, FragPtr->ShipInfo.max_crew);
|
||||
cwrite_8 (fh, FragPtr->ShipInfo.energy_level);
|
||||
cwrite_8 (fh, FragPtr->ShipInfo.max_energy);
|
||||
cwrite_16 (fh, FragPtr->ShipInfo.loc.x);
|
||||
cwrite_16 (fh, FragPtr->ShipInfo.loc.y);
|
||||
|
||||
if (Offset == 0)
|
||||
if (pQueue == &GLOBAL (avail_race_q))
|
||||
{
|
||||
// The queue being saved is avail_race_q.
|
||||
// It contains information not about specific ships, but about
|
||||
// a race. What is saved is everything in the EXTENDED_SHIP_INFO
|
||||
// structure from the field 'actual_strength' onwards,
|
||||
// for each of the races.
|
||||
EXTENDED_SHIP_FRAGMENTPTR ExtFragPtr;
|
||||
// avail_race_q contains information not about specific ships,
|
||||
// but about a race.
|
||||
EXTENDED_SHIP_FRAGMENTPTR ExtFragPtr =
|
||||
(EXTENDED_SHIP_FRAGMENTPTR) FragPtr;
|
||||
|
||||
ExtFragPtr = (EXTENDED_SHIP_FRAGMENTPTR)FragPtr;
|
||||
Ptr = (PBYTE)&ExtFragPtr->ShipInfo.actual_strength;
|
||||
cwrite ((PBYTE)Ptr, ((PBYTE)&ExtFragPtr[1]) - Ptr, 1, fh);
|
||||
// XXX: This saves padding too, which may contain
|
||||
// garbage.
|
||||
cwrite_16 (fh, ExtFragPtr->ShipInfo.actual_strength);
|
||||
cwrite_16 (fh, ExtFragPtr->ShipInfo.known_strength);
|
||||
cwrite_16 (fh, ExtFragPtr->ShipInfo.known_loc.x);
|
||||
cwrite_16 (fh, ExtFragPtr->ShipInfo.known_loc.y);
|
||||
cwrite_8 (fh, ExtFragPtr->ShipInfo.growth_err_term);
|
||||
cwrite_8 (fh, ExtFragPtr->ShipInfo.func_index);
|
||||
cwrite_16 (fh, ExtFragPtr->ShipInfo.dest_loc.x);
|
||||
cwrite_16 (fh, ExtFragPtr->ShipInfo.dest_loc.y);
|
||||
cwrite_16 (fh, 0); /* alignment padding */
|
||||
}
|
||||
|
||||
UnlockStarShip (pQueue, hStarShip);
|
||||
@@ -115,59 +184,234 @@ static void
|
||||
SaveEncounter (ENCOUNTERPTR EncounterPtr, DECODE_REF fh)
|
||||
{
|
||||
COUNT i;
|
||||
#define SAVE_BLOCK(file, start, end) \
|
||||
cwrite((PBYTE) (start), (PBYTE) (end) - (PBYTE) start, \
|
||||
1, (file))
|
||||
// An ENCOUNTER structure (indirectly) contains an array of
|
||||
// SHIP_INFO structure, which is bigger now because of the
|
||||
// larger type for crew.
|
||||
// This hack makes sure the savegames format is unchanged.
|
||||
// The original code consisted of jsut one line:
|
||||
// cwrite ((PBYTE)EncounterPtr, sizeof (*EncounterPtr), 1, fh);
|
||||
|
||||
// Save the stuff before the SHIP_INFO array:
|
||||
SAVE_BLOCK(fh, EncounterPtr, EncounterPtr->SD.ShipList);
|
||||
cwrite_ptr (fh); /* useless ptr; HENCOUNTER pred */
|
||||
cwrite_ptr (fh); /* useless ptr; HENCOUNTER succ */
|
||||
cwrite_ptr (fh); /* useless ptr; HELEMENT hElement */
|
||||
cwrite_16 (fh, EncounterPtr->transition_state);
|
||||
cwrite_16 (fh, EncounterPtr->origin.x);
|
||||
cwrite_16 (fh, EncounterPtr->origin.y);
|
||||
cwrite_16 (fh, EncounterPtr->radius);
|
||||
// EXTENDED_STAR_DESC fields
|
||||
cwrite_16 (fh, EncounterPtr->SD.star_pt.x);
|
||||
cwrite_16 (fh, EncounterPtr->SD.star_pt.y);
|
||||
cwrite_8 (fh, EncounterPtr->SD.Type);
|
||||
cwrite_8 (fh, EncounterPtr->SD.Index);
|
||||
cwrite_16 (fh, 0); /* alignment padding */
|
||||
|
||||
// Save each entry in the SHIP_INFO array:
|
||||
for (i = 0; i < MAX_HYPER_SHIPS; i++)
|
||||
{
|
||||
SHIP_INFO *ShipInfo = &EncounterPtr->SD.ShipList[i];
|
||||
ShipInfo->dummy_crew_level = (BYTE) ShipInfo->crew_level;
|
||||
ShipInfo->dummy_max_crew = (BYTE) ShipInfo->max_crew;
|
||||
SAVE_BLOCK(fh, ShipInfo, &ShipInfo->crew_level);
|
||||
SHIP_INFOPTR ShipInfo = &EncounterPtr->SD.ShipList[i];
|
||||
|
||||
cwrite_16 (fh, ShipInfo->ship_flags);
|
||||
cwrite_8 (fh, ShipInfo->var1);
|
||||
cwrite_8 (fh, ShipInfo->var2);
|
||||
cwrite_8 (fh, ShipInfo->crew_level);
|
||||
cwrite_8 (fh, ShipInfo->max_crew);
|
||||
cwrite_8 (fh, ShipInfo->energy_level);
|
||||
cwrite_8 (fh, ShipInfo->max_energy);
|
||||
cwrite_16 (fh, ShipInfo->loc.x);
|
||||
cwrite_16 (fh, ShipInfo->loc.y);
|
||||
cwrite_32 (fh, 0); /* useless val; STRING race_strings */
|
||||
cwrite_ptr (fh); /* useless ptr; FRAME icons */
|
||||
cwrite_ptr (fh); /* useless ptr; FRAME melee_icon */
|
||||
}
|
||||
|
||||
// Save the stuff after the SHIP_INFO array:
|
||||
SAVE_BLOCK(fh, &EncounterPtr->log_x, &EncounterPtr[1]);
|
||||
cwrite_32 (fh, EncounterPtr->log_x);
|
||||
cwrite_32 (fh, EncounterPtr->log_y);
|
||||
}
|
||||
|
||||
static void
|
||||
PrepareSummary (SUMMARY_DESC *summary_desc)
|
||||
SaveEvent (EVENTPTR EventPtr, DECODE_REF fh)
|
||||
{
|
||||
summary_desc->SS = GlobData.SIS_state;
|
||||
cwrite_ptr (fh); /* useless ptr; HEVENT pred */
|
||||
cwrite_ptr (fh); /* useless ptr; HEVENT succ */
|
||||
cwrite_8 (fh, EventPtr->day_index);
|
||||
cwrite_8 (fh, EventPtr->month_index);
|
||||
cwrite_16 (fh, EventPtr->year_index);
|
||||
cwrite_8 (fh, EventPtr->func_index);
|
||||
cwrite_8 (fh, 0); /* padding */
|
||||
cwrite_16 (fh, 0); /* padding */
|
||||
}
|
||||
|
||||
switch (summary_desc->Activity = LOBYTE (GLOBAL (CurrentActivity)))
|
||||
static void
|
||||
DummySaveQueue (PQUEUE QueuePtr, DECODE_REF fh)
|
||||
{
|
||||
/* QUEUE should never actually be saved since it contains
|
||||
* purely internal representation and the lists
|
||||
* involved are actually saved separately */
|
||||
(void)QueuePtr; /* silence compiler */
|
||||
|
||||
/* QUEUE format with QUEUE_TABLE defined -- UQM default */
|
||||
cwrite_ptr (fh); /* HLINK head */
|
||||
cwrite_ptr (fh); /* HLINK tail */
|
||||
cwrite_ptr (fh); /* PBYTE pq_tab */
|
||||
cwrite_ptr (fh); /* HLINK free_list */
|
||||
cwrite_16 (fh, 0); /* MEM_HANDLE hq_tab */
|
||||
cwrite_16 (fh, 0); /* COUNT object_size */
|
||||
cwrite_8 (fh, 0); /* BYTE num_objects */
|
||||
|
||||
cwrite_8 (fh, 0); /* padding */
|
||||
cwrite_16 (fh, 0); /* padding */
|
||||
}
|
||||
|
||||
static void
|
||||
SaveClockState (PCLOCK_STATE ClockPtr, DECODE_REF fh)
|
||||
{
|
||||
cwrite_8 (fh, ClockPtr->day_index);
|
||||
cwrite_8 (fh, ClockPtr->month_index);
|
||||
cwrite_16 (fh, ClockPtr->year_index);
|
||||
cwrite_16 (fh, ClockPtr->tick_count);
|
||||
cwrite_16 (fh, ClockPtr->day_in_ticks);
|
||||
cwrite_ptr (fh); /* useless ptr; Semaphore clock_sem */
|
||||
cwrite_ptr (fh); /* useless ptr; Task clock_task */
|
||||
cwrite_32 (fh, ClockPtr->TimeCounter); /* theoretically useless */
|
||||
|
||||
DummySaveQueue (&ClockPtr->event_q, fh);
|
||||
}
|
||||
|
||||
static void
|
||||
SaveGameState (PGAME_STATE GSPtr, DECODE_REF fh)
|
||||
{
|
||||
cwrite_8 (fh, 0); /* obsolete; BYTE cur_state */
|
||||
cwrite_8 (fh, GSPtr->glob_flags);
|
||||
cwrite_8 (fh, GSPtr->CrewCost);
|
||||
cwrite_8 (fh, GSPtr->FuelCost);
|
||||
cwrite_a8 (fh, GSPtr->ModuleCost, NUM_MODULES);
|
||||
cwrite_a8 (fh, GSPtr->ElementWorth, NUM_ELEMENT_CATEGORIES);
|
||||
cwrite_ptr (fh); /* useless ptr; PPRIMITIVE DisplayArray */
|
||||
cwrite_16 (fh, GSPtr->CurrentActivity);
|
||||
|
||||
cwrite_16 (fh, 0); /* CLOCK_STATE alignment padding */
|
||||
SaveClockState (&GSPtr->GameClock, fh);
|
||||
|
||||
cwrite_16 (fh, GSPtr->autopilot.x);
|
||||
cwrite_16 (fh, GSPtr->autopilot.y);
|
||||
cwrite_16 (fh, GSPtr->ip_location.x);
|
||||
cwrite_16 (fh, GSPtr->ip_location.y);
|
||||
/* STAMP ShipStamp */
|
||||
cwrite_16 (fh, GSPtr->ShipStamp.origin.x);
|
||||
cwrite_16 (fh, GSPtr->ShipStamp.origin.y);
|
||||
cwrite_32 (fh, (DWORD)GSPtr->ShipStamp.frame); /* abused ptr to store DWORD */
|
||||
/* VELOCITY_DESC velocity */
|
||||
cwrite_16 (fh, GSPtr->velocity.TravelAngle);
|
||||
cwrite_16 (fh, GSPtr->velocity.vector.width);
|
||||
cwrite_16 (fh, GSPtr->velocity.vector.height);
|
||||
cwrite_16 (fh, GSPtr->velocity.fract.width);
|
||||
cwrite_16 (fh, GSPtr->velocity.fract.height);
|
||||
cwrite_16 (fh, GSPtr->velocity.error.width);
|
||||
cwrite_16 (fh, GSPtr->velocity.error.height);
|
||||
cwrite_16 (fh, GSPtr->velocity.incr.width);
|
||||
cwrite_16 (fh, GSPtr->velocity.incr.height);
|
||||
cwrite_16 (fh, 0); /* VELOCITY_DESC padding */
|
||||
|
||||
cwrite_32 (fh, GSPtr->BattleGroupRef);
|
||||
|
||||
DummySaveQueue (&GSPtr->avail_race_q, fh);
|
||||
DummySaveQueue (&GSPtr->npc_built_ship_q, fh);
|
||||
DummySaveQueue (&GSPtr->encounter_q, fh);
|
||||
DummySaveQueue (&GSPtr->built_ship_q, fh);
|
||||
|
||||
cwrite_a8 (fh, GSPtr->GameState, sizeof (GSPtr->GameState));
|
||||
|
||||
assert (sizeof (GSPtr->GameState) % 4 == 3);
|
||||
cwrite_8 (fh, 0); /* GAME_STATE alignment padding */
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
SaveSisState (PSIS_STATE SSPtr, PVOID fp)
|
||||
{
|
||||
if (
|
||||
write_32 (fp, SSPtr->log_x) != 1 ||
|
||||
write_32 (fp, SSPtr->log_y) != 1 ||
|
||||
write_32 (fp, SSPtr->ResUnits) != 1 ||
|
||||
write_32 (fp, SSPtr->FuelOnBoard) != 1 ||
|
||||
write_16 (fp, SSPtr->CrewEnlisted) != 1 ||
|
||||
write_16 (fp, SSPtr->TotalElementMass) != 1 ||
|
||||
write_16 (fp, SSPtr->TotalBioMass) != 1 ||
|
||||
write_a8 (fp, SSPtr->ModuleSlots, NUM_MODULE_SLOTS) != 1 ||
|
||||
write_a8 (fp, SSPtr->DriveSlots, NUM_DRIVE_SLOTS) != 1 ||
|
||||
write_a8 (fp, SSPtr->JetSlots, NUM_JET_SLOTS) != 1 ||
|
||||
write_8 (fp, SSPtr->NumLanders) != 1 ||
|
||||
write_a16 (fp, SSPtr->ElementAmounts, NUM_ELEMENT_CATEGORIES) != 1 ||
|
||||
|
||||
write_a8 (fp, SSPtr->ShipName, SIS_NAME_SIZE) != 1 ||
|
||||
write_a8 (fp, SSPtr->CommanderName, SIS_NAME_SIZE) != 1 ||
|
||||
write_a8 (fp, SSPtr->PlanetName, SIS_NAME_SIZE) != 1 ||
|
||||
|
||||
write_16 (fp, 0) != 1 /* padding */
|
||||
)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
SaveSummary (SUMMARY_DESC *SummPtr, PVOID fp)
|
||||
{
|
||||
if (!SaveSisState (&SummPtr->SS, fp))
|
||||
return FALSE;
|
||||
|
||||
if (
|
||||
write_8 (fp, SummPtr->Activity) != 1 ||
|
||||
write_8 (fp, SummPtr->Flags) != 1 ||
|
||||
write_8 (fp, SummPtr->day_index) != 1 ||
|
||||
write_8 (fp, SummPtr->month_index) != 1 ||
|
||||
write_16 (fp, SummPtr->year_index) != 1 ||
|
||||
write_8 (fp, SummPtr->MCreditLo) != 1 ||
|
||||
write_8 (fp, SummPtr->MCreditHi) != 1 ||
|
||||
write_8 (fp, SummPtr->NumShips) != 1 ||
|
||||
write_8 (fp, SummPtr->NumDevices) != 1 ||
|
||||
write_a8 (fp, SummPtr->ShipList, MAX_BUILT_SHIPS) != 1 ||
|
||||
write_a8 (fp, SummPtr->DeviceList, MAX_EXCLUSIVE_DEVICES) != 1 ||
|
||||
|
||||
write_16 (fp, 0) != 1 /* padding */
|
||||
)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
SaveStarDesc (STAR_DESCPTR SDPtr, DECODE_REF fh)
|
||||
{
|
||||
cwrite_16 (fh, SDPtr->star_pt.x);
|
||||
cwrite_16 (fh, SDPtr->star_pt.y);
|
||||
cwrite_8 (fh, SDPtr->Type);
|
||||
cwrite_8 (fh, SDPtr->Index);
|
||||
cwrite_8 (fh, SDPtr->Prefix);
|
||||
cwrite_8 (fh, SDPtr->Postfix);
|
||||
}
|
||||
|
||||
static void
|
||||
PrepareSummary (SUMMARY_DESC *SummPtr)
|
||||
{
|
||||
SummPtr->SS = GlobData.SIS_state;
|
||||
|
||||
switch (SummPtr->Activity = LOBYTE (GLOBAL (CurrentActivity)))
|
||||
{
|
||||
case IN_HYPERSPACE:
|
||||
if (GET_GAME_STATE (ARILOU_SPACE_SIDE) > 1)
|
||||
summary_desc->Activity = IN_QUASISPACE;
|
||||
SummPtr->Activity = IN_QUASISPACE;
|
||||
break;
|
||||
case IN_INTERPLANETARY:
|
||||
if (GET_GAME_STATE (GLOBAL_FLAGS_AND_DATA) == (BYTE)~0)
|
||||
summary_desc->Activity = IN_STARBASE;
|
||||
SummPtr->Activity = IN_STARBASE;
|
||||
else if (pSolarSysState && pSolarSysState->MenuState.Initialized >= 3)
|
||||
summary_desc->Activity = IN_PLANET_ORBIT;
|
||||
SummPtr->Activity = IN_PLANET_ORBIT;
|
||||
break;
|
||||
}
|
||||
|
||||
summary_desc->MCreditLo = GET_GAME_STATE (MELNORME_CREDIT0);
|
||||
summary_desc->MCreditHi = GET_GAME_STATE (MELNORME_CREDIT1);
|
||||
SummPtr->MCreditLo = GET_GAME_STATE (MELNORME_CREDIT0);
|
||||
SummPtr->MCreditHi = GET_GAME_STATE (MELNORME_CREDIT1);
|
||||
|
||||
{
|
||||
HSTARSHIP hStarShip, hNextShip;
|
||||
|
||||
for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)), summary_desc->NumShips = 0;
|
||||
hStarShip; hStarShip = hNextShip, ++summary_desc->NumShips)
|
||||
for (hStarShip = GetHeadLink (&GLOBAL (built_ship_q)), SummPtr->NumShips = 0;
|
||||
hStarShip; hStarShip = hNextShip, ++SummPtr->NumShips)
|
||||
{
|
||||
SHIP_FRAGMENTPTR StarShipPtr;
|
||||
|
||||
@@ -175,26 +419,26 @@ PrepareSummary (SUMMARY_DESC *summary_desc)
|
||||
&GLOBAL (built_ship_q), hStarShip
|
||||
);
|
||||
hNextShip = _GetSuccLink (StarShipPtr);
|
||||
summary_desc->ShipList[summary_desc->NumShips] = GET_RACE_ID (StarShipPtr);
|
||||
SummPtr->ShipList[SummPtr->NumShips] = GET_RACE_ID (StarShipPtr);
|
||||
UnlockStarShip (&GLOBAL (built_ship_q), hStarShip);
|
||||
}
|
||||
}
|
||||
|
||||
summary_desc->NumDevices = InventoryDevices (summary_desc->DeviceList);
|
||||
SummPtr->NumDevices = InventoryDevices (SummPtr->DeviceList);
|
||||
|
||||
summary_desc->Flags = GET_GAME_STATE (LANDER_SHIELDS)
|
||||
SummPtr->Flags = GET_GAME_STATE (LANDER_SHIELDS)
|
||||
| (GET_GAME_STATE (IMPROVED_LANDER_SPEED) << (4 + 0))
|
||||
| (GET_GAME_STATE (IMPROVED_LANDER_CARGO) << (4 + 1))
|
||||
| (GET_GAME_STATE (IMPROVED_LANDER_SHOT) << (4 + 2))
|
||||
| ((GET_GAME_STATE (CHMMR_BOMB_STATE) < 2 ? 0 : 1) << (4 + 3));
|
||||
|
||||
summary_desc->day_index = GLOBAL (GameClock.day_index);
|
||||
summary_desc->month_index = GLOBAL (GameClock.month_index);
|
||||
summary_desc->year_index = GLOBAL (GameClock.year_index);
|
||||
SummPtr->day_index = GLOBAL (GameClock.day_index);
|
||||
SummPtr->month_index = GLOBAL (GameClock.month_index);
|
||||
SummPtr->year_index = GLOBAL (GameClock.year_index);
|
||||
}
|
||||
|
||||
static void
|
||||
SaveProblemMessage (STAMP *MsgStamp)
|
||||
SaveProblemMessage (PSTAMP MsgStamp)
|
||||
{
|
||||
#define MAX_MSG_LINES 1
|
||||
RECT r;
|
||||
@@ -299,7 +543,7 @@ SaveProblem (void)
|
||||
// This function first writes to a memory file, and then writes the whole
|
||||
// lot to the actual save file at once.
|
||||
BOOLEAN
|
||||
SaveGame (COUNT which_game, SUMMARY_DESC *summary_desc)
|
||||
SaveGame (COUNT which_game, SUMMARY_DESC *SummPtr)
|
||||
{
|
||||
BOOLEAN success, made_room;
|
||||
PVOID out_fp;
|
||||
@@ -346,6 +590,8 @@ RetrySave:
|
||||
else
|
||||
memset (&SD, 0, sizeof (SD));
|
||||
|
||||
// XXX: Backup: ShipStamp.frame is abused to store DWORD info
|
||||
// SaveFlagshipState() overwrites it with a DWORD value
|
||||
frame = GLOBAL (ShipStamp.frame);
|
||||
pt = GLOBAL (ip_location);
|
||||
SaveFlagshipState ();
|
||||
@@ -354,10 +600,10 @@ RetrySave:
|
||||
& (START_ENCOUNTER | START_INTERPLANETARY)))
|
||||
PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP);
|
||||
|
||||
cwrite ((PBYTE)&GlobData.Game_state, sizeof (GlobData.Game_state),
|
||||
1, fh);
|
||||
SaveGameState (&GlobData.Game_state, fh);
|
||||
|
||||
GLOBAL (ip_location) = pt;
|
||||
// XXX: Restore: ShipStamp.frame is abused to store DWORD info
|
||||
GLOBAL (ShipStamp.frame) = frame;
|
||||
|
||||
SaveShipQueue (fh, &GLOBAL (avail_race_q));
|
||||
@@ -367,7 +613,7 @@ RetrySave:
|
||||
|
||||
// Save the number of game events (compressed).
|
||||
num_links = CountLinks (&GLOBAL (GameClock.event_q));
|
||||
cwrite ((PBYTE)&num_links, sizeof (num_links), 1, fh);
|
||||
cwrite_16 (fh, num_links);
|
||||
// Save the game events themselves (compressed):
|
||||
{
|
||||
HEVENT hEvent;
|
||||
@@ -381,7 +627,7 @@ RetrySave:
|
||||
LockEvent (hEvent, &EventPtr);
|
||||
hNextEvent = GetSuccEvent (EventPtr);
|
||||
|
||||
cwrite ((PBYTE)EventPtr, sizeof (*EventPtr), 1, fh);
|
||||
SaveEvent (EventPtr, fh);
|
||||
|
||||
UnlockEvent (hEvent);
|
||||
hEvent = hNextEvent;
|
||||
@@ -391,7 +637,7 @@ RetrySave:
|
||||
// Save the number of encounters (black globes in HS/QS (compressed))
|
||||
num_links = CountLinks (&GLOBAL (encounter_q));
|
||||
// Save the encounters themselves (compressed):
|
||||
cwrite ((PBYTE)&num_links, sizeof (num_links), 1, fh);
|
||||
cwrite_16 (fh, num_links);
|
||||
{
|
||||
HENCOUNTER hEncounter;
|
||||
|
||||
@@ -404,7 +650,7 @@ RetrySave:
|
||||
LockEncounter (hEncounter, &EncounterPtr);
|
||||
hNextEncounter = GetSuccEncounter (EncounterPtr);
|
||||
|
||||
SaveEncounter(EncounterPtr, fh);
|
||||
SaveEncounter (EncounterPtr, fh);
|
||||
|
||||
UnlockEncounter (hEncounter);
|
||||
hEncounter = hNextEncounter;
|
||||
@@ -416,54 +662,55 @@ RetrySave:
|
||||
if (fp)
|
||||
{
|
||||
flen = LengthStateFile (fp);
|
||||
// (DWORD) Write the uncompressed size.
|
||||
cwrite ((PBYTE)&flen, sizeof (flen), 1, fh);
|
||||
// Write the uncompressed size.
|
||||
cwrite_32 (fh, flen);
|
||||
while (flen)
|
||||
{
|
||||
COUNT num_bytes;
|
||||
|
||||
num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
|
||||
ReadStateFile (buf, num_bytes, 1, fp);
|
||||
cwrite ((PBYTE)buf, num_bytes, 1, fh);
|
||||
cwrite (buf, num_bytes, 1, fh);
|
||||
|
||||
flen -= num_bytes;
|
||||
}
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
|
||||
// Copy the ? groupinfo file into the memory file (compressed).
|
||||
// Copy the defined groupinfo file into the memory file (compressed)
|
||||
fp = OpenStateFile (DEFGRPINFO_FILE, "rb");
|
||||
if (fp)
|
||||
{
|
||||
flen = LengthStateFile (fp);
|
||||
// (DWORD) Write the uncompressed size.
|
||||
cwrite ((PBYTE)&flen, sizeof (flen), 1, fh);
|
||||
// Write the uncompressed size.
|
||||
cwrite_32 (fh, flen);
|
||||
while (flen)
|
||||
{
|
||||
COUNT num_bytes;
|
||||
|
||||
num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
|
||||
ReadStateFile (buf, num_bytes, 1, fp);
|
||||
cwrite ((PBYTE)buf, num_bytes, 1, fh);
|
||||
cwrite (buf, num_bytes, 1, fh);
|
||||
|
||||
flen -= num_bytes;
|
||||
}
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
|
||||
// Copy the ? groupinfo file into the memory file (compressed).
|
||||
// Copy the random groupinfo file into the memory file (compressed)
|
||||
fp = OpenStateFile (RANDGRPINFO_FILE, "rb");
|
||||
if (fp)
|
||||
{
|
||||
flen = LengthStateFile (fp);
|
||||
cwrite ((PBYTE)&flen, sizeof (flen), 1, fh);
|
||||
// Write the uncompressed size.
|
||||
cwrite_32 (fh, flen);
|
||||
while (flen)
|
||||
{
|
||||
COUNT num_bytes;
|
||||
|
||||
num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
|
||||
ReadStateFile (buf, num_bytes, 1, fp);
|
||||
cwrite ((PBYTE)buf, num_bytes, 1, fh);
|
||||
cwrite (buf, num_bytes, 1, fh);
|
||||
|
||||
flen -= num_bytes;
|
||||
}
|
||||
@@ -471,22 +718,19 @@ RetrySave:
|
||||
}
|
||||
|
||||
// Write the current star desc into the memory file (compressed).
|
||||
cwrite ((PBYTE)&SD, sizeof (SD), 1, fh);
|
||||
SaveStarDesc (&SD, fh);
|
||||
|
||||
flen = cclose (fh);
|
||||
|
||||
// Write the memory file to the actual savegame file.
|
||||
sprintf (file, "starcon2.%02u", which_game);
|
||||
log_add (log_Debug, "'%s' is %u bytes long", file,
|
||||
flen + sizeof (*summary_desc));
|
||||
if (flen && (out_fp = (PVOID)res_OpenResFile (saveDir, file, "wb")))
|
||||
flen + sizeof (*SummPtr));
|
||||
if (flen && (out_fp = res_OpenResFile (saveDir, file, "wb")))
|
||||
{
|
||||
PrepareSummary (summary_desc);
|
||||
PrepareSummary (SummPtr);
|
||||
|
||||
// First write the summary.
|
||||
success = (BOOLEAN)(WriteResFile (
|
||||
summary_desc, sizeof (*summary_desc), 1, out_fp) != 0);
|
||||
|
||||
success = SaveSummary (SummPtr, out_fp);
|
||||
// Then write the rest of the data.
|
||||
if (success && WriteResFile (mem_lock (h), (COUNT)flen, 1,
|
||||
out_fp) == 0)
|
||||
@@ -513,4 +757,3 @@ RetrySave:
|
||||
return (success);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ static RACE_DESC androsynth_desc =
|
||||
FIRES_FORE | SEEKING_WEAPON,
|
||||
15, /* Super Melee cost */
|
||||
~0, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
MAX_X_UNIVERSE >> 1, MAX_Y_UNIVERSE >> 1,
|
||||
@@ -51,7 +51,6 @@ static RACE_DESC androsynth_desc =
|
||||
(STRING)ANDROSYNTH_RACE_STRINGS,
|
||||
(FRAME)ANDROSYNTH_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)ANDROSYNTH_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -45,7 +45,7 @@ static RACE_DESC arilou_desc =
|
||||
/* FIRES_FORE | */ IMMEDIATE_WEAPON,
|
||||
16, /* Super Melee cost */
|
||||
250 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
438, 6372,
|
||||
@@ -53,7 +53,6 @@ static RACE_DESC arilou_desc =
|
||||
(STRING)ARILOU_RACE_STRINGS,
|
||||
(FRAME)ARILOU_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)ARILOU_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -47,7 +47,7 @@ static RACE_DESC black_urquan_desc =
|
||||
FIRES_FORE,
|
||||
30, /* Super Melee cost */
|
||||
2666 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
6000, 6250,
|
||||
@@ -55,7 +55,6 @@ static RACE_DESC black_urquan_desc =
|
||||
(STRING)KOHR_AH_RACE_STRINGS,
|
||||
(FRAME)KOHR_AH_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)KOHR_AH_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -50,7 +50,7 @@ static RACE_DESC chenjesu_desc =
|
||||
FIRES_FORE | SEEKING_SPECIAL | SEEKING_WEAPON,
|
||||
28, /* Super Melee cost */
|
||||
0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
0, 0,
|
||||
@@ -58,7 +58,6 @@ static RACE_DESC chenjesu_desc =
|
||||
(STRING)CHENJESU_RACE_STRINGS,
|
||||
(FRAME)CHENJESU_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)CHENJESU_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -47,7 +47,7 @@ static RACE_DESC chmmr_desc =
|
||||
FIRES_FORE | IMMEDIATE_WEAPON | SEEKING_SPECIAL | POINT_DEFENSE,
|
||||
30, /* Super Melee cost */
|
||||
0, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
0, 0,
|
||||
@@ -55,7 +55,6 @@ static RACE_DESC chmmr_desc =
|
||||
(STRING)CHMMR_RACE_STRINGS,
|
||||
(FRAME)CHMMR_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)CHMMR_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -43,7 +43,7 @@ static RACE_DESC druuge_desc =
|
||||
FIRES_FORE,
|
||||
17, /* Super Melee cost */
|
||||
1400 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
9500, 2792,
|
||||
@@ -51,7 +51,6 @@ static RACE_DESC druuge_desc =
|
||||
(STRING)DRUUGE_RACE_STRINGS,
|
||||
(FRAME)DRUUGE_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)DRUUGE_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -47,7 +47,7 @@ static RACE_DESC human_desc =
|
||||
FIRES_FORE | SEEKING_WEAPON | POINT_DEFENSE,
|
||||
11, /* Super Melee cost */
|
||||
0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
1752, 1450,
|
||||
@@ -55,7 +55,6 @@ static RACE_DESC human_desc =
|
||||
(STRING)HUMAN_RACE_STRINGS,
|
||||
(FRAME)HUMAN_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)HUMAN_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -45,7 +45,7 @@ static RACE_DESC ilwrath_desc =
|
||||
FIRES_FORE,
|
||||
10, /* Super Melee cost */
|
||||
1410 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
48, 1700,
|
||||
@@ -53,7 +53,6 @@ static RACE_DESC ilwrath_desc =
|
||||
(STRING)ILWRATH_RACE_STRINGS,
|
||||
(FRAME)ILWRATH_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)ILWRATH_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -50,7 +50,7 @@ static RACE_DESC samatra_desc =
|
||||
/* FIRES_FORE | */ IMMEDIATE_WEAPON | CREW_IMMUNE,
|
||||
16, /* Super Melee cost */
|
||||
0, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
0, 0,
|
||||
@@ -58,7 +58,6 @@ static RACE_DESC samatra_desc =
|
||||
(STRING)0,
|
||||
(FRAME)0,
|
||||
(FRAME)0,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -46,7 +46,7 @@ static RACE_DESC melnorme_desc =
|
||||
FIRES_FORE,
|
||||
18, /* Super Melee cost */
|
||||
~0, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
MAX_X_UNIVERSE >> 1, MAX_Y_UNIVERSE >> 1,
|
||||
@@ -54,7 +54,6 @@ static RACE_DESC melnorme_desc =
|
||||
(STRING)MELNORME_RACE_STRINGS,
|
||||
(FRAME)MELNORME_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)MELNORME_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -58,7 +58,7 @@ static RACE_DESC mmrnmhrm_desc =
|
||||
FIRES_FORE | IMMEDIATE_WEAPON,
|
||||
19, /* Super Melee cost */
|
||||
0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
0, 0,
|
||||
@@ -66,7 +66,6 @@ static RACE_DESC mmrnmhrm_desc =
|
||||
(STRING)MMRNMHRM_RACE_STRINGS,
|
||||
(FRAME)MMRNMHRM_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)MMRNMHRM_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -46,7 +46,7 @@ static RACE_DESC mycon_desc =
|
||||
FIRES_FORE | SEEKING_WEAPON,
|
||||
21, /* Super Melee cost */
|
||||
1070 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
6392, 2200,
|
||||
@@ -54,7 +54,6 @@ static RACE_DESC mycon_desc =
|
||||
(STRING)MYCON_RACE_STRINGS,
|
||||
(FRAME)MYCON_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)MYCON_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -48,7 +48,7 @@ static RACE_DESC orz_desc =
|
||||
FIRES_FORE | SEEKING_SPECIAL,
|
||||
23, /* Super Melee cost */
|
||||
333 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
3608, 2637,
|
||||
@@ -56,7 +56,6 @@ static RACE_DESC orz_desc =
|
||||
(STRING)ORZ_RACE_STRINGS,
|
||||
(FRAME)ORZ_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)ORZ_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -46,7 +46,7 @@ static RACE_DESC pkunk_desc =
|
||||
FIRES_FORE | FIRES_LEFT | FIRES_RIGHT,
|
||||
20, /* Super Melee cost */
|
||||
666 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
502, 401,
|
||||
@@ -54,7 +54,6 @@ static RACE_DESC pkunk_desc =
|
||||
(STRING)PKUNK_RACE_STRINGS,
|
||||
(FRAME)PKUNK_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)PKUNK_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -40,7 +40,7 @@ static RACE_DESC probe_desc =
|
||||
0,
|
||||
0, /* Super Melee cost */
|
||||
0, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
0, 0,
|
||||
@@ -48,7 +48,6 @@ static RACE_DESC probe_desc =
|
||||
0,
|
||||
0,
|
||||
(FRAME)PROBE_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -46,7 +46,7 @@ static RACE_DESC shofixti_desc =
|
||||
FIRES_FORE,
|
||||
5, /* Super Melee cost */
|
||||
0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
0, 0,
|
||||
@@ -54,7 +54,6 @@ static RACE_DESC shofixti_desc =
|
||||
(STRING)SHOFIXTI_RACE_STRINGS,
|
||||
(FRAME)SHOFIXTI_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)SHOFIXTI_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -52,7 +52,7 @@ static RACE_DESC sis_desc =
|
||||
0,
|
||||
16, /* Super Melee cost */
|
||||
0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
0, 0,
|
||||
@@ -60,7 +60,6 @@ static RACE_DESC sis_desc =
|
||||
0,
|
||||
(FRAME)SIS_ICON_MASK_PMAP_ANIM,
|
||||
0,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -45,7 +45,7 @@ static RACE_DESC slylandro_desc =
|
||||
SEEKING_WEAPON | CREW_IMMUNE,
|
||||
17, /* Super Melee cost */
|
||||
~0, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
333, 9812,
|
||||
@@ -53,7 +53,6 @@ static RACE_DESC slylandro_desc =
|
||||
(STRING)SLYLANDRO_RACE_STRINGS,
|
||||
(FRAME)SLYLANDRO_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)SLYLANDRO_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -43,7 +43,7 @@ static RACE_DESC spathi_desc =
|
||||
FIRES_FORE | FIRES_AFT | SEEKING_SPECIAL | DONT_CHASE,
|
||||
18, /* Super Melee cost */
|
||||
1000 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
2549, 3600,
|
||||
@@ -51,7 +51,6 @@ static RACE_DESC spathi_desc =
|
||||
(STRING)SPATHI_RACE_STRINGS,
|
||||
(FRAME)SPATHI_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)SPATHI_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -45,7 +45,7 @@ static RACE_DESC supox_desc =
|
||||
FIRES_FORE,
|
||||
16, /* Super Melee cost */
|
||||
333 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
7468, 9246,
|
||||
@@ -53,7 +53,6 @@ static RACE_DESC supox_desc =
|
||||
(STRING)SUPOX_RACE_STRINGS,
|
||||
(FRAME)SUPOX_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)SUPOX_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -46,7 +46,7 @@ static RACE_DESC syreen_desc =
|
||||
FIRES_FORE,
|
||||
13, /* Super Melee cost */
|
||||
0 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, SYREEN_MAX_CREW_SIZE,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
0, 0,
|
||||
@@ -54,7 +54,6 @@ static RACE_DESC syreen_desc =
|
||||
(STRING)SYREEN_RACE_STRINGS,
|
||||
(FRAME)SYREEN_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)SYREEN_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, SYREEN_MAX_CREW_SIZE,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -46,7 +46,7 @@ static RACE_DESC thraddash_desc =
|
||||
FIRES_FORE,
|
||||
10, /* Super Melee cost */
|
||||
833 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
2535, 8358,
|
||||
@@ -54,7 +54,6 @@ static RACE_DESC thraddash_desc =
|
||||
(STRING)THRADDASH_RACE_STRINGS,
|
||||
(FRAME)THRADDASH_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)THRADDASH_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -45,7 +45,7 @@ static RACE_DESC umgah_desc =
|
||||
FIRES_FORE | IMMEDIATE_WEAPON,
|
||||
7, /* Super Melee cost */
|
||||
833 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
1798, 6000,
|
||||
@@ -53,7 +53,6 @@ static RACE_DESC umgah_desc =
|
||||
(STRING)UMGAH_RACE_STRINGS,
|
||||
(FRAME)UMGAH_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)UMGAH_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -47,7 +47,7 @@ static RACE_DESC urquan_desc =
|
||||
FIRES_FORE | SEEKING_SPECIAL,
|
||||
30, /* Super Melee cost */
|
||||
2666 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
5750, 6000,
|
||||
@@ -55,7 +55,6 @@ static RACE_DESC urquan_desc =
|
||||
(STRING)URQUAN_RACE_STRINGS,
|
||||
(FRAME)URQUAN_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)URQUAN_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -47,7 +47,7 @@ static RACE_DESC utwig_desc =
|
||||
FIRES_FORE | POINT_DEFENSE | SHIELD_DEFENSE,
|
||||
22, /* Super Melee cost */
|
||||
666 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY >> 1, MAX_ENERGY,
|
||||
{
|
||||
8534, 8797,
|
||||
@@ -55,7 +55,6 @@ static RACE_DESC utwig_desc =
|
||||
(STRING)UTWIG_RACE_STRINGS,
|
||||
(FRAME)UTWIG_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)UTWIG_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -48,7 +48,7 @@ static RACE_DESC vux_desc =
|
||||
FIRES_FORE | SEEKING_SPECIAL | IMMEDIATE_WEAPON,
|
||||
12, /* Super Melee cost */
|
||||
900 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
4412, 1558,
|
||||
@@ -56,7 +56,6 @@ static RACE_DESC vux_desc =
|
||||
(STRING)VUX_RACE_STRINGS,
|
||||
(FRAME)VUX_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)VUX_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -45,7 +45,7 @@ static RACE_DESC yehat_desc =
|
||||
FIRES_FORE | SHIELD_DEFENSE,
|
||||
23, /* Super Melee cost */
|
||||
750 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
4970, 40,
|
||||
@@ -53,7 +53,6 @@ static RACE_DESC yehat_desc =
|
||||
(STRING)YEHAT_RACE_STRINGS,
|
||||
(FRAME)YEHAT_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)YEHAT_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -46,7 +46,7 @@ static RACE_DESC zoqfotpik_desc =
|
||||
FIRES_FORE,
|
||||
6, /* Super Melee cost */
|
||||
320 / SPHERE_RADIUS_INCREMENT, /* Initial sphere of influence radius */
|
||||
0, 0, /* Hack; old crew field */
|
||||
MAX_CREW, MAX_CREW,
|
||||
MAX_ENERGY, MAX_ENERGY,
|
||||
{
|
||||
3761, 5333,
|
||||
@@ -54,7 +54,6 @@ static RACE_DESC zoqfotpik_desc =
|
||||
(STRING)ZOQFOTPIK_RACE_STRINGS,
|
||||
(FRAME)ZOQFOTPIK_ICON_MASK_PMAP_ANIM,
|
||||
(FRAME)ZOQFOTPIK_MICON_MASK_PMAP_ANIM,
|
||||
MAX_CREW, MAX_CREW,
|
||||
},
|
||||
{
|
||||
MAX_THRUST,
|
||||
|
||||
@@ -196,6 +196,8 @@ enum
|
||||
#define STATUS_MESSAGE_WIDTH 60
|
||||
#define STATUS_MESSAGE_HEIGHT 7
|
||||
|
||||
#define SIS_NAME_SIZE 16
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDWORD log_x, log_y;
|
||||
@@ -216,9 +218,9 @@ typedef struct
|
||||
|
||||
COUNT ElementAmounts[NUM_ELEMENT_CATEGORIES];
|
||||
|
||||
UNICODE ShipName[16];
|
||||
UNICODE CommanderName[16];
|
||||
UNICODE PlanetName[16];
|
||||
UNICODE ShipName[SIS_NAME_SIZE];
|
||||
UNICODE CommanderName[SIS_NAME_SIZE];
|
||||
UNICODE PlanetName[SIS_NAME_SIZE];
|
||||
} SIS_STATE;
|
||||
typedef SIS_STATE *PSIS_STATE;
|
||||
|
||||
|
||||
+33
-43
@@ -54,7 +54,7 @@ OpenStateFile (int stateFile, const char *mode)
|
||||
GAME_STATE_FILE *fp;
|
||||
|
||||
if (stateFile < 0 || stateFile >= NUM_STATE_FILES)
|
||||
return NULL_PTR;
|
||||
return NULL;
|
||||
|
||||
fp = &state_files[stateFile];
|
||||
fp->open_count++;
|
||||
@@ -67,7 +67,7 @@ OpenStateFile (int stateFile, const char *mode)
|
||||
{
|
||||
fp->data = HMalloc (fp->size_hint);
|
||||
if (!fp->data)
|
||||
return NULL_PTR;
|
||||
return NULL;
|
||||
fp->size = fp->size_hint;
|
||||
}
|
||||
|
||||
@@ -185,15 +185,6 @@ WriteStateFile (PVOID lpBuf, COUNT size, COUNT count, GAME_STATE_FILE *fp)
|
||||
return (bytes / size);
|
||||
}
|
||||
|
||||
int
|
||||
PutStateFileChar (char ch, GAME_STATE_FILE *fp)
|
||||
{
|
||||
if (1 == WriteStateFile (&ch, sizeof(ch), 1, fp))
|
||||
return ch;
|
||||
else
|
||||
return EOF;
|
||||
}
|
||||
|
||||
int
|
||||
SeekStateFile (GAME_STATE_FILE *fp, long offset, int whence)
|
||||
{
|
||||
@@ -220,14 +211,13 @@ InitPlanetInfo (void)
|
||||
fp = OpenStateFile (STARINFO_FILE, "wb");
|
||||
if (fp)
|
||||
{
|
||||
DWORD offset;
|
||||
STAR_DESCPTR pSD;
|
||||
|
||||
offset = 0;
|
||||
// Set record offsets for all stars to 0 (not present)
|
||||
pSD = &star_array[0];
|
||||
do
|
||||
{
|
||||
WriteStateFile (&offset, sizeof (offset), 1, fp);
|
||||
swrite_32 (fp, 0);
|
||||
++pSD;
|
||||
} while (pSD->star_pt.x <= MAX_X_UNIVERSE
|
||||
&& pSD->star_pt.y <= MAX_Y_UNIVERSE);
|
||||
@@ -242,6 +232,9 @@ UninitPlanetInfo (void)
|
||||
DeleteStateFile (STARINFO_FILE);
|
||||
}
|
||||
|
||||
#define OFFSET_SIZE (sizeof (DWORD))
|
||||
#define SCAN_RECORD_SIZE (sizeof (DWORD) * NUM_SCAN_TYPES)
|
||||
|
||||
void
|
||||
GetPlanetInfo (void)
|
||||
{
|
||||
@@ -266,27 +259,24 @@ GetPlanetInfo (void)
|
||||
moon_index = (COUNT)(pSolarSysState->pOrbitalDesc
|
||||
- pSolarSysState->MoonDesc + 1);
|
||||
|
||||
SeekStateFile (fp, star_index * sizeof (offset), SEEK_SET);
|
||||
ReadStateFile (&offset, sizeof (offset), 1, fp);
|
||||
SeekStateFile (fp, star_index * OFFSET_SIZE, SEEK_SET);
|
||||
sread_32 (fp, &offset);
|
||||
|
||||
if (offset)
|
||||
{
|
||||
COUNT i;
|
||||
|
||||
// Skip scan records for all preceeding planets to the one we need
|
||||
for (i = 0; i < planet_index; ++i)
|
||||
offset += sizeof (
|
||||
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask
|
||||
) * (pSolarSysState->PlanetDesc[i].NumPlanets + 1);
|
||||
offset += (pSolarSysState->PlanetDesc[i].NumPlanets + 1) *
|
||||
SCAN_RECORD_SIZE;
|
||||
|
||||
offset += sizeof (
|
||||
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask
|
||||
) * moon_index;
|
||||
// Skip scan records for all preceeding moons to the one we need
|
||||
offset += moon_index * SCAN_RECORD_SIZE;
|
||||
|
||||
SeekStateFile (fp, offset, SEEK_SET);
|
||||
ReadStateFile (pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask,
|
||||
sizeof (
|
||||
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask
|
||||
), 1, fp);
|
||||
sread_a32 (fp, pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask,
|
||||
NUM_SCAN_TYPES);
|
||||
}
|
||||
|
||||
CloseStateFile (fp);
|
||||
@@ -314,11 +304,11 @@ PutPlanetInfo (void)
|
||||
moon_index = (COUNT)(pSolarSysState->pOrbitalDesc
|
||||
- pSolarSysState->MoonDesc + 1);
|
||||
|
||||
SeekStateFile (fp, star_index * sizeof (offset), SEEK_SET);
|
||||
ReadStateFile (&offset, sizeof (offset), 1, fp);
|
||||
SeekStateFile (fp, star_index * OFFSET_SIZE, SEEK_SET);
|
||||
sread_32 (fp, &offset);
|
||||
|
||||
if (offset == 0)
|
||||
{
|
||||
{ // Scan record not present yet -- init it
|
||||
DWORD ScanRetrieveMask[NUM_SCAN_TYPES] =
|
||||
{
|
||||
0, 0, 0,
|
||||
@@ -326,34 +316,34 @@ PutPlanetInfo (void)
|
||||
|
||||
offset = LengthStateFile (fp);
|
||||
|
||||
SeekStateFile (fp, star_index * sizeof (offset), SEEK_SET);
|
||||
WriteStateFile (&offset, sizeof (offset), 1, fp);
|
||||
// Write the record offset
|
||||
SeekStateFile (fp, star_index * OFFSET_SIZE, SEEK_SET);
|
||||
swrite_32 (fp, offset);
|
||||
|
||||
// Init scan records for all planets and moons in the system
|
||||
SeekStateFile (fp, offset, SEEK_SET);
|
||||
for (i = 0; i < pSolarSysState->SunDesc[0].NumPlanets; ++i)
|
||||
{
|
||||
COUNT j;
|
||||
|
||||
WriteStateFile (ScanRetrieveMask, sizeof (ScanRetrieveMask), 1, fp);
|
||||
swrite_a32 (fp, ScanRetrieveMask, NUM_SCAN_TYPES);
|
||||
// init moons
|
||||
for (j = 0; j < pSolarSysState->PlanetDesc[i].NumPlanets; ++j)
|
||||
WriteStateFile (ScanRetrieveMask, sizeof (ScanRetrieveMask), 1, fp);
|
||||
swrite_a32 (fp, ScanRetrieveMask, NUM_SCAN_TYPES);
|
||||
}
|
||||
}
|
||||
|
||||
// Skip scan records for all preceeding planets to the one we need
|
||||
for (i = 0; i < planet_index; ++i)
|
||||
offset += sizeof (
|
||||
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask
|
||||
) * (pSolarSysState->PlanetDesc[i].NumPlanets + 1);
|
||||
offset += (pSolarSysState->PlanetDesc[i].NumPlanets + 1) *
|
||||
SCAN_RECORD_SIZE;
|
||||
|
||||
offset += sizeof (
|
||||
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask
|
||||
) * moon_index;
|
||||
// Skip scan records for all preceeding moons to the one we need
|
||||
offset += moon_index * SCAN_RECORD_SIZE;
|
||||
|
||||
SeekStateFile (fp, offset, SEEK_SET);
|
||||
WriteStateFile (pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask,
|
||||
sizeof (
|
||||
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask
|
||||
), 1, fp);
|
||||
swrite_a32 (fp, pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask,
|
||||
NUM_SCAN_TYPES);
|
||||
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
|
||||
+71
-1
@@ -19,7 +19,9 @@
|
||||
#ifndef _STATE_H
|
||||
#define _STATE_H
|
||||
|
||||
#include "port.h"
|
||||
#include "libs/compiler.h"
|
||||
#include <assert.h>
|
||||
|
||||
extern void InitPlanetInfo (void);
|
||||
extern void UninitPlanetInfo (void);
|
||||
@@ -67,8 +69,76 @@ void DeleteStateFile (int stateFile);
|
||||
DWORD LengthStateFile (GAME_STATE_FILE *fp);
|
||||
int ReadStateFile (PVOID lpBuf, COUNT size, COUNT count, GAME_STATE_FILE *fp);
|
||||
int WriteStateFile (PVOID lpBuf, COUNT size, COUNT count, GAME_STATE_FILE *fp);
|
||||
int PutStateFileChar (char ch, GAME_STATE_FILE *fp);
|
||||
int SeekStateFile (GAME_STATE_FILE *fp, long offset, int whence);
|
||||
|
||||
static inline COUNT
|
||||
sread_8 (PVOID fp, PBYTE v)
|
||||
{
|
||||
BYTE t;
|
||||
if (!v) /* read value ignored */
|
||||
v = &t;
|
||||
return ReadStateFile (v, 1, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
sread_16 (PVOID fp, PUWORD v)
|
||||
{
|
||||
UWORD t;
|
||||
if (!v) /* read value ignored */
|
||||
v = &t;
|
||||
return ReadStateFile (v, 2, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
sread_32 (PVOID fp, PDWORD v)
|
||||
{
|
||||
DWORD t;
|
||||
if (!v) /* read value ignored */
|
||||
v = &t;
|
||||
return ReadStateFile (v, 4, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
sread_a32 (PVOID fp, PDWORD ar, COUNT count)
|
||||
{
|
||||
assert (ar != NULL);
|
||||
|
||||
for ( ; count > 0; --count, ++ar)
|
||||
{
|
||||
if (sread_32 (fp, ar) != 1)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
swrite_8 (PVOID fp, BYTE v)
|
||||
{
|
||||
return WriteStateFile (&v, 1, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
swrite_16 (PVOID fp, UWORD v)
|
||||
{
|
||||
return WriteStateFile (&v, 2, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
swrite_32 (PVOID fp, DWORD v)
|
||||
{
|
||||
return WriteStateFile (&v, 4, 1, fp);
|
||||
}
|
||||
|
||||
static inline COUNT
|
||||
swrite_a32 (PVOID fp, PDWORD ar, COUNT count)
|
||||
{
|
||||
for ( ; count > 0; --count, ++ar)
|
||||
{
|
||||
if (swrite_32 (fp, *ar) != 1)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* _STATE_H */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user