* Use the tagfile format for score.bjo (and rename it to score.tag)

git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@3341 4a71c877-e1ca-e34f-864e-861f7616d084
master
Giel van Schijndel 2008-01-04 15:24:22 +00:00
parent e722d7ec39
commit 4d8da13cb4
3 changed files with 60 additions and 120 deletions

View File

@ -0,0 +1,19 @@
#
# FORMAT: tag enum, value representation (VR), value multiplicity (VM), default value
# VR: ST for text, US for unsigned, SI for signed, FP for floating point, GR for group,
# EN for group end, BO for boolean
# VM: Must be no longer than the size given here; set to 00 for repeating groups
# default value cannot be set for VM > 1, ST, GR or EN
#
01 ST 12 - # Format identifier: "ScoreData"
02 US 01 - # units built
03 US 01 - # units killed
04 US 01 - # units lost
05 US 01 - # structures built
06 US 01 - # structures killed
07 US 01 - # structures lost
08 US 01 - # artifacts found
09 US 01 - # mission started
0A US 01 - # shots on target
0B US 01 - # shots off target
0C US 01 - # babas mowed down

View File

@ -3288,7 +3288,7 @@ BOOL loadGame(const char *pGameToLoad, BOOL keepObjects, BOOL freeMem, BOOL User
{
//load in the message list file
aFileName[fileExten] = '\0';
strcat(aFileName, "score.bjo");
strlcat(aFileName, "score.tag", sizeof(aFileName));
// Load the fx data from the chosen file
if (!readScoreData(aFileName))
@ -3774,7 +3774,7 @@ BOOL saveGame(char *aFileName, SDWORD saveType)
//added at V15 save
//create the message filename
aFileName[fileExtension] = '\0';
strcat(aFileName, "score.bjo");
strlcat(aFileName, "score.tag", sizeof(aFileName));
/*Write the data to the file*/
if (!writeScoreData(aFileName))
{

View File

@ -28,6 +28,7 @@
// --------------------------------------------------------------------
#include "lib/framework/frame.h"
#include "lib/framework/strres.h"
#include "lib/framework/tagfile.h"
#include "lib/gamelib/gtime.h"
#include "console.h"
#include "scores.h"
@ -517,86 +518,36 @@ void fillUpStats( void )
infoBars[STAT_STR_BUILT].number = missionData.strBuilt;
}
/** Write the given MISSION_DATA to the given file with endianness swapped correctly
* \param fileHandle a PhysicsFS file handle of the file to write to
* \param serializeScore a pointer to the MISSION_DATA to write serialized into the file
* \return true on success or false on the first encounterd error
*/
static bool serializeScoreData(PHYSFS_file* fileHandle, const MISSION_DATA* serializeScore)
{
return (PHYSFS_writeUBE32(fileHandle, serializeScore->unitsBuilt)
&& PHYSFS_writeUBE32(fileHandle, serializeScore->unitsKilled)
&& PHYSFS_writeUBE32(fileHandle, serializeScore->unitsLost)
&& PHYSFS_writeUBE32(fileHandle, serializeScore->strBuilt)
&& PHYSFS_writeUBE32(fileHandle, serializeScore->strKilled)
&& PHYSFS_writeUBE32(fileHandle, serializeScore->strLost)
&& PHYSFS_writeUBE32(fileHandle, serializeScore->artefactsFound)
&& PHYSFS_writeUBE32(fileHandle, serializeScore->missionStarted)
&& PHYSFS_writeUBE32(fileHandle, serializeScore->shotsOnTarget)
&& PHYSFS_writeUBE32(fileHandle, serializeScore->shotsOffTarget)
&& PHYSFS_writeUBE32(fileHandle, serializeScore->babasMowedDown));
}
/** Read a MISSION_DATA from the given file with endianness swapped correctly
* \param fileHandle a PhysicsFS file handle of the file to read from
* \param serializeScore a pointer to a MISSION_DATA to write the deserialized data from the file into
* \return true on success or false on the first encounterd error
*/
static bool deserializeScoreData(PHYSFS_file* fileHandle, MISSION_DATA* serializeScore)
{
return (PHYSFS_readUBE32(fileHandle, &serializeScore->unitsBuilt)
&& PHYSFS_readUBE32(fileHandle, &serializeScore->unitsKilled)
&& PHYSFS_readUBE32(fileHandle, &serializeScore->unitsLost)
&& PHYSFS_readUBE32(fileHandle, &serializeScore->strBuilt)
&& PHYSFS_readUBE32(fileHandle, &serializeScore->strKilled)
&& PHYSFS_readUBE32(fileHandle, &serializeScore->strLost)
&& PHYSFS_readUBE32(fileHandle, &serializeScore->artefactsFound)
&& PHYSFS_readUBE32(fileHandle, &serializeScore->missionStarted)
&& PHYSFS_readUBE32(fileHandle, &serializeScore->shotsOnTarget)
&& PHYSFS_readUBE32(fileHandle, &serializeScore->shotsOffTarget)
&& PHYSFS_readUBE32(fileHandle, &serializeScore->babasMowedDown));
}
static const char ScoreData_tag_definition[] = "testdata/tagfile_savegame_score.def";
static const char ScoreData_file_identifier[] = "ScoreData";
// -----------------------------------------------------------------------------------
/* This will save out the score data */
bool writeScoreData(const char* fileName)
{
SCORE_SAVEHEADER fileHeader;
PHYSFS_file* fileHandle = openSaveFile(fileName);
if (!fileHandle)
if (!tagOpenWrite(ScoreData_tag_definition, fileName))
{
debug(LOG_ERROR, "readFXData: error while opening file (%s)", fileName);
return false;
}
fileHeader.aFileType[0] = 's';
fileHeader.aFileType[1] = 'c';
fileHeader.aFileType[2] = 'd';
fileHeader.aFileType[3] = 'a';
tagWriteString(0x01, ScoreData_file_identifier);
fileHeader.version = CURRENT_VERSION_NUM;
fileHeader.entries = 1; // always for score save?
// Write out the current file header
if (PHYSFS_write(fileHandle, fileHeader.aFileType, sizeof(fileHeader.aFileType), 1) != 1
|| !PHYSFS_writeUBE32(fileHandle, fileHeader.version)
|| !PHYSFS_writeUBE32(fileHandle, fileHeader.entries))
{
debug(LOG_ERROR, "writeScoreData: could not write header to %s; PHYSFS error: %s", fileName, PHYSFS_getLastError());
PHYSFS_close(fileHandle);
return false;
}
// Write out the score data
if (!serializeScoreData(fileHandle, &missionData))
{
debug(LOG_ERROR, "writeScoreData: could not write to %s; PHYSFS error: %s", fileName, PHYSFS_getLastError());
PHYSFS_close(fileHandle);
return false;
}
// Dump the scores for the current player
tagWrite(0x02, missionData.unitsBuilt);
tagWrite(0x03, missionData.unitsKilled);
tagWrite(0x04, missionData.unitsLost);
tagWrite(0x05, missionData.strBuilt);
tagWrite(0x06, missionData.strKilled);
tagWrite(0x07, missionData.strLost);
tagWrite(0x08, missionData.artefactsFound);
tagWrite(0x09, missionData.missionStarted);
tagWrite(0x0A, missionData.shotsOnTarget);
tagWrite(0x0B, missionData.shotsOffTarget);
tagWrite(0x0C, missionData.babasMowedDown);
// Close the file
PHYSFS_close(fileHandle);
tagClose();
// Everything is just fine!
return true;
@ -606,68 +557,38 @@ bool writeScoreData(const char* fileName)
/* This will read in the score data */
bool readScoreData(const char* fileName)
{
SCORE_SAVEHEADER fileHeader;
char strbuffer[25];
unsigned int expectedFileSize, fileSize;
PHYSFS_file* fileHandle = openLoadFile(fileName, false);
if (!fileHandle)
if (!tagOpenRead(ScoreData_tag_definition, fileName))
{
// Failure to open the file is no failure to read it
return true;
}
// Read the header from the file
if (PHYSFS_read(fileHandle, fileHeader.aFileType, sizeof(fileHeader.aFileType), 1) != 1
|| !PHYSFS_readUBE32(fileHandle, &fileHeader.version)
|| !PHYSFS_readUBE32(fileHandle, &fileHeader.entries))
{
debug(LOG_ERROR, "readScoreData: error while reading header from file: %s", PHYSFS_getLastError());
PHYSFS_close(fileHandle);
debug(LOG_ERROR, "readFXData: error while opening file (%s)", fileName);
return false;
}
// Check the header to see if we've been given a file of the right type
if (fileHeader.aFileType[0] != 's'
|| fileHeader.aFileType[1] != 'c'
|| fileHeader.aFileType[2] != 'd'
|| fileHeader.aFileType[3] != 'a')
// Read & verify the format header identifier
tagReadString(0x01, sizeof(strbuffer), strbuffer);
if (strncmp(strbuffer, ScoreData_file_identifier, sizeof(strbuffer)) != 0)
{
debug(LOG_ERROR, "readScoreData: Weird file type found? Has header letters - '%c' '%c' '%c' '%c' (should be 's' 'c' 'd' 'a')",
fileHeader.aFileType[0],
fileHeader.aFileType[1],
fileHeader.aFileType[2],
fileHeader.aFileType[3]);
PHYSFS_close(fileHandle);
debug(LOG_ERROR, "readScoreData: Weird file type found (in file %s)? Has header string: %s", fileName, strbuffer);
return false;
}
// Validate the filesize
expectedFileSize = sizeof(fileHeader.aFileType) + sizeof(fileHeader.version) + sizeof(fileHeader.entries) + fileHeader.entries * sizeof(MISSION_DATA);
fileSize = PHYSFS_fileLength(fileHandle);
if (fileSize != expectedFileSize)
{
PHYSFS_close(fileHandle);
ASSERT(!"readScoreData: unexpected filesize", "readScoreData: unexpected filesize; should be %u, but is %u", expectedFileSize, fileSize);
abort();
return false;
}
// Write out the score data
if (!deserializeScoreData(fileHandle, &missionData))
{
debug(LOG_ERROR, "readScoreData: could not read from %s; PHYSFS error: %s", fileName, PHYSFS_getLastError());
PHYSFS_close(fileHandle);
return false;
}
// Retrieve the score data for the current player
missionData.unitsBuilt = tagRead(0x02);
missionData.unitsKilled = tagRead(0x03);
missionData.unitsLost = tagRead(0x04);
missionData.strBuilt = tagRead(0x05);
missionData.strKilled = tagRead(0x06);
missionData.strLost = tagRead(0x07);
missionData.artefactsFound = tagRead(0x08);
missionData.missionStarted = tagRead(0x09);
missionData.shotsOnTarget = tagRead(0x0A);
missionData.shotsOffTarget = tagRead(0x0B);
missionData.babasMowedDown = tagRead(0x0C);
// Close the file
PHYSFS_close(fileHandle);
tagClose();
/* Hopefully everything's just fine by now */
return true;
}
// -----------------------------------------------------------------------------------