Skip to content

Commit

Permalink
Refactor|SaveInfo|libcommon: Group values comprising the saved rulese…
Browse files Browse the repository at this point in the history
…t for the game session
  • Loading branch information
danij-deng committed Feb 3, 2014
1 parent d00a767 commit f477cd2
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 95 deletions.
29 changes: 19 additions & 10 deletions doomsday/plugins/common/include/saveinfo.h
@@ -1,4 +1,4 @@
/** @file saveinfo.h Save state info.
/** @file saveinfo.h Saved game session info.
*
* @authors Copyright © 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright © 2005-2013 Daniel Swanson <danij@dengine.net>
Expand All @@ -24,22 +24,28 @@
#include "doomsday.h"
#include "common.h"

typedef struct saveheader_s {
int magic;
int version;
gamemode_t gameMode;
typedef struct gamerules_s {
skillmode_t skill;
#if !__JHEXEN__
byte fast;
#endif
byte episode;
byte map;
byte deathmatch;
byte noMonsters;
#if __JHEXEN__
byte randomClasses;
#else
byte respawnMonsters;
#endif
} gamerules_t;

typedef struct saveheader_s {
int magic;
int version;
gamemode_t gameMode;
gamerules_t gameRules;
byte episode;
byte map;
#if !__JHEXEN__
int mapTime;
byte players[MAXPLAYERS];
#endif
Expand Down Expand Up @@ -72,9 +78,10 @@ class SaveInfo
bool isLoadable();

/**
* Returns the logicl version of the serialized game session state.
* Returns the logical version of the serialized game session state.
*/
int version() const;
int magic() const;

/**
* Returns the textual description of the game session (provided by the user).
Expand All @@ -88,6 +95,10 @@ class SaveInfo
uint gameId() const;
void setGameId(uint newGameId);

uint episode() const;
uint map() const;
gamerules_t const &gameRules() const;

/**
* Serializes the game session info using @a writer.
*/
Expand Down Expand Up @@ -130,8 +141,6 @@ void SaveInfo_Delete(SaveInfo *info);

SaveInfo *SaveInfo_Copy(SaveInfo *info, SaveInfo const *other);

void SaveInfo_Configure(SaveInfo *info);

dd_bool SaveInfo_IsLoadable(SaveInfo *info);

Str const *SaveInfo_Description(SaveInfo const *info);
Expand Down
44 changes: 21 additions & 23 deletions doomsday/plugins/common/src/p_saveg.cpp
Expand Up @@ -689,24 +689,23 @@ static bool recogniseNativeState(Str const *path, SaveInfo *info)
#endif

// Magic must match.
saveheader_t const *hdr = &info->_header;
if(hdr->magic != MY_SAVE_MAGIC && hdr->magic != MY_CLIENT_SAVE_MAGIC)
if(info->magic() != MY_SAVE_MAGIC && info->magic() != MY_CLIENT_SAVE_MAGIC)
{
return false;
}

/*
* Check for unsupported versions.
*/
if(hdr->version > MY_SAVE_VERSION) // Future version?
if(info->version() > MY_SAVE_VERSION) // Future version?
{
return false;
}

#if __JHEXEN__
// We are incompatible with v3 saves due to an invalid test used to determine
// present sides (ver3 format's sides contain chunks of junk data).
if(hdr->version == 3)
if(info->version() == 3)
{
return false;
}
Expand Down Expand Up @@ -3671,22 +3670,21 @@ static int SV_LoadState(Str const *path, SaveInfo *saveInfo)
*/
hdr = saveInfo->header();

gameEpisode = hdr->episode - 1;
gameMap = hdr->map - 1;
gameEpisode = saveInfo->episode();
gameMap = saveInfo->map();

// Apply the game rules:
#if __JHEXEN__
gameSkill = hdr->skill;
#else
gameSkill = hdr->skill;
fastParm = hdr->fast;
gamerules_t const &newRules = saveInfo->gameRules();
gameSkill = newRules.skill;
#if !__JHEXEN__
fastParm = newRules.fast;
#endif
deathmatch = hdr->deathmatch;
noMonstersParm = hdr->noMonsters;
deathmatch = newRules.deathmatch;
noMonstersParm = newRules.noMonsters;
#if __JHEXEN__
randomClassParm = hdr->randomClasses;
randomClassParm = newRules.randomClasses;
#else
respawnMonsters = hdr->respawnMonsters;
respawnMonsters = newRules.respawnMonsters;
#endif

#if __JHEXEN__
Expand Down Expand Up @@ -3850,11 +3848,9 @@ static int loadStateWorker(Str const *path, SaveInfo &saveInfo)
*/

// Material origin scrollers must be re-spawned for older save state versions.
saveheader_t const *hdr = saveInfo.header();

/// @todo Implement SaveInfo format type identifiers.
if((hdr->magic != (IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC)) ||
hdr->version <= 10)
if((saveInfo.magic() != (IS_NETWORK_CLIENT? MY_CLIENT_SAVE_MAGIC : MY_SAVE_MAGIC)) ||
saveInfo.version() <= 10)
{
P_SpawnAllMaterialOriginScrollers();
}
Expand Down Expand Up @@ -4013,10 +4009,12 @@ void SV_LoadGameClient(uint gameId)
return;
}

gameSkill = skillmode_t( hdr->skill );
deathmatch = hdr->deathmatch;
noMonstersParm = hdr->noMonsters;
respawnMonsters = hdr->respawnMonsters;
gamerules_t const &newRules = saveInfo->gameRules();
gameSkill = skillmode_t( newRules.skill );
deathmatch = newRules.deathmatch;
noMonstersParm = newRules.noMonsters;
respawnMonsters = newRules.respawnMonsters;

// Do we need to change the map?
if(gameMap != (unsigned) (hdr->map - 1) || gameEpisode != (unsigned) (hdr->episode - 1))
{
Expand Down
126 changes: 74 additions & 52 deletions doomsday/plugins/common/src/saveinfo.cpp
@@ -1,4 +1,4 @@
/** @file saveinfo.cpp Save state info.
/** @file saveinfo.cpp Saved game session info.
*
* @authors Copyright © 2003-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright © 2005-2013 Daniel Swanson <danij@dengine.net>
Expand Down Expand Up @@ -60,6 +60,21 @@ int SaveInfo::version() const
return _header.version;
}

int SaveInfo::magic() const
{
return _header.magic;
}

Str const *SaveInfo::description() const
{
return &_description;
}

void SaveInfo::setDescription(Str const *newName)
{
Str_CopyOrClear(&_description, newName);
}

uint SaveInfo::gameId() const
{
return _gameId;
Expand All @@ -70,14 +85,19 @@ void SaveInfo::setGameId(uint newGameId)
_gameId = newGameId;
}

Str const *SaveInfo::description() const
uint SaveInfo::episode() const
{
return &_description;
return _header.episode - 1;
}

void SaveInfo::setDescription(Str const *newName)
uint SaveInfo::map() const
{
Str_CopyOrClear(&_description, newName);
return _header.map - 1;
}

gamerules_t const &SaveInfo::gameRules() const
{
return _header.gameRules;
}

saveheader_t const *SaveInfo::header() const
Expand All @@ -99,20 +119,24 @@ void SaveInfo::configure()
#else
hdr->episode = gameEpisode+1;
#endif

#if __JHEXEN__
hdr->skill = gameSkill;
hdr->randomClasses = randomClassParm;
hdr->gameRules.skill = gameSkill;
hdr->gameRules.randomClasses = randomClassParm;
#else
hdr->skill = gameSkill;
hdr->fast = fastParm;
hdr->gameRules.skill = gameSkill;
hdr->gameRules.fast = fastParm;
#endif
hdr->deathmatch = deathmatch;
hdr->noMonsters = noMonstersParm;
hdr->gameRules.deathmatch = deathmatch;
hdr->gameRules.noMonsters = noMonstersParm;

#if __JHEXEN__
hdr->randomClasses = randomClassParm;
hdr->gameRules.randomClasses = randomClassParm;
#else
hdr->respawnMonsters = respawnMonsters;
hdr->gameRules.respawnMonsters = respawnMonsters;
#endif

#if !__JHEXEN__
hdr->mapTime = mapTime;

for(int i = 0; i < MAXPLAYERS; i++)
Expand Down Expand Up @@ -140,18 +164,21 @@ void SaveInfo::write(Writer *writer) const
Writer_WriteInt32(writer, hdr->gameMode);
Str_Write(&_description, writer);

Writer_WriteByte(writer, hdr->skill & 0x7f);
Writer_WriteByte(writer, hdr->gameRules.skill & 0x7f);
Writer_WriteByte(writer, hdr->episode);
Writer_WriteByte(writer, hdr->map);
Writer_WriteByte(writer, hdr->deathmatch);
Writer_WriteByte(writer, hdr->gameRules.deathmatch);
#if !__JHEXEN__
Writer_WriteByte(writer, hdr->fast);
Writer_WriteByte(writer, hdr->gameRules.fast);
#endif
Writer_WriteByte(writer, hdr->noMonsters);
Writer_WriteByte(writer, hdr->gameRules.noMonsters);
#if __JHEXEN__
Writer_WriteByte(writer, hdr->randomClasses);
Writer_WriteByte(writer, hdr->gameRules.randomClasses);
#else
Writer_WriteByte(writer, hdr->respawnMonsters);
Writer_WriteByte(writer, hdr->gameRules.respawnMonsters);
#endif

#if !__JHEXEN__
Writer_WriteInt32(writer, hdr->mapTime);

for(int i = 0; i < MAXPLAYERS; ++i)
Expand Down Expand Up @@ -240,41 +267,44 @@ void SaveInfo::read(Reader *reader)
// by default this means "spawn no things" and if so then the "fast" game
// rule is meaningless so it is forced off.
byte skillModePlusFastBit = Reader_ReadByte(reader);
hdr->skill = (skillmode_t) (skillModePlusFastBit & 0x7f);
if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES)
hdr->gameRules.skill = (skillmode_t) (skillModePlusFastBit & 0x7f);
if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES)
{
hdr->skill = SM_NOTHINGS;
hdr->fast = 0;
hdr->gameRules.skill = SM_NOTHINGS;
hdr->gameRules.fast = 0;
}
else
{
hdr->fast = (skillModePlusFastBit & 0x80) != 0;
hdr->gameRules.fast = (skillModePlusFastBit & 0x80) != 0;
}
}
else
#endif
{
hdr->skill = skillmode_t( Reader_ReadByte(reader) & 0x7f );
hdr->gameRules.skill = skillmode_t( Reader_ReadByte(reader) & 0x7f );

// Interpret skill levels outside the normal range as "spawn no things".
if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES)
hdr->skill = SM_NOTHINGS;
if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES)
{
hdr->gameRules.skill = SM_NOTHINGS;
}
}

hdr->episode = Reader_ReadByte(reader);
hdr->map = Reader_ReadByte(reader);
hdr->deathmatch = Reader_ReadByte(reader);

hdr->gameRules.deathmatch = Reader_ReadByte(reader);
#if !__JHEXEN__
if(hdr->version >= 13)
hdr->fast = Reader_ReadByte(reader);
hdr->gameRules.fast = Reader_ReadByte(reader);
#endif
hdr->noMonsters = Reader_ReadByte(reader);
hdr->gameRules.noMonsters = Reader_ReadByte(reader);
#if __JHEXEN__
hdr->randomClasses = Reader_ReadByte(reader);
hdr->gameRules.randomClasses = Reader_ReadByte(reader);
#endif

#if !__JHEXEN__
hdr->respawnMonsters = Reader_ReadByte(reader);
hdr->gameRules.respawnMonsters = Reader_ReadByte(reader);

// Older formats serialize the unpacked saveheader_t struct; skip the junk values (alignment).
if(hdr->version < 10) SV_Seek(2);
Expand Down Expand Up @@ -311,26 +341,24 @@ void SaveInfo::read_Hx_v9(Reader *reader)
Str_Set(&_description, nameBuffer);

Reader_Read(reader, &verText, HXS_VERSION_TEXT_LENGTH);
hdr->version = atoi(&verText[8]);
hdr->version = atoi(&verText[8]);

/*Skip junk*/ SV_Seek(4);

hdr->episode = 1;
hdr->map = Reader_ReadByte(reader);
hdr->skill = (skillmode_t) (Reader_ReadByte(reader) & 0x7f);
hdr->episode = 1;
hdr->map = Reader_ReadByte(reader);
hdr->magic = MY_SAVE_MAGIC; // Lets pretend...
hdr->gameMode = gameMode; // Assume the current mode.

// Interpret skill modes outside the normal range as "spawn no things".
if(hdr->skill < SM_BABY || hdr->skill >= NUM_SKILL_MODES)
hdr->skill = SM_NOTHINGS;
hdr->gameRules.skill = (skillmode_t) (Reader_ReadByte(reader) & 0x7f);

hdr->deathmatch = Reader_ReadByte(reader);
hdr->noMonsters = Reader_ReadByte(reader);
hdr->randomClasses = Reader_ReadByte(reader);

hdr->magic = MY_SAVE_MAGIC; // Lets pretend...
// Interpret skill modes outside the normal range as "spawn no things".
if(hdr->gameRules.skill < SM_BABY || hdr->gameRules.skill >= NUM_SKILL_MODES)
hdr->gameRules.skill = SM_NOTHINGS;

/// @note Older formats do not contain all needed values:
hdr->gameMode = gameMode; // Assume the current mode.
hdr->gameRules.deathmatch = Reader_ReadByte(reader);
hdr->gameRules.noMonsters = Reader_ReadByte(reader);
hdr->gameRules.randomClasses = Reader_ReadByte(reader);

_gameId = 0; // None.

Expand Down Expand Up @@ -393,12 +421,6 @@ void SaveInfo_SetDescription(SaveInfo *info, Str const *newName)
info->setDescription(newName);
}

void SaveInfo_Configure(SaveInfo *info)
{
DENG_ASSERT(info != 0);
info->configure();
}

dd_bool SaveInfo_IsLoadable(SaveInfo *info)
{
DENG_ASSERT(info != 0);
Expand Down

0 comments on commit f477cd2

Please sign in to comment.