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:
Michael Martin
2013-10-19 16:59:36 -07:00
parent f271e8270c
commit f66cbbcd89
4 changed files with 49 additions and 101 deletions
+37 -50
View File
@@ -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
View File
@@ -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
View File
@@ -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);
-3
View File
@@ -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
{