248 lines
9.2 KiB
C++
248 lines
9.2 KiB
C++
/*
|
|
** Command & Conquer Generals(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// (c) 2001-2003 Electronic Arts Inc. //
|
|
// //
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// FILE: GameState.h //////////////////////////////////////////////////////////////////////////////
|
|
// Author: Colin Day, September 2002
|
|
// Desc: Game state singleton from which to load and save the game state
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#pragma once
|
|
|
|
#ifndef __GAME_STATE_H_
|
|
#define __GAME_STATE_H_
|
|
|
|
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
|
#include "Common/STLTypedefs.h"
|
|
#include "Common/Snapshot.h"
|
|
#include "Common/SubsystemInterface.h"
|
|
#include "Common/UnicodeString.h"
|
|
#include "GameNetwork/NetworkDefs.h"
|
|
|
|
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
|
class GameWindow;
|
|
class WindowLayout;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
|
typedef void (*IterateSaveFileCallback)( AsciiString filename, void *userData );
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
/** The save/load window is used for a variety of formats, using this type during the
|
|
* save/load menu initialization you can make that menu allow loading only, or allow
|
|
* both saving and loading from the same menu */
|
|
// ------------------------------------------------------------------------------------------------
|
|
enum SaveLoadLayoutType
|
|
{
|
|
SLLT_INVALID = 0,
|
|
SLLT_SAVE_AND_LOAD,
|
|
SLLT_LOAD_ONLY,
|
|
SLLT_SAVE_ONLY,
|
|
|
|
SLLT_NUM_TYPES // keep this last, why? don't know, it's not really used, but we like it this way
|
|
};
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
struct SaveDate
|
|
{
|
|
|
|
SaveDate() { year = month = day = dayOfWeek = hour = minute = second = milliseconds = 0; }
|
|
Bool isNewerThan( SaveDate *other );
|
|
|
|
UnsignedShort year;
|
|
UnsignedShort month;
|
|
UnsignedShort day;
|
|
UnsignedShort dayOfWeek;
|
|
UnsignedShort hour;
|
|
UnsignedShort minute;
|
|
UnsignedShort second;
|
|
UnsignedShort milliseconds;
|
|
|
|
};
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
enum SaveFileType
|
|
{
|
|
SAVE_FILE_TYPE_NORMAL, ///< a regular save game at any arbitrary point in the game
|
|
SAVE_FILE_TYPE_MISSION, ///< a save game in between missions (a mission save)
|
|
|
|
SAVE_FILE_TYPE_NUM_TYPES
|
|
};
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
class SaveGameInfo
|
|
{
|
|
|
|
public:
|
|
|
|
SaveGameInfo( void );
|
|
~SaveGameInfo( void );
|
|
|
|
AsciiString saveGameMapName; // map name of the "scratch pad" map extracted from save file
|
|
AsciiString pristineMapName; // pristine map in the map or user maps directory
|
|
AsciiString mapLabel; // pretty name of this level set in the editor
|
|
SaveDate date; // date of file save
|
|
AsciiString campaignSide; // which campaign side we're playing
|
|
Int missionNumber; // mission number in campaign
|
|
UnicodeString description; // user description for save game file
|
|
SaveFileType saveFileType; // type of save file we're dealing with
|
|
AsciiString missionMapName; // used for mission saves
|
|
|
|
};
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
struct AvailableGameInfo
|
|
{
|
|
|
|
AsciiString filename;
|
|
SaveGameInfo saveGameInfo;
|
|
AvailableGameInfo *next;
|
|
AvailableGameInfo *prev;
|
|
|
|
};
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
enum SaveCode
|
|
{
|
|
SC_INVALID = -1,
|
|
SC_OK,
|
|
SC_NO_FILE_AVAILABLE,
|
|
SC_FILE_NOT_FOUND,
|
|
SC_UNABLE_TO_OPEN_FILE,
|
|
SC_INVALID_XFER,
|
|
SC_UNKNOWN_BLOCK,
|
|
SC_INVALID_DATA,
|
|
SC_ERROR,
|
|
};
|
|
|
|
enum SnapshotType {
|
|
SNAPSHOT_SAVELOAD,
|
|
SNAPSHOT_DEEPCRC_LOGICONLY,
|
|
SNAPSHOT_DEEPCRC,
|
|
SNAPSHOT_MAX
|
|
};
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
// ------------------------------------------------------------------------------------------------
|
|
class GameState : public SubsystemInterface,
|
|
public Snapshot
|
|
{
|
|
|
|
public:
|
|
|
|
GameState( void );
|
|
virtual ~GameState( void );
|
|
|
|
// subsystem interface
|
|
virtual void init( void );
|
|
virtual void reset( void );
|
|
virtual void update( void ) { }
|
|
|
|
// save game methods
|
|
SaveCode saveGame( AsciiString filename,
|
|
UnicodeString desc,
|
|
SaveFileType saveType,
|
|
SnapshotType which = SNAPSHOT_SAVELOAD ); ///< save a game
|
|
SaveCode missionSave( void ); ///< do a in between mission save
|
|
SaveCode loadGame( AvailableGameInfo gameInfo ); ///< load a save file
|
|
SaveGameInfo *getSaveGameInfo( void ) { return &m_gameInfo; }
|
|
|
|
// snapshot interaction
|
|
void addPostProcessSnapshot( Snapshot *snapshot ); ///< add snapshot to post process laod
|
|
|
|
// manipulating files
|
|
Bool doesSaveGameExist( AsciiString filename ); ///< does the save file exist
|
|
void populateSaveGameListbox( GameWindow *listbox, SaveLoadLayoutType layoutType ); ///< populate listbox with available save games
|
|
void getSaveGameInfoFromFile( AsciiString filename, SaveGameInfo *saveGameInfo ); ///< get save game info from file
|
|
|
|
void friend_xferSaveDataForCRC( Xfer *xfer, SnapshotType which ); ///< This should only be called to DeepCRC sanity checking
|
|
|
|
Bool isInLoadGame(void) { return m_isInLoadGame; } // Brutal hack to allow bone pos validation while loading games
|
|
|
|
void setPristineMapName( AsciiString name ) { m_gameInfo.pristineMapName = name; }
|
|
AsciiString getPristineMapName( void ) { return m_gameInfo.pristineMapName; }
|
|
|
|
AsciiString getSaveDirectory() const;
|
|
AsciiString getFilePathInSaveDirectory(const AsciiString& leaf) const;
|
|
Bool isInSaveDirectory(const AsciiString& path) const;
|
|
|
|
AsciiString realMapPathToPortableMapPath(const AsciiString& in) const;
|
|
AsciiString portableMapPathToRealMapPath(const AsciiString& in) const;
|
|
|
|
AsciiString getMapLeafName(const AsciiString& in) const;
|
|
|
|
protected:
|
|
|
|
// snapshot methods
|
|
virtual void crc( Xfer *xfer ) { }
|
|
virtual void xfer( Xfer *xfer );
|
|
virtual void loadPostProcess( void ) { }
|
|
|
|
private:
|
|
|
|
AsciiString findNextSaveFilename( UnicodeString desc ); ///< find next acceptable filename for a new save game
|
|
void iterateSaveFiles( IterateSaveFileCallback callback, void *userData ); ///< iterate save files on disk
|
|
|
|
void xferSaveData( Xfer *xfer, SnapshotType which ); ///< save/load the file data
|
|
|
|
void gameStatePostProcessLoad( void ); ///< post process entry point after a game load
|
|
|
|
void clearAvailableGames( void ); ///< clear any available games resources we got in our list
|
|
|
|
struct SnapshotBlock
|
|
{
|
|
Snapshot *snapshot; ///< the snapshot object that handles this block
|
|
AsciiString blockName; ///< the block name
|
|
};
|
|
typedef std::list< SnapshotBlock > SnapshotBlockList;
|
|
typedef SnapshotBlockList::iterator SnapshotBlockListIterator;
|
|
void addSnapshotBlock( AsciiString blockName, Snapshot *snapshot, SnapshotType which );
|
|
SnapshotBlock *findBlockInfoByToken( AsciiString token, SnapshotType which );
|
|
|
|
SnapshotBlockList m_snapshotBlockList[SNAPSHOT_MAX]; ///< list of snapshot blocks of save file data
|
|
SaveGameInfo m_gameInfo; ///< save game info struct
|
|
|
|
typedef std::list< Snapshot * > SnapshotList;
|
|
typedef SnapshotList::iterator SnapshotListIterator;
|
|
typedef SnapshotList::reverse_iterator SnapshotListReverseIterator;
|
|
SnapshotList m_snapshotPostProcessList;
|
|
|
|
AvailableGameInfo *m_availableGames; ///< list of available games we can save over or load from
|
|
|
|
Bool m_isInLoadGame; // Brutal hack to allow bone pos validation while loading games
|
|
};
|
|
|
|
// EXTERNALS //////////////////////////////////////////////////////////////////////////////////////
|
|
extern GameState *TheGameState;
|
|
|
|
|
|
UnicodeString getUnicodeTimeBuffer(SYSTEMTIME timeVal);
|
|
UnicodeString getUnicodeDateBuffer(SYSTEMTIME timeVal);
|
|
|
|
|
|
#endif // end __GAME_STATE_H_
|