Finalize the work on the new save file format.
Remove all references to state files from the format. Some still leaks in in the GmSt chunk, but those are ignored or overwritten by later loading phases.
This commit is contained in:
+37
-50
@@ -71,7 +71,8 @@ save file.
|
||||
|
||||
- "GlSt": Global State. This chunk must come second, after
|
||||
Summ. Represents most of the data in the global state structure in
|
||||
globdata.h.
|
||||
globdata.h. BattleGroupRef is excised from this; its value is
|
||||
computed later on.
|
||||
|
||||
- "GmSt": Game State. This chunk must come third, after GlSt. This is
|
||||
the gigantic bitfield that the GET_GAME_STATE macros modify. It is
|
||||
@@ -107,56 +108,42 @@ save file.
|
||||
- "Star": Star Description. Basic indexing information to indicate
|
||||
which star system you are in.
|
||||
|
||||
- "SISF": Star Info State File. An index into which planetside
|
||||
resources you have investigated and collected. See
|
||||
doc/devel/statefiles for more details.
|
||||
- "Scan": Scanner Masks. This is a semi-structured tree of DWORDs that
|
||||
represents which planetary resources have been captured or
|
||||
removed. It is a format roughly similar to the old star info
|
||||
statefile format (see doc/devel/statefile) but little-endianness is
|
||||
enforced, making this chunk endian-safe where the old statefile dump
|
||||
was not.
|
||||
|
||||
- "DGSF": Defined Group State File. Battlegroup information for
|
||||
space-based encounters dictated by the plot. See
|
||||
doc/devel/statefiles for more details.
|
||||
- "BtGp": Battle Group. Defines the relevant information for all ships
|
||||
in a given star system. This includes an "encounter ID" - randomly
|
||||
generated fleets have an encounter ID of zero, and ones built by the
|
||||
plot have an 32-bit identifier. Vanilla UQM reserves the first 32
|
||||
encounter IDs for itself, and uses 15 of them (random encounter,
|
||||
Ur-Quan Probe, Shofixti Survivor, Zoq-Fot-Pik Emissary, Unzervalt
|
||||
Guardian, nine Melnorme Traders, and the final boss). This also
|
||||
includes the expiration date for random encounters and which system
|
||||
they are relevant to. Much of this information was originally stored
|
||||
in randgrp.dat, but it has echoes in defgrp.dat as well. The data
|
||||
here is a ragged 2D array of a slight extension of the SHIP_FRAGMENT
|
||||
structure. There is one BtGp chunk per defined group. (Since one of
|
||||
these is defined at game start, and the random encounter structure
|
||||
has values that mean 'no encounter present', there should always be
|
||||
at least two of these chunks in any save.)
|
||||
|
||||
- "RGSF": Random Group State File. Battlegroup information for random
|
||||
encounters in interplanetary space. See doc/devel/statefiles for
|
||||
more details.
|
||||
- "Grps": Active Battle Groups. These are IP_GROUP structures to
|
||||
supplement the SHIP_FRAGMENTs specified in BtGp chunks. They give
|
||||
more detailed information about the precise location and disposition
|
||||
of each ship in the system you are either in or most recently left.
|
||||
|
||||
- "Scan": Scanner Masks. NOT YET IMPLEMENTED; WILL REPLACE SISF. It
|
||||
might just be a rename with better endianness enforcement, though;
|
||||
the SISF dump is pretty well-structured as it is.
|
||||
THINGS LEFT TO DO
|
||||
-----------------
|
||||
|
||||
- "DGrp": Defined Group. NOT YET IMPLEMENTED; WILL REPLACE DGSF. Will
|
||||
carry an enumeration id to indicate which of the defgrps it is
|
||||
(that's currently intrinsic to the game state bit array) and will
|
||||
also have a bit indicating whether or not it is the "current"
|
||||
defgrp. If no defgrp is current, BattleGroupRef is 0; otherwise,
|
||||
BattleGroupRef is the defgrp file offset that corresponds to the
|
||||
current system. There will be one DGrp chunk for each system with an
|
||||
active defgrp record.
|
||||
|
||||
- NOT YET DESIGNED: RGSF also needs to be replaced with one or more
|
||||
chunk types. This will likely be similar to the DGrp chunks, but
|
||||
there are stronger constraints on repetition here.
|
||||
|
||||
THINGS LEFT TO DO BEFORE MERGING
|
||||
--------------------------------
|
||||
|
||||
- Actually enforce little-endianness of everything that hits the disk.
|
||||
- Everything that isn't a State File now respects this.
|
||||
- State files are going to require more work (see below).
|
||||
|
||||
- There are 448 bits in GmSt that are actually indices into DGSF. They
|
||||
shouldn't be there. In fact, they shouldn't even be in the
|
||||
GAME_STATE array either. They should be an array of DWORDs living
|
||||
independently in the global state
|
||||
- In preparation for this, the GRPOFFS state has been moved to the
|
||||
end of the state array. We'll be able to eradicate it once the
|
||||
state files are no longer part of the save.
|
||||
|
||||
- The State Files are (except maybe for Star Info) a horrible mess and
|
||||
we should not be replicating them in the save file. We should
|
||||
instead be regenerating them from more structured forms.
|
||||
- Once we do this we can start computing new values for the GRPOFFS
|
||||
state and the BattleGroupRef based on the new chunks. We can then
|
||||
remove the GRPOFFS bits from the GmSt chunk and the BattleGroupRef
|
||||
from the GlSt chunk. From there we can see our way to eradicating
|
||||
the state file abstraction entirely, but that will be quite a bit
|
||||
more work.
|
||||
The last 448 bits in GmSt probably shouldn't exist. However, we should
|
||||
not remove them from the source base (and thus the save file) until
|
||||
after other pending commits have been merged. When this happens, we
|
||||
can break out those bits into an array of DWORDs instead. The loading
|
||||
code basically ignores those GmSt bits by overwriting them while
|
||||
loading later chunks, and GmSt is an expandable array in the first
|
||||
place, so removing those final bits from the Game State array should
|
||||
be compatible in both directions.
|
||||
|
||||
+1
-33
@@ -298,7 +298,7 @@ LoadGameState (GAME_STATE *GSPtr, void *fh)
|
||||
return FALSE;
|
||||
}
|
||||
read_32 (fh, &magic);
|
||||
if (magic != 79)
|
||||
if (magic != 75)
|
||||
{
|
||||
/* Chunk is the wrong size. */
|
||||
return FALSE;
|
||||
@@ -334,8 +334,6 @@ LoadGameState (GAME_STATE *GSPtr, void *fh)
|
||||
read_16s (fh, &GSPtr->velocity.incr.width);
|
||||
read_16s (fh, &GSPtr->velocity.incr.height);
|
||||
|
||||
read_32 (fh, &GSPtr->BattleGroupRef);
|
||||
|
||||
read_32 (fh, &magic);
|
||||
if (magic != GAME_STATE_TAG)
|
||||
{
|
||||
@@ -446,27 +444,6 @@ LoadStarDesc (STAR_DESC *SDPtr, void *fh)
|
||||
read_8 (fh, &SDPtr->Postfix);
|
||||
}
|
||||
|
||||
static void
|
||||
LoadStateFile (int file_type, void *fh, DWORD flen)
|
||||
{
|
||||
GAME_STATE_FILE *fp = OpenStateFile (file_type, "wb");
|
||||
char buf[256];
|
||||
if (fp)
|
||||
{
|
||||
while (flen)
|
||||
{
|
||||
COUNT num_bytes;
|
||||
|
||||
num_bytes = flen >= sizeof (buf) ? sizeof (buf) : (COUNT)flen;
|
||||
read_a8 (fh, buf, num_bytes);
|
||||
WriteStateFile (buf, num_bytes, 1, fp);
|
||||
|
||||
flen -= num_bytes;
|
||||
}
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LoadScanInfo (uio_Stream *fh, DWORD flen)
|
||||
{
|
||||
@@ -765,15 +742,6 @@ LoadGame (COUNT which_game, SUMMARY_DESC *SummPtr)
|
||||
}
|
||||
LoadBattleGroup (in_fp, chunkSize);
|
||||
break;
|
||||
case STAR_SF_TAG:
|
||||
LoadStateFile (STARINFO_FILE, in_fp, chunkSize);
|
||||
break;
|
||||
case DEFGRP_SF_TAG:
|
||||
LoadStateFile (DEFGRPINFO_FILE, in_fp, chunkSize);
|
||||
break;
|
||||
case RANDGRP_SF_TAG:
|
||||
LoadStateFile (RANDGRPINFO_FILE, in_fp, chunkSize);
|
||||
break;
|
||||
default:
|
||||
log_add (log_Debug, "Skipping chunk of tag %08X (size %u)", chunk, chunkSize);
|
||||
if (skip_8(in_fp, chunkSize) != 1)
|
||||
|
||||
+5
-9
@@ -330,7 +330,7 @@ static void
|
||||
SaveGameState (const GAME_STATE *GSPtr, uio_Stream *fh)
|
||||
{
|
||||
write_32 (fh, GLOBAL_STATE_TAG);
|
||||
write_32 (fh, 79);
|
||||
write_32 (fh, 75);
|
||||
write_8 (fh, GSPtr->glob_flags);
|
||||
write_8 (fh, GSPtr->CrewCost);
|
||||
write_8 (fh, GSPtr->FuelCost);
|
||||
@@ -362,9 +362,9 @@ SaveGameState (const GAME_STATE *GSPtr, uio_Stream *fh)
|
||||
write_16 (fh, GSPtr->velocity.incr.width);
|
||||
write_16 (fh, GSPtr->velocity.incr.height);
|
||||
|
||||
write_32 (fh, GSPtr->BattleGroupRef);
|
||||
|
||||
/* The Game state bits. Vanilla UQM uses 155 bytes here. */
|
||||
/* The Game state bits. Vanilla UQM uses 155 bytes here at
|
||||
* present. Only the first 99 bytes are significant, though;
|
||||
* the rest will be overwritten by the BtGp chunks. */
|
||||
write_32 (fh, GAME_STATE_TAG);
|
||||
write_32 (fh, sizeof (GSPtr->GameState));
|
||||
write_a8 (fh, GSPtr->GameState, sizeof (GSPtr->GameState));
|
||||
@@ -815,11 +815,7 @@ SaveGame (COUNT which_game, SUMMARY_DESC *SummPtr, const char *name)
|
||||
// Save the encounter chunk (black globes in HS/QS)
|
||||
SaveEncounters (out_fp);
|
||||
|
||||
// Save out the state file chunks.
|
||||
SaveStateFile (STARINFO_FILE, STAR_SF_TAG, out_fp);
|
||||
SaveStateFile (DEFGRPINFO_FILE, DEFGRP_SF_TAG, out_fp);
|
||||
SaveStateFile (RANDGRPINFO_FILE, RANDGRP_SF_TAG, out_fp);
|
||||
|
||||
// Save out the data that used to be in state files
|
||||
SaveStarInfo (out_fp);
|
||||
SaveGroups (out_fp);
|
||||
|
||||
|
||||
@@ -48,9 +48,6 @@ extern "C" {
|
||||
#define SCAN_TAG 0x6e616353 // "Scan": Scan Masks (stuff picked up)
|
||||
#define BATTLE_GROUP_TAG 0x70477442 // "BtGp": Battle Group definition
|
||||
#define GROUP_LIST_TAG 0x73707247 // "Grps": Group List
|
||||
#define STAR_SF_TAG 0x46534953 // "SISF": Star Info State File
|
||||
#define DEFGRP_SF_TAG 0x46534744 // "DGSF": Defined Group State File
|
||||
#define RANDGRP_SF_TAG 0x46534752 // "RGSF": Random Group State File
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user