/* ** 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_