Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.

This commit is contained in:
LFeenanEA 2025-02-27 17:34:39 +00:00
parent 2e338c00cb
commit 3d0ee53a05
No known key found for this signature in database
GPG key ID: C6EBE8C2EA08F7E0
6072 changed files with 2283311 additions and 0 deletions

View file

@ -0,0 +1,163 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/definition.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/24/01 4:35p $*
* *
* $Revision:: 10 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "definition.h"
#include "chunkio.h"
//////////////////////////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////////////////////////
enum
{
CHUNKID_VARIABLES = 0x00000100,
};
enum
{
VARID_INSTANCEID = 0x01,
XXX_VARID_PARENTID,
VARID_NAME,
};
/////////////////////////////////////////////////////////
//
// Save
//
/////////////////////////////////////////////////////////
bool
DefinitionClass::Save (ChunkSaveClass &csave)
{
bool retval = true;
csave.Begin_Chunk (CHUNKID_VARIABLES);
retval &= Save_Variables (csave);
csave.End_Chunk ();
return retval;
}
/////////////////////////////////////////////////////////
//
// Load
//
/////////////////////////////////////////////////////////
bool
DefinitionClass::Load (ChunkLoadClass &cload)
{
bool retval = true;
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
case CHUNKID_VARIABLES:
Load_Variables (cload);
break;
}
cload.Close_Chunk ();
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Save_Variables
//
//////////////////////////////////////////////////////////////////////////////////
bool
DefinitionClass::Save_Variables (ChunkSaveClass &csave)
{
bool retval = true;
WRITE_MICRO_CHUNK (csave, VARID_INSTANCEID, m_ID);
WRITE_MICRO_CHUNK_WWSTRING (csave, VARID_NAME, m_Name);
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Load_Variables
//
//////////////////////////////////////////////////////////////////////////////////
bool
DefinitionClass::Load_Variables (ChunkLoadClass &cload)
{
bool retval = true;
//
// Loop through all the microchunks that define the variables
//
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ()) {
READ_MICRO_CHUNK (cload, VARID_INSTANCEID, m_ID)
READ_MICRO_CHUNK_WWSTRING (cload, VARID_NAME, m_Name)
}
cload.Close_Micro_Chunk ();
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Set_ID
//
//////////////////////////////////////////////////////////////////////////////////
void
DefinitionClass::Set_ID (uint32 id)
{
m_ID = id;
//
// If we are registered with the definition manager, then we need to
// re-link ourselves back into the list
//
if (m_DefinitionMgrLink != -1) {
DefinitionMgrClass::Unregister_Definition (this);
DefinitionMgrClass::Register_Definition (this);
}
return ;
}

View file

@ -0,0 +1,194 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/definition.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/24/01 4:57p $*
* *
* $Revision:: 20 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DEFINITION_H
#define __DEFINITION_H
#include "always.h"
// SKB Remove because of G conflicts with CLASSID_??
// #include "definitionclassids.h"
#include "definitionmgr.h"
#include "editable.h"
#include "wwstring.h"
// Forward declarations
class ChunkSaveClass;
class ChunkLoadClass;
//////////////////////////////////////////////////////////////////////////////////
//
// DefinitionClass
//
//////////////////////////////////////////////////////////////////////////////////
class DefinitionClass : public EditableClass
{
public:
/////////////////////////////////////////////////////////////////////
// Editable interface requirements
/////////////////////////////////////////////////////////////////////
DECLARE_EDITABLE(DefinitionClass, EditableClass);
/////////////////////////////////////////////////////////////////////
// Public constructors/destructors
/////////////////////////////////////////////////////////////////////
DefinitionClass (void);
virtual ~DefinitionClass (void);
/////////////////////////////////////////////////////////////////////
// Public methods
/////////////////////////////////////////////////////////////////////
// Type identification
virtual uint32 Get_Class_ID (void) const = 0;
virtual uint32 Get_ID (void) const;
virtual void Set_ID (uint32 id);
virtual PersistClass * Create (void) const = 0;
// Display name methods
virtual const char * Get_Name (void) const;
virtual void Set_Name (const char *new_name);
// Validation methods
virtual bool Is_Valid_Config (StringClass &message);
// From PersistClass
virtual bool Save (ChunkSaveClass &csave);
virtual bool Load (ChunkLoadClass &cload);
// User data support
uint32 Get_User_Data (void) const { return m_GenericUserData; }
void Set_User_Data (uint32 data) { m_GenericUserData = data; }
// Save support
bool Is_Save_Enabled (void) const { return m_SaveEnabled; }
void Enable_Save (bool onoff) { m_SaveEnabled = onoff; }
protected:
/////////////////////////////////////////////////////////////////////
// Protected member data
/////////////////////////////////////////////////////////////////////
int m_DefinitionMgrLink;
private:
/////////////////////////////////////////////////////////////////////
// Private methods
/////////////////////////////////////////////////////////////////////
bool Save_Variables (ChunkSaveClass &csave);
bool Load_Variables (ChunkLoadClass &cload);
/////////////////////////////////////////////////////////////////////
// Private member data
/////////////////////////////////////////////////////////////////////
StringClass m_Name;
uint32 m_ID;
uint32 m_GenericUserData;
bool m_SaveEnabled;
/////////////////////////////////////////////////////////////////////
// Friends
/////////////////////////////////////////////////////////////////////
friend class DefinitionMgrClass;
};
/////////////////////////////////////////////////////////////////////
// DefinitionClass
/////////////////////////////////////////////////////////////////////
inline
DefinitionClass::DefinitionClass (void)
: m_ID (0),
m_SaveEnabled (true),
m_DefinitionMgrLink (-1)
{
return ;
}
/////////////////////////////////////////////////////////////////////
// DefinitionClass
/////////////////////////////////////////////////////////////////////
inline
DefinitionClass::~DefinitionClass (void)
{
return ;
}
//////////////////////////////////////////////////////////////////////////////////
// Get_Name
//////////////////////////////////////////////////////////////////////////////////
inline const char *
DefinitionClass::Get_Name (void) const
{
return m_Name;
}
//////////////////////////////////////////////////////////////////////////////////
// Set_Name
//////////////////////////////////////////////////////////////////////////////////
inline void
DefinitionClass::Set_Name (const char *new_name)
{
m_Name = new_name;
return ;
}
//////////////////////////////////////////////////////////////////////////////////
// Get_ID
//////////////////////////////////////////////////////////////////////////////////
inline uint32
DefinitionClass::Get_ID (void) const
{
return m_ID;
}
//////////////////////////////////////////////////////////////////////////////////
// Is_Valid_Config
//////////////////////////////////////////////////////////////////////////////////
inline bool
DefinitionClass::Is_Valid_Config (StringClass &message)
{
return true;
}
#endif //__DEFINITION_H

View file

@ -0,0 +1,108 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/definitionclassids.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/03/00 5:44p $*
* *
* $Revision:: 15 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DEFINITION_CLASS_ID_H
#define __DEFINITION_CLASS_ID_H
#include "always.h"
#include "bittype.h"
//////////////////////////////////////////////////////////////////////////////////
//
// Constants
//
//////////////////////////////////////////////////////////////////////////////////
const int DEF_CLASSID_START = 0x00001000;
const int DEF_CLASSID_RANGE = 0x00001000;
#define NEXT_SUPER_CLASSID(n) DEF_CLASSID_START + (n * DEF_CLASSID_RANGE)
//////////////////////////////////////////////////////////////////////////////////
//
// DefinitionClassID
//
// Note: The following enum should contain ALL of the class ids for
// definitions in the entire system (to guarantee they are unique). Each
// super-class is allocated a range of class ids. Use the
// SuperClassID_From_ClassID function to determine which super class
// a particular class id belongs to.
//
//////////////////////////////////////////////////////////////////////////////////
enum
{
CLASSID_TERRAIN = NEXT_SUPER_CLASSID(0),
CLASSID_TILE = NEXT_SUPER_CLASSID(1),
CLASSID_GAME_OBJECTS = NEXT_SUPER_CLASSID(2),
CLASSID_LIGHT = NEXT_SUPER_CLASSID(3),
CLASSID_SOUND = NEXT_SUPER_CLASSID(4),
CLASSID_WAYPATH = NEXT_SUPER_CLASSID(5),
CLASSID_ZONE = NEXT_SUPER_CLASSID(6),
CLASSID_TRANSITION = NEXT_SUPER_CLASSID(7),
CLASSID_PHYSICS = NEXT_SUPER_CLASSID(8),
CLASSID_EDITOR_OBJECTS = NEXT_SUPER_CLASSID(9),
CLASSID_MUNITIONS = NEXT_SUPER_CLASSID(10),
CLASSID_DUMMY_OBJECTS = NEXT_SUPER_CLASSID(11),
CLASSID_BUILDINGS = NEXT_SUPER_CLASSID(12),
CLASSID_TWIDDLERS = NEXT_SUPER_CLASSID(13),
CLASSID_GLOBAL_SETTINGS = NEXT_SUPER_CLASSID(14),
};
//////////////////////////////////////////////////////////////////////////////////
//
// SuperClassID_From_ClassID
//
//////////////////////////////////////////////////////////////////////////////////
inline uint32
SuperClassID_From_ClassID (uint32 class_id)
{
//
// Which id-range does it fall under?
//
int delta = class_id - DEF_CLASSID_START;
int num_ranges = delta / DEF_CLASSID_RANGE;
return DEF_CLASSID_START + (num_ranges * DEF_CLASSID_RANGE);
}
#endif //__DEFINITION_CLASS_ID_H

View file

@ -0,0 +1,64 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/definitionfactory.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 9/09/99 7:12p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "definitionfactory.h"
#include "definitionfactorymgr.h"
/////////////////////////////////////////////////////////
//
// DefinitionFactoryClass
//
/////////////////////////////////////////////////////////
DefinitionFactoryClass::DefinitionFactoryClass (void)
: m_NextFactory (0),
m_PrevFactory (0)
{
DefinitionFactoryMgrClass::Register_Factory (this);
return ;
}
/////////////////////////////////////////////////////////
//
// ~DefinitionFactoryClass
//
/////////////////////////////////////////////////////////
DefinitionFactoryClass::~DefinitionFactoryClass (void)
{
DefinitionFactoryMgrClass::Unregister_Factory (this);
return ;
}

View file

@ -0,0 +1,93 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/definitionfactory.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 2/22/01 6:18p $*
* *
* $Revision:: 9 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DEFINITION_FACTORY_H
#define __DEFINITION_FACTORY_H
#include "always.h"
#include "bittype.h"
#include "definitionclassids.h"
// Forward declarations
class DefinitionClass;
//////////////////////////////////////////////////////////////////////////////////
//
// DefinitionFactoryClass
//
// Definition factories act as virtual constructors for object definitions. They
// are responsible for creating new definitions for a particular class of objects.
//
//////////////////////////////////////////////////////////////////////////////////
class DefinitionFactoryClass
{
public:
//////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////
DefinitionFactoryClass (void);
virtual ~DefinitionFactoryClass (void);
//////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////
virtual DefinitionClass * Create (void) const = 0;
virtual const char * Get_Name (void) const = 0;
virtual uint32 Get_Class_ID (void) const = 0;
virtual bool Is_Displayed (void) const = 0;
protected:
//////////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////////
DefinitionFactoryClass * m_NextFactory;
DefinitionFactoryClass * m_PrevFactory;
//////////////////////////////////////////////////////////////
// Friends
//////////////////////////////////////////////////////////////
friend class DefinitionFactoryMgrClass;
};
#endif //__DEFINITION_FACTORY_H

View file

@ -0,0 +1,295 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /VSS_Sync/wwsaveload/definitionfactorymgr.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/16/00 11:42a $*
* *
* $Revision:: 12 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "definitionfactorymgr.h"
#include "definitionfactory.h"
#include "wwdebug.h"
#include <string.h>
#ifdef _UNIX
#include "osdep.h"
#endif
////////////////////////////////////////////////////////////////////////////
// Static member initialization
////////////////////////////////////////////////////////////////////////////
DefinitionFactoryClass *DefinitionFactoryMgrClass::_FactoryListHead = 0;
////////////////////////////////////////////////////////////////////////////
//
// Find_Factory
//
////////////////////////////////////////////////////////////////////////////
DefinitionFactoryClass *
DefinitionFactoryMgrClass::Find_Factory (uint32 class_id)
{
DefinitionFactoryClass *factory = 0;
//
// Loop through all the factories and see if we can
// find the one who owns the corresponding class-id.
//
for ( DefinitionFactoryClass *curr_factory = _FactoryListHead;
(factory == 0) && (curr_factory != 0);
curr_factory = curr_factory->m_NextFactory) {
//
// Is this the factory we were looking for?
//
if (curr_factory->Get_Class_ID () == class_id) {
factory = curr_factory;
}
}
return factory;
}
////////////////////////////////////////////////////////////////////////////
//
// Find_Factory
//
////////////////////////////////////////////////////////////////////////////
DefinitionFactoryClass *
DefinitionFactoryMgrClass::Find_Factory (const char *name)
{
DefinitionFactoryClass *factory = 0;
//
// Loop through all the factories and see if we can
// find the one who owns the corresponding class-id.
//
for ( DefinitionFactoryClass *curr_factory = _FactoryListHead;
(factory == 0) && (curr_factory != 0);
curr_factory = curr_factory->m_NextFactory) {
//
// Is this the factory we were looking for?
//
if (::stricmp (curr_factory->Get_Name (), name) == 0) {
factory = curr_factory;
}
}
return factory;
}
////////////////////////////////////////////////////////////////////////////
//
// Get_First
//
////////////////////////////////////////////////////////////////////////////
DefinitionFactoryClass *
DefinitionFactoryMgrClass::Get_First (uint32 superclass_id)
{
DefinitionFactoryClass *factory = 0;
//
// Loop through all the factories and see if we can
// find the next one that belongs to the given superclass
//
for ( DefinitionFactoryClass *curr_factory = _FactoryListHead;
(factory == 0) && (curr_factory != 0);
curr_factory = curr_factory->m_NextFactory) {
//
// Is this the factory we were looking for?
//
if (::SuperClassID_From_ClassID (curr_factory->Get_Class_ID ()) == superclass_id) {
factory = curr_factory;
}
}
return factory;
}
////////////////////////////////////////////////////////////////////////////
//
// Get_Next
//
////////////////////////////////////////////////////////////////////////////
DefinitionFactoryClass *
DefinitionFactoryMgrClass::Get_Next
(
DefinitionFactoryClass *curr_factory,
uint32 superclass_id
)
{
DefinitionFactoryClass *factory = 0;
//
// Loop through all the factories and see if we can
// find the next one that belongs to the given superclass
//
while ((factory == NULL) && ((curr_factory = curr_factory->m_NextFactory) != NULL)) {
//
// Is this the factory we were looking for?
//
if (::SuperClassID_From_ClassID (curr_factory->Get_Class_ID ()) == superclass_id) {
factory = curr_factory;
}
}
return factory;
}
////////////////////////////////////////////////////////////////////////////
//
// Get_First
//
////////////////////////////////////////////////////////////////////////////
DefinitionFactoryClass *
DefinitionFactoryMgrClass::Get_First (void)
{
return _FactoryListHead;
}
////////////////////////////////////////////////////////////////////////////
//
// Get_Next
//
////////////////////////////////////////////////////////////////////////////
DefinitionFactoryClass *
DefinitionFactoryMgrClass::Get_Next (DefinitionFactoryClass *curr_factory)
{
DefinitionFactoryClass *factory = 0;
//
// Simply return the next factory in the chain
//
if (curr_factory != NULL) {
factory = curr_factory->m_NextFactory;
}
return factory;
}
////////////////////////////////////////////////////////////////////////////
//
// Register_Factory
//
////////////////////////////////////////////////////////////////////////////
void
DefinitionFactoryMgrClass::Register_Factory (DefinitionFactoryClass *factory)
{
WWASSERT (factory->m_NextFactory == 0);
WWASSERT (factory->m_PrevFactory == 0);
Link_Factory (factory);
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// Unregister_Factory
//
////////////////////////////////////////////////////////////////////////////
void
DefinitionFactoryMgrClass::Unregister_Factory (DefinitionFactoryClass *factory)
{
WWASSERT (factory != 0);
Unlink_Factory (factory);
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// Link_Factory
//
////////////////////////////////////////////////////////////////////////////
void
DefinitionFactoryMgrClass::Link_Factory (DefinitionFactoryClass *factory)
{
WWASSERT (factory->m_NextFactory == 0);
WWASSERT (factory->m_PrevFactory == 0);
// Adding this factory in front of the current head of the list
factory->m_NextFactory = _FactoryListHead;
// If the list wasn't empty, link the next factory back to this factory
if (factory->m_NextFactory != 0) {
factory->m_NextFactory->m_PrevFactory = factory;
}
// Point the head of the list at this factory now
_FactoryListHead = factory;
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// Unlink_Factory
//
////////////////////////////////////////////////////////////////////////////
void
DefinitionFactoryMgrClass::Unlink_Factory (DefinitionFactoryClass *factory)
{
WWASSERT(factory != 0);
// Handle the factory's prev pointer:
if (factory->m_PrevFactory == 0) {
// this factory is the head
WWASSERT (_FactoryListHead == factory);
_FactoryListHead = factory->m_NextFactory;
} else {
// link it's prev with it's next
factory->m_PrevFactory->m_NextFactory = factory->m_NextFactory;
}
// Handle the factory's next pointer if its not at the end of the list:
if (factory->m_NextFactory != 0) {
factory->m_NextFactory->m_PrevFactory = factory->m_PrevFactory;
}
// factory is now un-linked
factory->m_NextFactory = 0;
factory->m_PrevFactory = 0;
return ;
}

View file

@ -0,0 +1,90 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/definitionfactorymgr.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 7/07/00 11:55a $*
* *
* $Revision:: 11 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DEFINITION_FACTORY_MGR_H
#define __DEFINITION_FACTORY_MGR_H
#include "always.h"
#include "bittype.h"
#include "definitionclassids.h"
class DefinitionFactoryClass;
//////////////////////////////////////////////////////////////////////////////////
//
// DefinitionFactoryMgrClass
//
//////////////////////////////////////////////////////////////////////////////////
class DefinitionFactoryMgrClass
{
public:
/////////////////////////////////////////////////////////////////////
// Public methods
/////////////////////////////////////////////////////////////////////
static DefinitionFactoryClass * Find_Factory (uint32 class_id);
static DefinitionFactoryClass * Find_Factory (const char *name);
static void Register_Factory (DefinitionFactoryClass *factory);
static void Unregister_Factory (DefinitionFactoryClass *factory);
// Class enumeration
static DefinitionFactoryClass * Get_First (uint32 superclass_id);
static DefinitionFactoryClass * Get_Next (DefinitionFactoryClass *current, uint32 superclass_id);
// Factory enumeration
static DefinitionFactoryClass * Get_First (void);
static DefinitionFactoryClass * Get_Next (DefinitionFactoryClass *current);
private:
/////////////////////////////////////////////////////////////////////
// Private methods
/////////////////////////////////////////////////////////////////////
static void Link_Factory (DefinitionFactoryClass *factory);
static void Unlink_Factory (DefinitionFactoryClass *factory);
/////////////////////////////////////////////////////////////////////
// Static member data
/////////////////////////////////////////////////////////////////////
static DefinitionFactoryClass * _FactoryListHead;
};
#endif //__DEFINITION_FACTORY_MGR_H

View file

@ -0,0 +1,933 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/definitionmgr.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/28/01 7:33p $*
* *
* $Revision:: 33 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "definitionmgr.h"
#include "definition.h"
#include "definitionfactory.h"
#include "definitionfactorymgr.h"
#include "definitionclassids.h"
#include "chunkio.h"
#include "persistfactory.h"
#include "wwdebug.h"
#include "wwmemlog.h"
#include "twiddler.h"
#include <string.h>
#include "wwprofile.h"
//////////////////////////////////////////////////////////////////////////////////
// Global instance
//////////////////////////////////////////////////////////////////////////////////
DefinitionMgrClass _TheDefinitionMgr;
//////////////////////////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////////////////////////
static const int DEFINTION_LIST_GROW_SIZE = 1000;
static const uint32 IDRANGE_PER_CLASS = 10000;
enum
{
CHUNKID_VARIABLES = 0x00000100,
CHUNKID_OBJECTS,
CHUNKID_OBJECT
};
enum
{
VARID_NEXTDEFID = 0x01
};
//////////////////////////////////////////////////////////////////////////////////
// Static member initialization
//////////////////////////////////////////////////////////////////////////////////
DefinitionClass ** DefinitionMgrClass::_SortedDefinitionArray = NULL;
int DefinitionMgrClass::_DefinitionCount = 0;
int DefinitionMgrClass::_MaxDefinitionCount = 0;
HashTemplateClass<StringClass, DynamicVectorClass<DefinitionClass*>*>* DefinitionMgrClass::DefinitionHash;
//////////////////////////////////////////////////////////////////////////////////
//
// DefinitionMgrClass
//
//////////////////////////////////////////////////////////////////////////////////
DefinitionMgrClass::DefinitionMgrClass (void)
{
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// ~DefinitionMgrClass
//
//////////////////////////////////////////////////////////////////////////////////
DefinitionMgrClass::~DefinitionMgrClass (void)
{
Free_Definitions ();
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Find_Definition
//
//////////////////////////////////////////////////////////////////////////////////
DefinitionClass *
DefinitionMgrClass::Find_Definition (uint32 id, bool twiddle)
{
DefinitionClass *definition = NULL;
int lower_index = 0;
int upper_index = _DefinitionCount - 1;
int index = upper_index / 2;
bool keep_going = (_DefinitionCount > 0);
//
// Binary search the list until we've found the definition
//
while (keep_going) {
DefinitionClass *curr_def = _SortedDefinitionArray[index];
WWASSERT (curr_def != NULL);
//
// Is this the definition we are looking for?
//
if (curr_def->Get_ID () == id) {
definition = _SortedDefinitionArray[index];
keep_going = false;
} else if (upper_index <= lower_index + 1) {
//
// When the window get's too small, our divide by two won't catch
// both entries, so just go ahead and do them both now.
//
keep_going = false;
if (_SortedDefinitionArray[lower_index]->Get_ID () == id) {
definition = _SortedDefinitionArray[lower_index];
} else if (_SortedDefinitionArray[upper_index]->Get_ID () == id) {
definition = _SortedDefinitionArray[upper_index];
}
} else {
//
// Cut our 'window' in half
//
if (id > curr_def->Get_ID ()) {
lower_index = index;
index += (upper_index - index) / 2;
} else {
upper_index = index;
index -= (index - lower_index) / 2;
}
}
}
//
// Should we twiddle this definition? (Twiddling refers to our randomizing
// framework for definitions)
//
if ( twiddle &&
definition != NULL &&
definition->Get_Class_ID () == CLASSID_TWIDDLERS)
{
definition = ((TwiddlerClass *)definition)->Twiddle ();
}
return definition;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Find_Named_Definition
//
//////////////////////////////////////////////////////////////////////////////////
DefinitionClass *
DefinitionMgrClass::Find_Named_Definition (const char *name, bool twiddle)
{
DefinitionClass *definition = NULL;
//
// Loop through all the definitions and see if we can
// find the one with the requested name
//
for (int index = 0; index < _DefinitionCount; index ++) {
DefinitionClass *curr_def = _SortedDefinitionArray[index];
//
// Is this the definition we were looking for?
//
if (curr_def != NULL && ::stricmp (curr_def->Get_Name (), name) == 0) {
definition = curr_def;
break;
}
}
//
// Should we twiddle this definition? (Twiddling refers to our randomizing
// framework for definitions)
//
if ( twiddle &&
definition != NULL &&
definition->Get_Class_ID () == CLASSID_TWIDDLERS)
{
definition = ((TwiddlerClass *)definition)->Twiddle ();
}
return definition;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Find_Typed_Definition
//
//////////////////////////////////////////////////////////////////////////////////
DefinitionClass *
DefinitionMgrClass::Find_Typed_Definition (const char *name, uint32 class_id, bool twiddle)
{
//
// Sanity check
//
if (DefinitionHash == NULL) {
WWDEBUG_SAY (("DefinitionMgrClass::Find_Typed_Definition () failed due to a NULL DefinitionHash.\n"));
return NULL;
}
DefinitionClass *definition = NULL;
// Check the hash table first. The hash table is built as we need the definitions, so if definition is not
// in the table, it will be added there.
//
// TSS null deref on this sucker 08/03/01
//
WWASSERT(DefinitionHash != NULL);
StringClass name_string(name,true);
DynamicVectorClass<DefinitionClass*>* defs = DefinitionHash->Get(name_string);
if (defs) {
for (int i=0;i<defs->Length();++i) {
DefinitionClass* curr_def=(*defs)[i];
WWASSERT(curr_def);
uint32 curr_class_id = curr_def->Get_Class_ID ();
if ( (curr_class_id == class_id) ||
(::SuperClassID_From_ClassID (curr_class_id) == class_id) ||
(twiddle && (curr_def->Get_Class_ID () == CLASSID_TWIDDLERS)))
{
definition = curr_def;
break;
}
}
}
//
// Loop through all the definitions and see if we can
// find the one with the requested name
//
if (!definition) {
for (int index = 0; index < _DefinitionCount; index ++) {
DefinitionClass *curr_def = _SortedDefinitionArray[index];
if (curr_def != NULL) {
//
// Is this the correct class of definition?
//
uint32 curr_class_id = curr_def->Get_Class_ID ();
if ( (curr_class_id == class_id) ||
(::SuperClassID_From_ClassID (curr_class_id) == class_id) ||
(twiddle && (curr_def->Get_Class_ID () == CLASSID_TWIDDLERS)))
{
//
// Is this the definition we were looking for?
//
if (::stricmp (curr_def->Get_Name (), name) == 0) {
definition = curr_def;
// Add the definition to the hash table, so that it can be quickly accessed the next time it is needed.
if (!defs) {
defs=W3DNEW DynamicVectorClass<DefinitionClass*>;
DefinitionHash->Insert(name_string,defs);
}
defs->Add(definition);
break;
}
}
}
}
}
//
// Should we twiddle this definition? (Twiddling refers to our randomizing
// framework for definitions)
//
if ( twiddle &&
definition != NULL &&
definition->Get_Class_ID () == CLASSID_TWIDDLERS)
{
definition = ((TwiddlerClass *)definition)->Twiddle ();
}
return definition;
}
//////////////////////////////////////////////////////////////////////////////////
//
// List_Available_Definitions
//
//////////////////////////////////////////////////////////////////////////////////
void
DefinitionMgrClass::List_Available_Definitions (void)
{
//
// Loop through all the definitions and print the definition name
//
WWDEBUG_SAY(("Available definitions:\n"));
for (int index = 0; index < _DefinitionCount; index ++) {
DefinitionClass *curr_def = _SortedDefinitionArray[index];
if (curr_def != NULL) {
WWDEBUG_SAY((" >%s<\n", curr_def->Get_Name ()));
}
}
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// List_Available_Definitions
//
//////////////////////////////////////////////////////////////////////////////////
void
DefinitionMgrClass::List_Available_Definitions (int superclass_id)
{
//
// Loop through all the definitions and print the definition name
//
WWDEBUG_SAY(("Available superclass definitions for 0x%8X:\n", superclass_id));
DefinitionClass *definition = NULL;
for ( definition = Get_First (superclass_id, DefinitionMgrClass::ID_SUPERCLASS);
definition != NULL;
definition = Get_Next (definition, superclass_id, DefinitionMgrClass::ID_SUPERCLASS))
{
WWDEBUG_SAY((" >%s<\n", definition->Get_Name ()));
}
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Get_First
//
//////////////////////////////////////////////////////////////////////////////////
DefinitionClass *
DefinitionMgrClass::Get_First (uint32 id, ID_TYPE type)
{
DefinitionClass *definition = NULL;
//
// Loop through all the definitions and find the first
// one that belongs to the requested class
//
for ( int index = 0;
(definition == NULL) && (index < _DefinitionCount);
index ++)
{
DefinitionClass *curr_def = _SortedDefinitionArray[index];
if (curr_def != NULL) {
//
// Is this the definition we were looking for?
//
if ( (type == ID_SUPERCLASS) &&
(::SuperClassID_From_ClassID (curr_def->Get_Class_ID ()) == id)) {
definition = curr_def;
} else if ( (type == ID_CLASS) &&
(curr_def->Get_Class_ID () == id)) {
definition = curr_def;
}
}
}
return definition;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Get_Next
//
//////////////////////////////////////////////////////////////////////////////////
DefinitionClass *
DefinitionMgrClass::Get_Next
(
DefinitionClass * curr_def,
uint32 id,
ID_TYPE type
)
{
DefinitionClass *definition = NULL;
//
// Loop through all the definitions and find the first
// one that belongs to the requested class
//
for ( int index = curr_def->m_DefinitionMgrLink + 1;
(definition == NULL) && (index < _DefinitionCount);
index ++)
{
DefinitionClass *curr_def = _SortedDefinitionArray[index];
if (curr_def != NULL) {
//
// Is this the definition we were looking for?
//
if ( (type == ID_SUPERCLASS) &&
(::SuperClassID_From_ClassID (curr_def->Get_Class_ID ()) == id)) {
definition = curr_def;
} else if ( (type == ID_CLASS) &&
(curr_def->Get_Class_ID () == id)) {
definition = curr_def;
}
}
}
return definition;
}
////////////////////////////////////////////////////////////////////////////
//
// Get_Next
//
////////////////////////////////////////////////////////////////////////////
DefinitionClass *
DefinitionMgrClass::Get_Next (DefinitionClass *curr_def)
{
WWASSERT (curr_def != NULL);
DefinitionClass *definition = NULL;
int index = curr_def->m_DefinitionMgrLink + 1;
if (index < _DefinitionCount) {
definition = _SortedDefinitionArray[index];
}
return definition;
}
////////////////////////////////////////////////////////////////////////////
//
// Free_Definitions
//
////////////////////////////////////////////////////////////////////////////
void
DefinitionMgrClass::Free_Definitions (void)
{
// Clear the hash table
if (DefinitionHash) {
HashTemplateIterator<StringClass,DynamicVectorClass<DefinitionClass*>*> ite(*DefinitionHash);
for (ite.First();!ite.Is_Done();ite.Next()) {
DynamicVectorClass<DefinitionClass*>* defs=ite.Peek_Value();
// delete ite.Peek_Value();
delete defs;
}
DefinitionHash->Remove_All();
delete DefinitionHash;
DefinitionHash=NULL;
}
//
// Free each of the definition objects
//
for (int index = 0; index < _DefinitionCount; index ++) {
DefinitionClass *definition = _SortedDefinitionArray[index];
if (definition != NULL) {
delete definition;
}
}
//
// Free the definition array
//
if (_SortedDefinitionArray != NULL) {
delete [] _SortedDefinitionArray;
}
_SortedDefinitionArray = NULL;
_MaxDefinitionCount = 0;
_DefinitionCount = 0;
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// Prepare_Definition_Array
//
////////////////////////////////////////////////////////////////////////////
void
DefinitionMgrClass::Prepare_Definition_Array (void)
{
if (_DefinitionCount + 1 > _MaxDefinitionCount) {
//
// Allocate a new, bigger array
//
int new_size = _MaxDefinitionCount + DEFINTION_LIST_GROW_SIZE;
DefinitionClass **new_array = W3DNEWARRAY DefinitionClass *[new_size];
//
// Copy the entries from the old array to the new array
//
::memcpy (new_array, _SortedDefinitionArray, _DefinitionCount * sizeof (DefinitionClass *));
//
// Free the old array and start using the new array
//
if (_SortedDefinitionArray != NULL) {
delete [] _SortedDefinitionArray;
}
_SortedDefinitionArray = new_array;
_MaxDefinitionCount = new_size;
}
if (!DefinitionHash) DefinitionHash=W3DNEW HashTemplateClass<StringClass, DynamicVectorClass<DefinitionClass*>*>;
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// Register_Definition
//
////////////////////////////////////////////////////////////////////////////
void
DefinitionMgrClass::Register_Definition (DefinitionClass *definition)
{
WWASSERT (definition != NULL);
if (definition != NULL && definition->m_DefinitionMgrLink == -1 && definition->Get_ID () != 0) {
//
// Make sure the definition array is large enough
//
Prepare_Definition_Array ();
//
// Calculate where in the list we should insert this definition
//
uint32 id = definition->Get_ID ();
int lower_index = 0;
int upper_index = _DefinitionCount - 1;
int index = upper_index / 2;
int insert_index = _DefinitionCount;
bool keep_going = (_DefinitionCount > 0);
bool is_valid = true;
while (keep_going) {
DefinitionClass *curr_def = _SortedDefinitionArray[index];
WWASSERT (curr_def != NULL);
//
// Check to make sure we aren't trying to register a definition
// that has the same ID as a definition that is already in the list.
//
if (curr_def->Get_ID () == id) {
insert_index = index;
keep_going = false;
is_valid = false;
} else {
//
// Cut our 'window' in half
//
if (id > curr_def->Get_ID ()) {
lower_index = index;
index += (upper_index - index) / 2;
} else {
upper_index = index;
index -= (index - lower_index) / 2;
}
//
// If we've narrowed down the window to 2 entries, then quick check
// the different possibilities.
//
if (upper_index <= lower_index + 1) {
if (_SortedDefinitionArray[upper_index]->Get_ID () <= id) {
insert_index = upper_index + 1;
} else if (_SortedDefinitionArray[lower_index]->Get_ID () <= id) {
insert_index = upper_index;
} else {
insert_index = lower_index;
}
keep_going = false;
}
}
}
//WWASSERT (is_valid);
if (is_valid) {
//
// Re-index all the definitions that got bumped one cell due to this insertion.
//
for (index = _DefinitionCount - 1; index >= insert_index; index --) {
_SortedDefinitionArray[index + 1] = _SortedDefinitionArray[index];
_SortedDefinitionArray[index + 1]->m_DefinitionMgrLink = index + 1;
}
//
// Insert this definition into the list
//
definition->m_DefinitionMgrLink = insert_index;
_SortedDefinitionArray[insert_index] = definition;
_DefinitionCount ++;
}
}
return ;
}
////////////////////////////////////////////////////////////////////////////
//
// Unregister_Definition
//
////////////////////////////////////////////////////////////////////////////
void
DefinitionMgrClass::Unregister_Definition (DefinitionClass *definition)
{
WWASSERT (definition != 0);
//WWASSERT (definition->m_DefinitionMgrLink >= 0 && definition->m_DefinitionMgrLink < _DefinitionCount);
if (definition != NULL && definition->m_DefinitionMgrLink != -1) {
//
// Re-index the definitions that come after this definition in the list
//
for (int index = definition->m_DefinitionMgrLink; index < _DefinitionCount - 1; index ++) {
_SortedDefinitionArray[index] = _SortedDefinitionArray[index + 1];
_SortedDefinitionArray[index]->m_DefinitionMgrLink = index;
}
_SortedDefinitionArray[_DefinitionCount - 1] = NULL;
definition->m_DefinitionMgrLink = -1;
_DefinitionCount --;
}
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Save
//
//////////////////////////////////////////////////////////////////////////////////
bool
DefinitionMgrClass::Save
(
ChunkSaveClass & csave
)
{
WWMEMLOG(MEM_GAMEDATA);
bool retval = true;
//
// Create a chunk to contain the class variables we need to serialize.
//
csave.Begin_Chunk (CHUNKID_VARIABLES);
Save_Variables (csave);
csave.End_Chunk ();
//
// Have the base class write the objects to their own chunk.
//
csave.Begin_Chunk (CHUNKID_OBJECTS);
retval &= Save_Objects (csave);
csave.End_Chunk ();
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Load
//
//////////////////////////////////////////////////////////////////////////////////
bool
DefinitionMgrClass::Load (ChunkLoadClass &cload)
{
WWMEMLOG(MEM_GAMEDATA);
bool retval = true;
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
//
// If this is the chunk that contains the class variables, then
// loop through and read each microchunk
//
case CHUNKID_VARIABLES:
retval &= Load_Variables (cload);
break;
//
// Load all the definition objects from this chunk
//
case CHUNKID_OBJECTS:
retval &= Load_Objects (cload);
break;
}
cload.Close_Chunk ();
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Save_Objects
//
//////////////////////////////////////////////////////////////////////////////////
bool
DefinitionMgrClass::Save_Objects
(
ChunkSaveClass & csave
)
{
bool retval = true;
//
// Loop through all the definition objects
//
for (int index = 0; index < _DefinitionCount; index ++) {
DefinitionClass *definition = _SortedDefinitionArray[index];
if (definition != NULL && definition->Is_Save_Enabled ()) {
//
// Save this definition object
//
csave.Begin_Chunk (definition->Get_Factory ().Chunk_ID ());
definition->Get_Factory ().Save (csave, definition);
csave.End_Chunk ();
}
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Save_Variables
//
//////////////////////////////////////////////////////////////////////////////////
bool
DefinitionMgrClass::Save_Variables (ChunkSaveClass &csave)
{
bool retval = true;
return retval;
}
float _alloc_time;
float _load_time;
float _reg_time;
//////////////////////////////////////////////////////////////////////////////////
//
// Load_Objects
//
//////////////////////////////////////////////////////////////////////////////////
bool
DefinitionMgrClass::Load_Objects (ChunkLoadClass &cload)
{
bool retval = true;
while (cload.Open_Chunk ()) {
//
// Load this definition from the chunk (if possible)
//
PersistFactoryClass *factory = SaveLoadSystemClass::Find_Persist_Factory (cload.Cur_Chunk_ID ());
if (factory != NULL) {
DefinitionClass *definition = (DefinitionClass *)factory->Load (cload);
if (definition != NULL) {
//
// Add this definition to our array
//
Prepare_Definition_Array ();
_SortedDefinitionArray[_DefinitionCount ++] = definition;
}
}
cload.Close_Chunk ();
}
//
// Sort the definitions
//
if (_DefinitionCount > 0) {
::qsort (_SortedDefinitionArray, _DefinitionCount, sizeof (DefinitionClass *), fnCompareDefinitionsCallback);
}
//
// Assign a mgr link to each definition
//
for (int index = 0; index < _DefinitionCount; index ++) {
_SortedDefinitionArray[index]->m_DefinitionMgrLink = index;
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Load_Variables
//
//////////////////////////////////////////////////////////////////////////////////
bool
DefinitionMgrClass::Load_Variables (ChunkLoadClass &cload)
{
bool retval = true;
//
// Loop through all the microchunks that define the variables
//
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ()) {
case VARID_NEXTDEFID:
break;
}
cload.Close_Micro_Chunk ();
}
return retval;
}
/////////////////////////////////////////////////////////////////////
//
// Get_New_ID
//
/////////////////////////////////////////////////////////////////////
uint32
DefinitionMgrClass::Get_New_ID (uint32 class_id)
{
uint32 idrange_start = (class_id - DEF_CLASSID_START) * IDRANGE_PER_CLASS;
uint32 idrange_end = (idrange_start + IDRANGE_PER_CLASS);
uint32 new_id = idrange_start;
//
// Loop through all the definition objects
//
for (int index = 0; index < _DefinitionCount; index ++) {
DefinitionClass *definition = _SortedDefinitionArray[index];
if (definition != NULL) {
//
// Get this definition's ID
//
uint32 curr_id = definition->Get_ID ();
//
// Is this id in the range we are looking for?
//
if (curr_id >= idrange_start && curr_id < idrange_end) {
//
// Take the largest ID in the range
//
new_id = max (new_id, curr_id);
}
}
}
new_id ++;
return new_id;
}
////////////////////////////////////////////////////////////////
//
// fnCompareDefinitionsCallback
//
////////////////////////////////////////////////////////////////
int __cdecl
DefinitionMgrClass::fnCompareDefinitionsCallback
(
const void *elem1,
const void *elem2
)
{
WWASSERT (elem1 != NULL);
WWASSERT (elem2 != NULL);
DefinitionClass *definition1 = *((DefinitionClass **)elem1);
DefinitionClass *definition2 = *((DefinitionClass **)elem2);
//
// Sort the definitions based on ID
//
int result = 0;
if (definition1->Get_ID () > definition2->Get_ID ()) {
result = 1;
} else if (definition1->Get_ID () < definition2->Get_ID ()) {
result = -1;
} else {
result = 0;
}
return result;
}

View file

@ -0,0 +1,187 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/definitionmgr.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 8/24/01 5:13p $*
* *
* $Revision:: 24 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __DEFINITION_MGR_H
#define __DEFINITION_MGR_H
#include "always.h"
#include "saveload.h"
#include "saveloadsubsystem.h"
#include "saveloadids.h"
#include "wwdebug.h"
#include "wwstring.h"
#include "hashtemplate.h"
#include "vector.h"
// Forward declarations
class DefinitionClass;
//////////////////////////////////////////////////////////////////////////////////
// Global declarations
//////////////////////////////////////////////////////////////////////////////////
extern class DefinitionMgrClass _TheDefinitionMgr;
//////////////////////////////////////////////////////////////////////////////////
//
// DefinitionMgrClass
//
//////////////////////////////////////////////////////////////////////////////////
class DefinitionMgrClass : public SaveLoadSubSystemClass
{
public:
/////////////////////////////////////////////////////////////////////
// Public constructors/destructors
/////////////////////////////////////////////////////////////////////
DefinitionMgrClass (void);
~DefinitionMgrClass (void);
/////////////////////////////////////////////////////////////////////
// Public methods
/////////////////////////////////////////////////////////////////////
// From SaveLoadSubSystemClass
virtual uint32 Chunk_ID (void) const;
// Type identification
static DefinitionClass * Find_Definition (uint32 id, bool twiddle = true);
static DefinitionClass * Find_Named_Definition (const char *name, bool twiddle = true);
static DefinitionClass * Find_Typed_Definition (const char *name, uint32 class_id, bool twiddle = true);
static void List_Available_Definitions (void);
static void List_Available_Definitions (int superclass_id);
static uint32 Get_New_ID (uint32 class_id);
// Definition registration
static void Register_Definition (DefinitionClass *definition);
static void Unregister_Definition (DefinitionClass *definition);
//
// Definition enumeration
//
typedef enum
{
ID_CLASS = 1,
ID_SUPERCLASS,
} ID_TYPE;
static DefinitionClass * Get_First (void);
static DefinitionClass * Get_First (uint32 id, ID_TYPE type = ID_CLASS);
static DefinitionClass * Get_Next (DefinitionClass *curr_def);
static DefinitionClass * Get_Next (DefinitionClass *curr_def, uint32 id, ID_TYPE type = ID_CLASS);
static void Free_Definitions (void);
protected:
/////////////////////////////////////////////////////////////////////
// Protected methods
/////////////////////////////////////////////////////////////////////
// From SaveLoadSubSystemClass
virtual bool Contains_Data (void) const;
virtual bool Save (ChunkSaveClass &csave);
virtual bool Load (ChunkLoadClass &cload);
virtual const char* Name (void) const { return "DefinitionMgrClass"; }
// Persistence methods
bool Save_Objects (ChunkSaveClass &csave);
bool Load_Objects (ChunkLoadClass &cload);
bool Save_Variables (ChunkSaveClass &csave);
bool Load_Variables (ChunkLoadClass &cload);
private:
static HashTemplateClass<StringClass, DynamicVectorClass<DefinitionClass*>*>* DefinitionHash;
/////////////////////////////////////////////////////////////////////
// Private methods
/////////////////////////////////////////////////////////////////////
static void Prepare_Definition_Array (void);
static int __cdecl fnCompareDefinitionsCallback (const void *elem1, const void *elem2);
/////////////////////////////////////////////////////////////////////
// Static member data
/////////////////////////////////////////////////////////////////////
static DefinitionClass ** _SortedDefinitionArray;
static int _MaxDefinitionCount;
static int _DefinitionCount;
/////////////////////////////////////////////////////////////////////
// Friend classes
/////////////////////////////////////////////////////////////////////
friend class DefinitionClass;
};
/////////////////////////////////////////////////////////////////////
// Chunk_ID
/////////////////////////////////////////////////////////////////////
inline uint32
DefinitionMgrClass::Chunk_ID (void) const
{
return CHUNKID_SAVELOAD_DEFMGR;
}
/////////////////////////////////////////////////////////////////////
// Contains_Data
/////////////////////////////////////////////////////////////////////
inline bool
DefinitionMgrClass::Contains_Data (void) const
{
return true; // TODO: check if we have any definitions...
}
/////////////////////////////////////////////////////////////////////
// Get_First_Definition
/////////////////////////////////////////////////////////////////////
inline DefinitionClass *
DefinitionMgrClass::Get_First (void)
{
DefinitionClass *definition = NULL;
if (_DefinitionCount > 0) {
definition = _SortedDefinitionArray[0];
}
return definition;
}
#endif //__DEFINITION_MGR_H

View file

@ -0,0 +1,308 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/editable.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 11/02/00 3:34p $*
* *
* $Revision:: 27 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __EDITABLE_H
#define __EDITABLE_H
#include "always.h"
#include "persist.h"
#include "parameter.h"
#include "simpleparameter.h"
#include "parameterlist.h"
#include "wwdebug.h"
//////////////////////////////////////////////////////////////////////////////////
//
// EditableClass
//
//////////////////////////////////////////////////////////////////////////////////
class EditableClass : public PersistClass
{
public:
/////////////////////////////////////////////////////////////////////
// Public methods
//
// Note: These methods can be implemented in derived classes
// by the DECLARE_EDITABLE macro.
//
/////////////////////////////////////////////////////////////////////
virtual int Get_Parameter_Count (void) const;
virtual ParameterClass * Lock_Parameter (int i);
virtual void Unlock_Parameter (int i);
};
/////////////////////////////////////////////////////////////////////
// Get_Parameter_Count
/////////////////////////////////////////////////////////////////////
inline int
EditableClass::Get_Parameter_Count (void) const
{
return 0;
}
/////////////////////////////////////////////////////////////////////
// Get_Parameter
/////////////////////////////////////////////////////////////////////
inline ParameterClass *
EditableClass::Lock_Parameter (int i)
{
WWASSERT (0);
return NULL;
}
/////////////////////////////////////////////////////////////////////
// Set_Parameter
/////////////////////////////////////////////////////////////////////
inline void
EditableClass::Unlock_Parameter (int i)
{
return ;
}
//#define PARAM_EDITING_ON
#ifdef PARAM_EDITING_ON
//////////////////////////////////////////////////////////////////////////////////
//
// DECLARE_EDITABLE
//
//////////////////////////////////////////////////////////////////////////////////
#define DECLARE_EDITABLE(_class, _parent) \
ParameterListClass plist_##_class; \
virtual int _class::Get_Parameter_Count(void) const \
{ \
return plist_##_class.Count () + _parent::Get_Parameter_Count (); \
} \
virtual ParameterClass *_class::Lock_Parameter(int i) \
{ \
if (i < _parent::Get_Parameter_Count()) { \
return _parent::Lock_Parameter (i); \
} \
return plist_##_class[i - _parent::Get_Parameter_Count()]; \
} \
//////////////////////////////////////////////////////////////////////////////////
//
// EDITABLE_PARAM
//
// The following macros are used inside the constructor for an editable
// object to map member data to abstract parameter objects.
//
// Some examples:
//
// To register the player's name (a string):
// EDITABLE_PARAM(GameClass, ParameterClass::TYPE_STRING, Name)
//
// To register the player's name using a more descriptive display string:
// NAMED_EDITABLE_PARAM(GameClass, ParameterClass::TYPE_STRING, Name, "Player Name")
//
// To register a unit's maximum health
// INT_EDITABLE_PARAM(GameClass, MaxHeatlh, 0, 500)
//
// To register a complex variable (such as an enumerated type:
// #ifdef PARAM_EDITING_ON
// EnumParameterClass *param = new EnumParameterClass(GangID);
// param->Set_Name ("Gang");
// param->Add_Value ("GDI", ID_GDI);
// param->Add_Value ("NOD", ID_NOD);
// param->Add_Value ("Neutral", ID_NEUTRAL);
// GENERIC_EDITABLE_PARAM(param)
// #endif
//
//////////////////////////////////////////////////////////////////////////////////
#define EDITABLE_PARAM(_class, type, data) plist_##_class.Add (&(data), #data, type);
#define NAMED_EDITABLE_PARAM(_class, type, data, name) plist_##_class.Add (&(data), name, type);
#define INT_EDITABLE_PARAM(_class, data, min, max) { \
IntParameterClass *param = W3DNEW IntParameterClass( &data, #data); \
param->Set_Range (min, max); \
plist_##_class.Add (param); } \
#define INT_UNITS_PARAM(_class, data, min, max, unitsname) { \
IntParameterClass *param = W3DNEW IntParameterClass( &data, #data); \
param->Set_Range (min, max); \
param->Set_Units_Name(unitsname); \
plist_##_class.Add (param); } \
#define NAMED_INT_UNITS_PARAM(_class,data,min,max,unitsname,name) { \
IntParameterClass *param = W3DNEW IntParameterClass( &data, #data); \
param->Set_Range (min, max); \
param->Set_Units_Name(unitsname); \
param->Set_Name(name); \
plist_##_class.Add (param); } \
#define FLOAT_EDITABLE_PARAM(_class, data, min, max) { \
FloatParameterClass *param = W3DNEW FloatParameterClass( &data, #data); \
param->Set_Range (min, max); \
plist_##_class.Add (param); } \
#define FLOAT_UNITS_PARAM(_class, data, min, max, unitsname) { \
FloatParameterClass *param = W3DNEW FloatParameterClass( &data, #data); \
param->Set_Range (min, max); \
param->Set_Units_Name(unitsname); \
plist_##_class.Add (param); }
#define NAMED_FLOAT_UNITS_PARAM(_class, data, min, max, unitsname,name) { \
FloatParameterClass *param = W3DNEW FloatParameterClass( &data, #data); \
param->Set_Range (min, max); \
param->Set_Units_Name(unitsname); \
param->Set_Name(name); \
plist_##_class.Add (param); }
#define ANGLE_EDITABLE_PARAM(_class, data, min, max) { \
AngleParameterClass *param = W3DNEW AngleParameterClass( &data, #data); \
param->Set_Range (min, max); \
param->Set_Units_Name ("degrees"); \
plist_##_class.Add (param); } \
#define NAMED_ANGLE_EDITABLE_PARAM(_class, data, min, max, name) { \
AngleParameterClass *param = W3DNEW AngleParameterClass( &data, #data); \
param->Set_Range (min, max); \
param->Set_Units_Name ("degrees"); \
param->Set_Name(name); \
plist_##_class.Add (param); } \
#define GENERIC_EDITABLE_PARAM(_class, param) \
plist_##_class.Add (param); \
#define MODEL_DEF_PARAM(_class, data, name) { \
ModelDefParameterClass *param = W3DNEW ModelDefParameterClass (&data); \
param->Set_Name (#data); \
param->Set_Base_Class (name); \
GENERIC_EDITABLE_PARAM(_class, param); }
#define PHYS_DEF_PARAM(_class, data, name) { \
PhysDefParameterClass *param = W3DNEW PhysDefParameterClass (&data); \
param->Set_Name (#data); \
param->Set_Base_Class (name); \
GENERIC_EDITABLE_PARAM(_class, param); }
#define SCRIPT_PARAM(_class, name, params) { \
ScriptParameterClass *param = W3DNEW ScriptParameterClass (&name, &params); \
param->Set_Name (#name); \
GENERIC_EDITABLE_PARAM(_class, param); }
#define SCRIPTLIST_PARAM(_class, name, name_list, param_list) { \
ScriptListParameterClass *param = W3DNEW ScriptListParameterClass (&name_list, &param_list); \
param->Set_Name (name); \
GENERIC_EDITABLE_PARAM(_class, param); }
#define ENUM_PARAM(_class, data, params) { \
EnumParameterClass *param = W3DNEW EnumParameterClass (&data); \
param->Set_Name (#data); \
param->Add_Values params; \
plist_##_class.Add (param); } \
#define FILENAME_PARAM(_class, data, desc, extension) { \
FilenameParameterClass *param = W3DNEW FilenameParameterClass (&data); \
param->Set_Name (#data); \
param->Set_Description (desc); \
param->Set_Extension (extension); \
plist_##_class.Add (param); } \
#define DEFIDLIST_PARAM(_class, data, root_class_id) { \
DefIDListParameterClass *param = W3DNEW DefIDListParameterClass (&data); \
param->Set_Name (#data); \
param->Set_Class_ID (root_class_id); \
plist_##_class.Add (param); } \
#define CLASSID_DEFIDLIST_PARAM(_class, data, root_class_id, class_id, name) { \
DefIDListParameterClass *param = W3DNEW DefIDListParameterClass (&data); \
param->Set_Name (name); \
param->Set_Class_ID (root_class_id); \
param->Set_Selected_Class_ID (&class_id); \
plist_##_class.Add (param); }
#define ZONE_PARAM(_class, data, name) { \
ZoneParameterClass *param = W3DNEW ZoneParameterClass (&data); \
param->Set_Name (name); \
GENERIC_EDITABLE_PARAM(_class, param); }
#define PARAM_SEPARATOR(_class, name) { \
SeparatorParameterClass *param = W3DNEW SeparatorParameterClass; \
param->Set_Name (name); \
GENERIC_EDITABLE_PARAM(_class, param); }
#define GENERIC_DEFID_PARAM(_class, data, root_class_id) { \
GenericDefParameterClass *param = W3DNEW GenericDefParameterClass (&data); \
param->Set_Class_ID (root_class_id); \
param->Set_Name (#data); \
plist_##_class.Add (param); }
#else
#define DECLARE_EDITABLE(_class, _parent)
#define EDITABLE_PARAM(_class, type, data)
#define NAMED_EDITABLE_PARAM(_class, type, data, name)
#define INT_EDITABLE_PARAM(_class, data, min, max)
#define INT_UNITS_PARAM(_class, data, min, max, unitsname)
#define NAMED_INT_UNITS_PARAM(_class,data,min,max,unitsname,name)
#define FLOAT_EDITABLE_PARAM(_class, data, min, max)
#define FLOAT_UNITS_PARAM(_class, data, min, max, unitsname)
#define NAMED_FLOAT_UNITS_PARAM(_class, data, min, max, unitsname,name)
#define ANGLE_EDITABLE_PARAM(_class, data, min, max)
#define NAMED_ANGLE_EDITABLE_PARAM(_class, data, min, max, name)
#define GENERIC_EDITABLE_PARAM(_class, param)
#define MODEL_DEF_PARAM(_class, data, name)
#define PHYS_DEF_PARAM(_class, data, name)
#define SCRIPT_PARAM(_class, name, params)
#define SCRIPTLIST_PARAM(_class, name, name_list, param_list)
#define ENUM_PARAM(_class, data, params)
#define FILENAME_PARAM(_class, data, desc, extension)
#define DEFIDLIST_PARAM(_class, data, root_class_id)
#define CLASSID_DEFIDLIST_PARAM(_class, data, root_class_id, class_id, name)
#define ZONE_PARAM(_class, data, name)
#define PARAM_SEPARATOR(_class, name)
#define GENERIC_DEFID_PARAM(_class, data, root_class_id)
#endif //PARAM_EDITING_ON
#endif //__EDITABLE_H

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,160 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/parameterlist.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 10/06/99 2:52p $*
* *
* $Revision:: 9 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __PARAMETER_LIST_H
#define __PARAMETER_LIST_H
#include "always.h"
#include "vector.h"
#include "parameter.h"
#include "wwdebug.h"
//////////////////////////////////////////////////////////////////////////////////
//
// ParameterListClass
//
//////////////////////////////////////////////////////////////////////////////////
class ParameterListClass : public DynamicVectorClass<ParameterClass *>
{
public:
/////////////////////////////////////////////////////////////////////
// Public constructurs/destructors
/////////////////////////////////////////////////////////////////////
~ParameterListClass (void);
/////////////////////////////////////////////////////////////////////
// Public methods
/////////////////////////////////////////////////////////////////////
void Add (void *data, const char *param_name, ParameterClass::Type type);
void Add (ParameterClass *parameter);
protected:
/////////////////////////////////////////////////////////////////////
// Protected methods
/////////////////////////////////////////////////////////////////////
void Free_Parameters (void);
private:
/////////////////////////////////////////////////////////////////////
// Private member data
/////////////////////////////////////////////////////////////////////
DynamicVectorClass<ParameterClass *> m_Parameters;
};
/////////////////////////////////////////////////////////////////////
// ~ParameterListClass
/////////////////////////////////////////////////////////////////////
inline
ParameterListClass::~ParameterListClass (void)
{
Free_Parameters ();
return ;
}
/////////////////////////////////////////////////////////////////////
// Add
/////////////////////////////////////////////////////////////////////
inline void
ParameterListClass::Add (void *data, const char *param_name, ParameterClass::Type type)
{
//
// Create a new parameter object
//
ParameterClass *new_param = ParameterClass::Construct (type, data, param_name);
//
// Add the new paramter object to our list
//
WWASSERT (new_param != NULL);
if (new_param != NULL) {
DynamicVectorClass<ParameterClass *>::Add (new_param);
}
return ;
}
/////////////////////////////////////////////////////////////////////
// Add
/////////////////////////////////////////////////////////////////////
inline void
ParameterListClass::Add (ParameterClass *new_param)
{
//
// Add the new paramter object to our list
//
if (new_param != NULL) {
DynamicVectorClass<ParameterClass *>::Add (new_param);
}
return ;
}
/////////////////////////////////////////////////////////////////////
// Free_Parameters
/////////////////////////////////////////////////////////////////////
inline void
ParameterListClass::Free_Parameters (void)
{
for (int index = 0; index < Count (); index ++) {
ParameterClass *param = Vector[index];
//
// Free the parameter object
//
if (param != NULL) {
delete param;
}
}
m_Parameters.Delete_All ();
return ;
}
#endif //__PARAMETER_LIST_H

View file

@ -0,0 +1,69 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/parametertypes.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 9/10/99 3:38p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __PARAMETER_TYPES_H
#define __PARAMETER_TYPES_H
#include "always.h"
//////////////////////////////////////////////////////////////////////////////////
//
// ParameterType
//
//////////////////////////////////////////////////////////////////////////////////
/*typedef enum
{
TYPE_INT = 0,
TYPE_FLOAT,
TYPE_STRING,
TYPE_VECTOR3,
TYPE_MATRIX3D,
TYPE_TRANSITION,
TYPE_PRESETID,
TYPE_MODELFILENAME
} ParameterType;*/
#endif //__PARAMETER_TYPES_H

View file

@ -0,0 +1,77 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/persist.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 5/04/01 8:42p $*
* *
* $Revision:: 13 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef PERSIST_H
#define PERSIST_H
#include "always.h"
#include "refcount.h"
#include "postloadable.h"
class PersistFactoryClass;
class ChunkSaveClass;
class ChunkLoadClass;
//////////////////////////////////////////////////////////////////////////////////
//
// PersistClass
//
// PersistClass defines the interface for an object to the save load system.
// Each concrete derived type of PersistClass must have an associated
// PersistFactoryClass that basically maps a chunk_id to a constructor,
// a save function, a load function, and a on_post_load function (taken from
// PostLoadableClass )
//
//////////////////////////////////////////////////////////////////////////////////
class PersistClass : public PostLoadableClass
{
public:
virtual const PersistFactoryClass & Get_Factory (void) const = 0;
virtual bool Save (ChunkSaveClass &csave) { return true; }
virtual bool Load (ChunkLoadClass &cload) { return true; }
};
#endif

View file

@ -0,0 +1,50 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/persistfactory.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/09/99 9:50a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "persistfactory.h"
#include "saveload.h"
PersistFactoryClass::PersistFactoryClass(void) :
NextFactory(NULL)
{
SaveLoadSystemClass::Register_Persist_Factory(this);
}
PersistFactoryClass::~PersistFactoryClass(void)
{
SaveLoadSystemClass::Unregister_Persist_Factory(this);
}

View file

@ -0,0 +1,144 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/persistfactory.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 5/04/01 8:42p $*
* *
* $Revision:: 11 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef PERSISTFACTORY_H
#define PERSISTFACTORY_H
#include "always.h"
#include "bittype.h"
#include "chunkio.h"
#include "wwdebug.h"
#include "saveload.h"
class PersistClass;
/*
** PersistFactoryClass
** Create a PersistFactoryClass for each concrete derived PersistClass. These
** factories automatically register with the SaveLoadSystem in their constructors
** and should be accessible through the virtual Get_Factory method of any
** derived PersistClass.
*/
class PersistFactoryClass
{
public:
PersistFactoryClass(void);
virtual ~PersistFactoryClass(void);
virtual uint32 Chunk_ID(void) const = 0;
virtual PersistClass * Load(ChunkLoadClass & cload) const = 0;
virtual void Save(ChunkSaveClass & csave,PersistClass * obj) const = 0;
private:
PersistFactoryClass * NextFactory;
friend class SaveLoadSystemClass;
};
/*
** SimplePersistFactoryClass
** This template automates the creation of a PersistFactory for any type of Persist
** object. Simply instantiate a single static instance of this template with the
** type and chunkid in the .cpp file of your class.
*/
template <class T,int CHUNKID> class SimplePersistFactoryClass : public PersistFactoryClass
{
public:
virtual uint32 Chunk_ID(void) const { return CHUNKID; }
virtual PersistClass * Load(ChunkLoadClass & cload) const;
virtual void Save(ChunkSaveClass & csave,PersistClass * obj) const;
/*
** Internal chunk id's
*/
enum
{
SIMPLEFACTORY_CHUNKID_OBJPOINTER = 0x00100100,
SIMPLEFACTORY_CHUNKID_OBJDATA
};
};
template<class T, int CHUNKID> PersistClass *
SimplePersistFactoryClass<T,CHUNKID>::Load(ChunkLoadClass & cload) const
{
T * new_obj = W3DNEW T;
T * old_obj = NULL;
cload.Open_Chunk();
WWASSERT(cload.Cur_Chunk_ID() == SIMPLEFACTORY_CHUNKID_OBJPOINTER);
cload.Read(&old_obj,sizeof(T *));
cload.Close_Chunk();
cload.Open_Chunk();
WWASSERT(cload.Cur_Chunk_ID() == SIMPLEFACTORY_CHUNKID_OBJDATA);
new_obj->Load(cload);
cload.Close_Chunk();
SaveLoadSystemClass::Register_Pointer(old_obj,new_obj);
return new_obj;
}
template<class T, int CHUNKID> void
SimplePersistFactoryClass<T,CHUNKID>::Save(ChunkSaveClass & csave,PersistClass * obj) const
{
uint32 objptr = (uint32)obj;
csave.Begin_Chunk(SIMPLEFACTORY_CHUNKID_OBJPOINTER);
csave.Write(&objptr,sizeof(uint32));
csave.End_Chunk();
csave.Begin_Chunk(SIMPLEFACTORY_CHUNKID_OBJDATA);
obj->Save(csave);
csave.End_Chunk();
}
#endif

View file

@ -0,0 +1,210 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/pointerremap.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 5/09/01 11:36a $*
* *
* $Revision:: 9 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "pointerremap.h"
#include "refcount.h"
#include "wwdebug.h"
const int POINTER_TABLES_GROWTH_STEP = 4096;
PointerRemapClass::PointerRemapClass(void)
{
PointerPairTable.Set_Growth_Step(POINTER_TABLES_GROWTH_STEP);
PointerRequestTable.Set_Growth_Step(POINTER_TABLES_GROWTH_STEP);
RefCountRequestTable.Set_Growth_Step(POINTER_TABLES_GROWTH_STEP);
}
PointerRemapClass::~PointerRemapClass(void)
{
}
void PointerRemapClass::Reset(void)
{
PointerPairTable.Delete_All();
PointerRequestTable.Delete_All();
RefCountRequestTable.Delete_All();
}
void PointerRemapClass::Process(void)
{
if ( PointerPairTable.Count() > 0 ) {
qsort(&PointerPairTable[0], PointerPairTable.Count(), sizeof(PointerPairTable[0]), ptr_pair_compare_function);
}
if ( PointerRequestTable.Count() > 0 ) {
WWASSERT( PointerPairTable.Count() > 0 );
qsort(&PointerRequestTable[0],PointerRequestTable.Count(), sizeof(PointerRequestTable[0]), ptr_request_compare_function);
Process_Request_Table(PointerRequestTable,false);
}
// remap the ref-counted pointers
if ( RefCountRequestTable.Count() > 0 ) {
WWASSERT( PointerPairTable.Count() > 0 );
qsort(&RefCountRequestTable[0],RefCountRequestTable.Count(), sizeof(RefCountRequestTable[0]), ptr_request_compare_function);
Process_Request_Table(RefCountRequestTable,true);
}
}
void PointerRemapClass::Process_Request_Table(DynamicVectorClass<PtrRemapStruct> & request_table,bool refcount)
{
// Remap the pointers
int pointer_index = 0;
int pair_index = 0;
for (pointer_index = 0; pointer_index < request_table.Count(); pointer_index++) {
void * pointer_to_remap = *(request_table[pointer_index].PointerToRemap);
int pre_search_index = pair_index;
// Find the pair which contains the pointer we are looking for as its "old" pointer
while ( (pair_index < PointerPairTable.Count()) &&
(PointerPairTable[pair_index].OldPointer < pointer_to_remap) )
{
pair_index++;
}
if ((pair_index < PointerPairTable.Count()) && (PointerPairTable[pair_index].OldPointer == pointer_to_remap)) {
// we found the match, plug in the new pointer and add a ref if needed.
*request_table[pointer_index].PointerToRemap = PointerPairTable[pair_index].NewPointer;
if (refcount) {
RefCountClass * refptr = (RefCountClass *)(*request_table[pointer_index].PointerToRemap);
refptr->Add_Ref();
}
} else {
// Failed to re-map the pointer.
// warn the user, set pointer to NULL, reset index to the pre_search_index.
// If this happens, things could be going very wrong. (find out why its happening!)
pair_index = pre_search_index;
*request_table[pointer_index].PointerToRemap = NULL;
#ifdef WWDEBUG
const char * file = request_table[pointer_index].File;
int line = request_table[pointer_index].Line;
WWDEBUG_SAY(("Warning! Failed to re-map pointer! old_ptr = 0x%X file = %s line = %d\r\n",(unsigned int)pointer_to_remap,file,line));
WWASSERT( 0 );
#endif
}
}
}
void PointerRemapClass::Register_Pointer (void *old_pointer, void *new_pointer)
{
PointerPairTable.Add(PtrPairStruct(old_pointer,new_pointer));
}
#ifdef WWDEBUG
void PointerRemapClass::Request_Pointer_Remap(void **pointer_to_convert,const char * file,int line)
{
PtrRemapStruct remap;
remap.PointerToRemap = pointer_to_convert;
remap.File = file;
remap.Line = line;
PointerRequestTable.Add(remap);
}
void PointerRemapClass::Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert,const char * file, int line)
{
PtrRemapStruct remap;
remap.PointerToRemap = (void**)pointer_to_convert;
remap.File = file;
remap.Line = line;
RefCountRequestTable.Add(remap);
}
#else
void PointerRemapClass::Request_Pointer_Remap (void **pointer_to_convert)
{
PtrRemapStruct remap;
remap.PointerToRemap = pointer_to_convert;
PointerRequestTable.Add(remap);
}
void PointerRemapClass::Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert)
{
PtrRemapStruct remap;
remap.PointerToRemap = (void**)pointer_to_convert;
RefCountRequestTable.Add(remap);
}
#endif
/*
** sort compare function for pointer pair structures
** sorts by the old pointer value
*/
int __cdecl PointerRemapClass::ptr_pair_compare_function(void const * ptr1, void const * ptr2)
{
void * old1 = ((PointerRemapClass::PtrPairStruct const *)ptr1)->OldPointer;
void * old2 = ((PointerRemapClass::PtrPairStruct const *)ptr2)->OldPointer;
if (old1 == old2) {
return(0);
}
if (old1 < old2) {
return(-1);
}
return(1);
}
/*
** sort compare function for pointer remap structures
** sorts by the old pointer value
*/
int __cdecl PointerRemapClass::ptr_request_compare_function(void const * ptr1, void const * ptr2)
{
PtrRemapStruct * remap1 = (PtrRemapStruct *)ptr1;
PtrRemapStruct * remap2 = (PtrRemapStruct *)ptr2;
void * old1 = *(remap1->PointerToRemap);
void * old2 = *(remap2->PointerToRemap);
if (old1 == old2) {
return(0);
}
if (old1 < old2) {
return(-1);
}
return(1);
}

View file

@ -0,0 +1,115 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/pointerremap.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 4/30/01 1:54p $*
* *
* $Revision:: 6 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef POINTERREMAP_H
#define POINTERREMAP_H
#ifdef _UNIX
#include "osdep/osdep.h"
#endif
#include "always.h"
#include "vector.h"
class RefCountClass;
class PointerRemapClass
{
public:
PointerRemapClass(void);
~PointerRemapClass(void);
void Reset(void);
void Process(void);
void Register_Pointer (void *old_pointer, void *new_pointer);
#ifdef WWDEBUG
void Request_Pointer_Remap (void **pointer_to_convert,const char * file,int line);
void Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert,const char * file, int line);
#else
void Request_Pointer_Remap (void **pointer_to_convert);
void Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert);
#endif
private:
struct PtrPairStruct
{
PtrPairStruct(void) {}
PtrPairStruct(void * oldptr,void * newptr) : OldPointer(oldptr),NewPointer(newptr) {}
bool operator == (const PtrPairStruct & that) { return ((OldPointer == that.OldPointer) && (NewPointer == that.NewPointer)); }
bool operator != (const PtrPairStruct & that) { return !(*this == that); }
void * OldPointer;
void * NewPointer;
};
struct PtrRemapStruct
{
PtrRemapStruct(void) {}
bool operator == (const PtrRemapStruct & that) { return (PointerToRemap == that.PointerToRemap); }
bool operator != (const PtrRemapStruct & that) { return !(*this == that); }
void ** PointerToRemap;
#ifdef WWDEBUG
const char * File;
int Line;
#endif
};
void Process_Request_Table(DynamicVectorClass<PtrRemapStruct> & request_table,bool refcount);
static int __cdecl ptr_pair_compare_function(void const * ptr1, void const * ptr2);
static int __cdecl ptr_request_compare_function(void const * ptr1, void const * ptr2);
/*
** Array of pointers associated with ID values to assist in swizzling.
*/
DynamicVectorClass<PtrPairStruct> PointerPairTable;
DynamicVectorClass<PtrRemapStruct> PointerRequestTable;
DynamicVectorClass<PtrRemapStruct> RefCountRequestTable;
};
#endif

View file

@ -0,0 +1,71 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/postloadable.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 5/09/01 11:46a $*
* *
* $Revision:: 3 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#ifndef POSTLOADABLE_H
#define POSTLOADABLE_H
//////////////////////////////////////////////////////////////////////////////////
//
// PostLoadableClass
//
// PostLoadableClass allows a lower level for non-Persist objects to On_Post_Load
// without requiring Get_Factory or other requirements of PersistClass. Objects
// derived from this class can be added to the post-load list in the SaveLoadSystem
//
//////////////////////////////////////////////////////////////////////////////////
class PostLoadableClass
{
public:
PostLoadableClass(void) : IsPostLoadRegistered(false) { }
virtual ~PostLoadableClass(void) { }
virtual void On_Post_Load (void) { }
bool Is_Post_Load_Registered(void) { return IsPostLoadRegistered; }
void Set_Post_Load_Registered(bool onoff) { IsPostLoadRegistered = onoff; }
private:
bool IsPostLoadRegistered;
};
#endif

View file

@ -0,0 +1,284 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/saveload.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 5/09/01 11:48a $*
* *
* $Revision:: 15 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "saveload.h"
#include "saveloadsubsystem.h"
#include "persist.h"
#include "persistfactory.h"
#include "chunkio.h"
#include "wwdebug.h"
#include "saveloadstatus.h"
#include "wwhack.h"
SaveLoadSubSystemClass * SaveLoadSystemClass::SubSystemListHead = NULL;
PersistFactoryClass * SaveLoadSystemClass::FactoryListHead = NULL;
SList<PostLoadableClass> SaveLoadSystemClass::PostLoadList;
PointerRemapClass SaveLoadSystemClass::PointerRemapper;
bool SaveLoadSystemClass::Save (ChunkSaveClass &csave,SaveLoadSubSystemClass & subsystem)
{
bool ok = true;
if (subsystem.Contains_Data()) {
csave.Begin_Chunk (subsystem.Chunk_ID ());
ok &= subsystem.Save (csave);
csave.End_Chunk ();
}
return ok;
}
bool SaveLoadSystemClass::Load (ChunkLoadClass &cload,bool auto_post_load)
{
// WWASSERT(PostLoadList.Head() == NULL);
PointerRemapper.Reset();
bool ok = true;
// Load each chunk we encounter and link the manager into the PostLoad list
while (cload.Open_Chunk ()) {
SaveLoadSubSystemClass *sys = Find_Sub_System(cload.Cur_Chunk_ID ());
if (sys != NULL) {
INIT_SUB_STATUS(sys->Name());
ok &= sys->Load(cload);
}
cload.Close_Chunk();
}
// Process all of the pointer remap requests
PointerRemapper.Process();
PointerRemapper.Reset();
// Call PostLoad on each PersistClass that wanted post-load
if (auto_post_load) {
Post_Load_Processing();
}
return ok;
}
bool SaveLoadSystemClass::Post_Load_Processing (void)
{
// Call PostLoad on each PersistClass that wanted post-load
PostLoadableClass * obj = PostLoadList.Remove_Head();
while (obj) {
obj->On_Post_Load();
obj->Set_Post_Load_Registered(false);
obj = PostLoadList.Remove_Head();
}
return true;
}
void SaveLoadSystemClass::Register_Sub_System (SaveLoadSubSystemClass * sys)
{
WWASSERT(sys != NULL);
Link_Sub_System(sys);
}
void SaveLoadSystemClass::Unregister_Sub_System (SaveLoadSubSystemClass * sys)
{
WWASSERT(sys != NULL);
Unlink_Sub_System(sys);
}
SaveLoadSubSystemClass * SaveLoadSystemClass::Find_Sub_System (uint32 chunk_id)
{
// TODO: need a d-s that gives fast searching based on chunk_id!!
SaveLoadSubSystemClass * sys;
for ( sys = SubSystemListHead; sys != NULL; sys = sys->NextSubSystem ) {
if ( sys->Chunk_ID() == chunk_id ) {
break;
}
}
return sys;
}
void SaveLoadSystemClass::Register_Persist_Factory(PersistFactoryClass * factory)
{
WWASSERT(factory != NULL);
Link_Factory(factory);
}
void SaveLoadSystemClass::Unregister_Persist_Factory(PersistFactoryClass * factory)
{
WWASSERT(factory != NULL);
Unlink_Factory(factory);
}
PersistFactoryClass * SaveLoadSystemClass::Find_Persist_Factory(uint32 chunk_id)
{
// TODO: need a d-s that gives fast searching based on chunk_id!!
PersistFactoryClass * fact;
for ( fact = FactoryListHead; fact != NULL; fact = fact->NextFactory ) {
if ( fact->Chunk_ID() == chunk_id ) {
break;
}
}
return fact;
}
bool SaveLoadSystemClass::Is_Post_Load_Callback_Registered(PostLoadableClass * obj)
{
// obsolete!
bool retval = false;
SLNode<PostLoadableClass> *list_node = NULL;
for ( list_node = PostLoadList.Head();
retval == false && list_node != NULL;
list_node = list_node->Next())
{
retval = (list_node->Data() == obj);
}
return retval;
}
void SaveLoadSystemClass::Register_Post_Load_Callback(PostLoadableClass * obj)
{
WWASSERT(obj != NULL);
if (!obj->Is_Post_Load_Registered()) {
obj->Set_Post_Load_Registered(true);
PostLoadList.Add_Head(obj);
}
}
void SaveLoadSystemClass::Register_Pointer (void *old_pointer, void *new_pointer)
{
PointerRemapper.Register_Pointer(old_pointer,new_pointer);
}
#ifdef WWDEBUG
void SaveLoadSystemClass::Request_Pointer_Remap (void **pointer_to_convert,const char * file,int line)
{
PointerRemapper.Request_Pointer_Remap(pointer_to_convert,file,line);
}
void SaveLoadSystemClass::Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert,const char * file,int line)
{
PointerRemapper.Request_Ref_Counted_Pointer_Remap(pointer_to_convert,file,line);
}
#else
void SaveLoadSystemClass::Request_Pointer_Remap (void **pointer_to_convert)
{
PointerRemapper.Request_Pointer_Remap(pointer_to_convert);
}
void SaveLoadSystemClass::Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert)
{
PointerRemapper.Request_Ref_Counted_Pointer_Remap(pointer_to_convert);
}
#endif
void SaveLoadSystemClass::Link_Sub_System(SaveLoadSubSystemClass * sys)
{
WWASSERT(sys != NULL);
if (sys != NULL) {
WWASSERT(sys->NextSubSystem == NULL); // sys should never be registered twice!
sys->NextSubSystem = SubSystemListHead;
SubSystemListHead = sys;
}
}
void SaveLoadSystemClass::Unlink_Sub_System(SaveLoadSubSystemClass * sys)
{
WWASSERT(sys != NULL);
SaveLoadSubSystemClass * cursys = SubSystemListHead;
SaveLoadSubSystemClass * prev = NULL;
while (cursys != sys) {
prev = cursys;
cursys = cursys->NextSubSystem;
}
if (prev == NULL) {
SubSystemListHead = sys->NextSubSystem;
} else {
prev->NextSubSystem = sys->NextSubSystem;
}
sys->NextSubSystem = NULL;
}
void SaveLoadSystemClass::Link_Factory(PersistFactoryClass * fact)
{
WWASSERT(fact != NULL);
if (fact != NULL) {
WWASSERT(fact->NextFactory == NULL); // factories should never be registered twice!
fact->NextFactory = FactoryListHead;
FactoryListHead = fact;
}
}
void SaveLoadSystemClass::Unlink_Factory(PersistFactoryClass * fact)
{
WWASSERT(fact != NULL);
PersistFactoryClass * curfact = FactoryListHead;
PersistFactoryClass * prev = NULL;
while (curfact != fact) {
prev = curfact;
curfact = curfact->NextFactory;
}
if (prev == NULL) {
FactoryListHead = fact->NextFactory;
} else {
prev->NextFactory = fact->NextFactory;
}
fact->NextFactory = NULL;
}
void Force_Link_WWSaveLoad (void)
{
FORCE_LINK( Twiddler );
return ;
}

View file

@ -0,0 +1,224 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/saveload.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 4/16/01 4:35p $*
* *
* $Revision:: 11 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef SAVELOAD_H
#define SAVELOAD_H
#include "always.h"
#include "pointerremap.h"
#include "bittype.h"
#include "slist.h"
class RefCountClass;
class SaveLoadSubSystemClass;
class PersistFactoryClass;
class PersistClass;
class PostLoadableClass;
class ChunkSaveClass;
class ChunkLoadClass;
//////////////////////////////////////////////////////////////////////////////////
//
// WWSaveLoad
//
// The WWSaveLoad library is a framework for saving and loading. The main
// goals that we attempted to achieve in designing this system are:
//
// - Save things in a form that could adapt as our code evolves. We want
// to be able to load files which were created with a previous version of the
// application into the current version.
// - Use the same framework throughout all of our libraries with as small an
// impact on them as possible
// - Automate as much of the implementation of save-load as possible.
// - Make this a generic hunk of code which contains no commando-specific parts
// so that it can be used by other applications.
// - Make this system capable of generating the file formats for our level editor,
// the game's level definition file, and player save files.
//
// To achive this, we developed several core concepts:
//
// - Persistant Objects: Most of the state of the game is contained in the objects
// active at any given time. PersistClass is an abstract interface which will allow
// objects to be used with the save-load system. It was also important to keep the
// overhead caused by inheriting this class to an absolute minimum.
//
// - PersistFactories: We need an automatic "virtual-constructor" or "abstract-factory"
// system for all objects that get saved. This is the PersistFactoryClass and the
// automated SimplePersistFactory template. All objects that "persist" are derived from
// PersistClass and all concrete derived PersistClasses have an associated static
// instance of a PersistFactory which handles their saving and construction upon encountering
// them while loading. In certain cases these PersistFactories can also serve as
// a "shortcut" where we cheat by not actually telling the object to save but simply save
// a small piece of data that allows us to recreate an identical object when we load. This
// is used in WW3D sometimes; we just save a render object name and then ask the WW3D asset
// manager to recreate that model for us.
//
// - SaveLoadSubSystems: The overall file structure will be governed by many sub-systems
// (derived from SaveLoadSubSystemClass). The application in-effect creates file formats
// by simply having the sub-systems that it wants write into a file. In this way you can
// achieve things like saving only static data into one file and dynamic into another, etc.
// All persistant objects that get saved will be told to save by some sub-system. For
// example: in Commando, I have a PhysicsDynamicDataSubSystem which saves all of the
// dynamic physics objects. In saving those objects I use the built-in PersistFactories
// and am therefore completely safe from new object types being added to the system, it will just
// automatically work
//
// - Pointer re-mapping: A pointer remaping system is built into the save-load system. There
// are several things that happen in this system. Each object, as it is saved and loaded,
// registers with the system its old address and its new address. (the old address is saved
// and the new address is available once the object is created). This is automated by the
// SimplePersistFactory for all but classes that use multiple inheritance. During the load
// process a table is built which contains all of these pointer pairs (old address, new address).
// Whenever an object loads a pointer, it gives a "pointer to that pointer" to the save load system.
// Then, after all of the objects have been loaded, the system goes through that list of pointers
// and finds them in the pointer pair table. NOTE: use the macros for re-mapping your
// pointers to enable automatic debugging information when you build with WWDEBUG defined.
//
// - Chunks: The file format will be chunk based since that gives us the flexibility to
// add new data and remove obsolete data without necessarily losing the ability
// to read old files. We will use a "high-granularity" of chunks. In many cases, each
// member variable will be in its own chunk for maximum flexibility. To help soften
// the memory usage for this approach, we developed the concept of "micro-chunks".
// Micro-chunks are just like chunks in that they have an id and a size but
// each of these fields are only a single byte and they are never hierarchical.
//
// - ChunkID's: The chunk ID's used by Subsystems and PersistFactories must be unique
// but all others can be considered local to the object that is saving itself. Unique
// ids for the subsystems and factories are achieved by saveloadids.h defining ranges
// of ids for various libraries and then those libraries maintaining a single header
// file internally which gives unique id's within that range to all of their sub-systems
// and persist factories. Never re-use an id or you will break compatibility with older
// versions of your files...
//
//////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
//
// SaveLoadSystemClass
//
//////////////////////////////////////////////////////////////////////////////////
class SaveLoadSystemClass
{
public:
/*
** Save-Load interface. To create a file, ask each sub-system to save itself.
** To load a file just open it and pass it to the load method.
*/
static bool Save (ChunkSaveClass &csave, SaveLoadSubSystemClass & subsystem);
static bool Load (ChunkLoadClass &cload,bool auto_post_load = true);
static bool Post_Load_Processing (void);
/*
** Look up the persist factory for a given chunk id
*/
static PersistFactoryClass * Find_Persist_Factory(uint32 chunk_id);
/*
** Post-Load interface. An object being loaded can ask for a callback after
** all objects have been loaded and pointers re-mapped.
*/
static void Register_Post_Load_Callback(PostLoadableClass * obj);
/*
** Pointer Remapping interface. NOTE: use the macros defined below to
** get debug info with your pointers when doing a debug build.
*/
static void Register_Pointer (void *old_pointer, void *new_pointer);
#ifdef WWDEBUG
static void Request_Pointer_Remap (void **pointer_to_convert,const char * file = NULL,int line = 0);
static void Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert,const char * file = NULL,int line = 0);
#else
static void Request_Pointer_Remap (void **pointer_to_convert);
static void Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert);
#endif
protected:
/*
** Internal SaveLoadSystem functions
*/
static void Register_Sub_System (SaveLoadSubSystemClass * subsys);
static void Unregister_Sub_System (SaveLoadSubSystemClass * subsys);
static SaveLoadSubSystemClass * Find_Sub_System (uint32 chunk_id);
static void Register_Persist_Factory(PersistFactoryClass * factory);
static void Unregister_Persist_Factory(PersistFactoryClass * factory);
static void Link_Sub_System(SaveLoadSubSystemClass * subsys);
static void Unlink_Sub_System(SaveLoadSubSystemClass * subsys);
static void Link_Factory(PersistFactoryClass * factory);
static void Unlink_Factory(PersistFactoryClass * factory);
static bool Is_Post_Load_Callback_Registered(PostLoadableClass * obj);
static SaveLoadSubSystemClass * SubSystemListHead;
static PersistFactoryClass * FactoryListHead;
static PointerRemapClass PointerRemapper;
static SList<PostLoadableClass> PostLoadList;
/*
** these are friends so that they can register themselves at construction time.
*/
friend class SaveLoadSubSystemClass;
friend class PersistFactoryClass;
};
/*
** Use the following macros to automatically enable pointer-remap DEBUG code. Remember that
** in all cases you submit a pointer to the pointer you want re-mapped.
*/
#ifdef WWDEBUG
#define REQUEST_POINTER_REMAP(pp) SaveLoadSystemClass::Request_Pointer_Remap(pp,__FILE__,__LINE__)
#define REQUEST_REF_COUNTED_POINTER_REMAP(pp) SaveLoadSystemClass::Request_Ref_Counted_Pointer_Remap(pp,__FILE__,__LINE__)
#else
#define REQUEST_POINTER_REMAP(pp) SaveLoadSystemClass::Request_Pointer_Remap(pp)
#define REQUEST_REF_COUNTED_POINTER_REMAP(pp) SaveLoadSystemClass::Request_Ref_Counted_Pointer_Remap(pp)
#endif
#endif //SAVELOAD_H

View file

@ -0,0 +1,71 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/saveloadids.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 5/04/01 8:42p $*
* *
* $Revision:: 9 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef SAVELOADIDS_H
#define SAVELOADIDS_H
//////////////////////////////////////////////////////////////////////////////////
//
// Chunk ID Ranges.
// Here are the ranges to use for SubSystem and PersistFactory chunk id's
// and also the chunk id's used by the save-load system itself. If you are
// creating a new library that is going to take advantage of this system,
// create a new range for it here.
//
//////////////////////////////////////////////////////////////////////////////////
enum
{
CHUNKID_SAVELOAD_BEGIN = 0x00000100,
CHUNKID_SAVELOAD_DEFMGR,
CHUNKID_TWIDDLER,
CHUNKID_WW3D_BEGIN = 0x00010000,
CHUNKID_WWPHYS_BEGIN = 0x00020000,
CHUNKID_WWAUDIO_BEGIN = 0x00030000,
CHUNKID_COMBAT_BEGIN = 0x00040000,
CHUNKID_COMMANDO_EDITOR_BEGIN = 0x00050000,
CHUNKID_PHYSTEST_BEGIN = 0x00060000,
CHUNKID_COMMANDO_BEGIN = 0x00070000,
CHUNKID_WWMATH_BEGIN = 0x00080000,
CHUNKID_WWTRANSLATEDB_BEGIN = 0x00090000
};
#endif

View file

@ -0,0 +1,40 @@
/*
** 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/>.
*/
#include "saveloadstatus.h"
#include "mutex.h"
#define MAX_STATUS_TEXT_ID 2
static CriticalSectionClass text_mutex;
static StringClass status_text[MAX_STATUS_TEXT_ID];
void SaveLoadStatus::Set_Status_Text(const char* text,int id)
{
CriticalSectionClass::LockClass m(text_mutex);
WWASSERT(id<MAX_STATUS_TEXT_ID);
status_text[id]=text;
if (id==0) status_text[1]="";
}
StringClass SaveLoadStatus::Get_Status_Text(int id)
{
CriticalSectionClass::LockClass m(text_mutex);
WWASSERT(id<MAX_STATUS_TEXT_ID);
return status_text[id];
}

View file

@ -0,0 +1,38 @@
/*
** 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/>.
*/
#ifndef WWSAVELOADSTATUS_H
#define WWSAVELOADSTATUS_H
#if defined(_MSC_VER)
#pragma once
#endif
#include "always.h"
#include "wwstring.h"
namespace SaveLoadStatus
{
void Set_Status_Text(const char* text,int id);
StringClass Get_Status_Text(int id);
};
#define INIT_STATUS(t) SaveLoadStatus::Set_Status_Text(t,0)
#define INIT_SUB_STATUS(t) SaveLoadStatus::Set_Status_Text(t,1)
#endif

View file

@ -0,0 +1,54 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/saveloadsubsystem.cpp $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 9/09/99 9:50a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "saveloadsubsystem.h"
#include "saveload.h"
SaveLoadSubSystemClass::SaveLoadSubSystemClass(void) :
NextSubSystem(NULL)
{
// All Sub-Systems are automatically registered with the SaveLoadSystem
SaveLoadSystemClass::Register_Sub_System (this);
return ;
}
SaveLoadSubSystemClass::~SaveLoadSubSystemClass (void)
{
SaveLoadSystemClass::Unregister_Sub_System (this);
return ;
}

View file

@ -0,0 +1,95 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/saveloadsubsystem.h $*
* *
* Author:: Greg Hjelstrom *
* *
* $Modtime:: 6/12/00 4:25p $*
* *
* $Revision:: 7 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef SAVELOADSUBSYSTEM_H
#define SAVELOADSUBSYSTEM_H
#include "always.h"
#include "bittype.h"
#include "postloadable.h"
class ChunkLoadClass;
class ChunkSaveClass;
//////////////////////////////////////////////////////////////////////////////////
//
// SaveLoadSubSystemClass
//
// Each SaveLoadSubSystem will automatically be registered with the SaveLoadSystem
// at construction time. The plan is to have a single static instance of each
// sub-system so that it automatically registers when the global constructors
// are executed.
//
// When an application wants to create a file it does so by asking the
// SaveLoadSystem to save the particular set of SaveLoadSubSystems that contain
// that data.
//
//////////////////////////////////////////////////////////////////////////////////
class SaveLoadSubSystemClass : public PostLoadableClass
{
public:
SaveLoadSubSystemClass (void);
virtual ~SaveLoadSubSystemClass (void);
virtual uint32 Chunk_ID (void) const = 0;
protected:
virtual bool Contains_Data(void) const { return true; }
virtual bool Save (ChunkSaveClass &csave) = 0;
virtual bool Load (ChunkLoadClass &cload) = 0;
virtual const char* Name() const = 0;
private:
SaveLoadSubSystemClass * NextSubSystem; // managed by SaveLoadSystem
friend class SaveLoadSystemClass;
};
#endif

View file

@ -0,0 +1,86 @@
/*
** 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/>.
*/
#ifndef __SIMPLE_DEFINITION_FACTORY_H
#define __SIMPLE_DEFINITION_FACTORY_H
#include "definitionfactory.h"
//////////////////////////////////////////////////////////////////////////////////
//
// SimpleDefinitionFactoryClass
//
// Template class to automate the creation of simple definition factories.
//
//////////////////////////////////////////////////////////////////////////////////
template<class T, int class_id, char *name>
class SimpleDefinitionFactoryClass : public DefinitionFactoryClass
{
public:
//////////////////////////////////////////////////////////////
// Public constructors/destructors
//////////////////////////////////////////////////////////////
SimpleDefinitionFactoryClass (bool is_displayed = true) :
IsDisplayed (is_displayed) {}
//////////////////////////////////////////////////////////////
// Public methods
//////////////////////////////////////////////////////////////
virtual DefinitionClass * Create (void) const;
virtual const char * Get_Name (void) const;
virtual uint32 Get_Class_ID (void) const;
virtual bool Is_Displayed (void) const { return IsDisplayed; }
protected:
//////////////////////////////////////////////////////////////
// Protected member data
//////////////////////////////////////////////////////////////
bool IsDisplayed;
};
template<class T, int class_id, char *name>
inline DefinitionClass *
SimpleDefinitionFactoryClass<T, class_id, name>::Create (void) const
{
return W3DNEW T;
}
template<class T, int class_id, char *name>
inline const char *
SimpleDefinitionFactoryClass<T, class_id, name>::Get_Name (void) const
{
return name;
}
template<class T, int class_id, char *name>
inline uint32
SimpleDefinitionFactoryClass<T, class_id, name>::Get_Class_ID (void) const
{
return class_id;
}
#define DECLARE_DEFINITION_FACTORY(_class, _id, _name) \
char _class ## Name[] = _name; \
SimpleDefinitionFactoryClass<_class, _id, _class ## Name> \
#endif //__SIMPLE_DEFINITION_FACTORY_H

View file

@ -0,0 +1,247 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/simpleparameter.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 7/16/01 11:12a $*
* *
* $Revision:: 17 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __SIMPLE_PARAMETER_H
#define __SIMPLE_PARAMETER_H
#include "always.h"
#include "parameter.h"
#include "vector2.h"
#include "vector3.h"
#include "matrix3d.h"
#include "rect.h"
#include <float.h>
//////////////////////////////////////////////////////////////////////////////////
//
// SimpleParameterClass
//
//////////////////////////////////////////////////////////////////////////////////
template <class T, ParameterClass::Type type>
class SimpleParameterClass : public ParameterClass
{
public:
///////////////////////////////////////////////////////////////////////
// Public constructors/destructors
///////////////////////////////////////////////////////////////////////
SimpleParameterClass (void *data, const char *name);
//////////////////////////////////////////////////////////////////////////////
// Public operators
//////////////////////////////////////////////////////////////////////////////
bool operator== (const ParameterClass &src);
///////////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////////
const T & Get_Value (void) const;
void Set_Value (const T &new_value);
// From Parameter class
ParameterClass::Type Get_Type (void) const;
void Copy_Value (const ParameterClass &src);
private:
///////////////////////////////////////////////////////////////////////
// Private member data
///////////////////////////////////////////////////////////////////////
T * m_Data;
T m_Min;
T m_Max;
};
//////////////////////////////////////////////////////////////////////////////////
// SimpleParameterClass
//////////////////////////////////////////////////////////////////////////////////
template <class T, ParameterClass::Type type> inline
SimpleParameterClass<T, type>::SimpleParameterClass (void *data, const char *name)
{
Set_Name (name);
m_Data = (T *)data;
return ;
}
//////////////////////////////////////////////////////////////////////////////////
// Get_Value
//////////////////////////////////////////////////////////////////////////////////
template <class T, ParameterClass::Type type> inline bool
SimpleParameterClass<T, type>::operator== (const ParameterClass &src)
{
bool retval = false;
if (src.Get_Type () == Get_Type ()) {
retval = ((*m_Data) == *(((const SimpleParameterClass &)src).m_Data));
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
// Get_Value
//////////////////////////////////////////////////////////////////////////////////
template <class T, ParameterClass::Type type> inline const T &
SimpleParameterClass<T, type>::Get_Value (void) const
{
return (*m_Data);
}
//////////////////////////////////////////////////////////////////////////////////
// Set_Value
//////////////////////////////////////////////////////////////////////////////////
template <class T, ParameterClass::Type type> inline void
SimpleParameterClass<T, type>::Set_Value (const T &new_value)
{
(*m_Data) = new_value;
Set_Modified ();
return ;
}
//////////////////////////////////////////////////////////////////////////////////
// Get_Type
//////////////////////////////////////////////////////////////////////////////////
template <class T, ParameterClass::Type type> inline ParameterClass::Type
SimpleParameterClass<T, type>::Get_Type (void) const
{
return type;
}
//////////////////////////////////////////////////////////////////////////////////
// Copy_Value
//////////////////////////////////////////////////////////////////////////////////
template <class T, ParameterClass::Type type> inline void
SimpleParameterClass<T, type>::Copy_Value (const ParameterClass &src)
{
if (Get_Type () == src.Get_Type ()) {
(*m_Data) = ((SimpleParameterClass<T, type> &)src).Get_Value ();
}
ParameterClass::Copy_Value (src);
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Simple parameter types
//
//////////////////////////////////////////////////////////////////////////////////
typedef SimpleParameterClass<bool, ParameterClass::TYPE_BOOL> BoolParameterClass;
typedef SimpleParameterClass<Vector2, ParameterClass::TYPE_VECTOR2> Vector2ParameterClass;
typedef SimpleParameterClass<Vector3, ParameterClass::TYPE_VECTOR3> Vector3ParameterClass;
typedef SimpleParameterClass<Matrix3D, ParameterClass::TYPE_MATRIX3D> Matrix3DParameterClass;
typedef SimpleParameterClass<RectClass,ParameterClass::TYPE_RECT> RectParameterClass;
typedef SimpleParameterClass<Vector3, ParameterClass::TYPE_COLOR > ColorParameterClass;
typedef SimpleParameterClass<int, ParameterClass::TYPE_STRINGSDB_ID> StringsDBEntryParameterClass;
//////////////////////////////////////////////////////////////////////////////////
//
// RangedParameterClass
//
// Extends simple paramter types so they can have minimum/maximum values.
//
//////////////////////////////////////////////////////////////////////////////////
template <class T, ParameterClass::Type type>
class RangedParameterClass : public SimpleParameterClass<T, type>
{
public:
///////////////////////////////////////////////////////////////////////
// Public constructors/destructors
///////////////////////////////////////////////////////////////////////
RangedParameterClass (void *data, const char *name)
: SimpleParameterClass<T, type> (data, name) { }
///////////////////////////////////////////////////////////////////////
// Public methods
///////////////////////////////////////////////////////////////////////
void Set_Range (const T &min, const T &max) { m_Min = min; m_Max = max; }
const T & Get_Min (void) const { return m_Min; }
const T & Get_Max (void) const { return m_Max; }
private:
///////////////////////////////////////////////////////////////////////
// Private member data
///////////////////////////////////////////////////////////////////////
T m_Min;
T m_Max;
};
//////////////////////////////////////////////////////////////////////////////////
// IntParameterClass
//////////////////////////////////////////////////////////////////////////////////
class IntParameterClass : public RangedParameterClass<int, ParameterClass::TYPE_INT>
{
public:
IntParameterClass (void *data, const char *name)
: RangedParameterClass<int, ParameterClass::TYPE_INT> (data, name)
{ Set_Range (-1000000000L, 1000000000L); }
};
//////////////////////////////////////////////////////////////////////////////////
// FloatParameterClass
//////////////////////////////////////////////////////////////////////////////////
class FloatParameterClass : public RangedParameterClass<float, ParameterClass::TYPE_FLOAT>
{
public:
FloatParameterClass (void *data, const char *name)
: RangedParameterClass<float, ParameterClass::TYPE_FLOAT> (data, name)
{ Set_Range (-100000.0F, 100000.0F); }
};
//////////////////////////////////////////////////////////////////////////////////
// AngleParameterClass
//////////////////////////////////////////////////////////////////////////////////
class AngleParameterClass : public RangedParameterClass<float, ParameterClass::TYPE_ANGLE>
{
public:
AngleParameterClass (void *data, const char *name)
: RangedParameterClass<float, ParameterClass::TYPE_ANGLE> (data, name)
{ Set_Range (0.0F, 6.283185307F); }
};
#endif //__SIMPLE_PARAMETER_H

View file

@ -0,0 +1,279 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/twiddler.cpp $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 6/27/00 2:34p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "twiddler.h"
#include "random.h"
#include "saveloadids.h"
#include "simpledefinitionfactory.h"
#include "persistfactory.h"
#include "win.h"
#include "wwhack.h"
DECLARE_FORCE_LINK( Twiddler )
//////////////////////////////////////////////////////////////////////////////////
// Constants
//////////////////////////////////////////////////////////////////////////////////
enum
{
CHUNKID_VARIABLES = 0x00000100,
CHUNKID_BASE_CLASS = 0x00000200,
};
enum
{
VARID_DEFINTION_ID = 0x01,
VARID_INDIRECT_CLASSID,
};
//////////////////////////////////////////////////////////////////////////////////
//
// Static factories
//
//////////////////////////////////////////////////////////////////////////////////
DECLARE_DEFINITION_FACTORY(TwiddlerClass, CLASSID_TWIDDLERS, "Twiddler") _TwiddlerFactory;
SimplePersistFactoryClass<TwiddlerClass, CHUNKID_TWIDDLER> _TwiddlerPersistFactory;
//////////////////////////////////////////////////////////////////////////////////
//
// TwiddlerClass
//
//////////////////////////////////////////////////////////////////////////////////
TwiddlerClass::TwiddlerClass (void)
: m_IndirectClassID (0)
{
CLASSID_DEFIDLIST_PARAM (TwiddlerClass, m_DefinitionList, 0, m_IndirectClassID, "Preset List");
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// ~TwiddlerClass
//
//////////////////////////////////////////////////////////////////////////////////
TwiddlerClass::~TwiddlerClass (void)
{
return ;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Twiddle
//
//////////////////////////////////////////////////////////////////////////////////
DefinitionClass *
TwiddlerClass::Twiddle (void) const
{
DefinitionClass *definition = NULL;
if (m_DefinitionList.Count () > 0) {
//
// Get a random index into our definition list
//
RandomClass randomizer (::GetTickCount ());
int index = randomizer (0, m_DefinitionList.Count () - 1);
//
// Lookup the definition this entry represents
//
int def_id = m_DefinitionList[index];
definition = DefinitionMgrClass::Find_Definition (def_id);
}
return definition;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Create
//
//////////////////////////////////////////////////////////////////////////////////
PersistClass *
TwiddlerClass::Create (void) const
{
PersistClass *retval = NULL;
//
// Pick a random definition
//
DefinitionClass *definition = Twiddle ();
if (definition != NULL) {
//
// Indirect the creation to the definition we randomly selected
//
retval = definition->Create ();
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Get_Factory
//
//////////////////////////////////////////////////////////////////////////////////
const PersistFactoryClass &
TwiddlerClass::Get_Factory (void) const
{
return _TwiddlerPersistFactory;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Save
//
//////////////////////////////////////////////////////////////////////////////////
bool
TwiddlerClass::Save (ChunkSaveClass &csave)
{
bool retval = true;
csave.Begin_Chunk (CHUNKID_VARIABLES);
retval &= Save_Variables (csave);
csave.End_Chunk ();
csave.Begin_Chunk (CHUNKID_BASE_CLASS);
retval &= DefinitionClass::Save (csave);
csave.End_Chunk ();
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Load
//
//////////////////////////////////////////////////////////////////////////////////
bool
TwiddlerClass::Load (ChunkLoadClass &cload)
{
bool retval = true;
while (cload.Open_Chunk ()) {
switch (cload.Cur_Chunk_ID ()) {
case CHUNKID_VARIABLES:
retval &= Load_Variables (cload);
break;
case CHUNKID_BASE_CLASS:
retval &= DefinitionClass::Load (cload);
break;
}
cload.Close_Chunk ();
}
return retval;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Save_Variables
//
//////////////////////////////////////////////////////////////////////////////////
bool
TwiddlerClass::Save_Variables (ChunkSaveClass &csave)
{
WRITE_MICRO_CHUNK (csave, VARID_INDIRECT_CLASSID, m_IndirectClassID)
for (int index = 0; index < m_DefinitionList.Count (); index ++) {
//
// Save this definition ID to the chunk
//
int def_id = m_DefinitionList[index];
WRITE_MICRO_CHUNK (csave, VARID_DEFINTION_ID, def_id)
}
return true;
}
//////////////////////////////////////////////////////////////////////////////////
//
// Load_Variables
//
//////////////////////////////////////////////////////////////////////////////////
bool
TwiddlerClass::Load_Variables (ChunkLoadClass &cload)
{
//
// Start fresh
//
m_DefinitionList.Delete_All ();
//
// Loop through all the microchunks that define the variables
//
while (cload.Open_Micro_Chunk ()) {
switch (cload.Cur_Micro_Chunk_ID ()) {
READ_MICRO_CHUNK (cload, VARID_INDIRECT_CLASSID, m_IndirectClassID)
case VARID_DEFINTION_ID:
{
//
// Read the definition ID from the chunk and add it
// to our list
//
int def_id = 0;
cload.Read (&def_id, sizeof (def_id));
m_DefinitionList.Add (def_id);
}
break;
}
cload.Close_Micro_Chunk ();
}
return true;
}

View file

@ -0,0 +1,130 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/twiddler.h $*
* *
* Author:: Patrick Smith *
* *
* $Modtime:: 6/27/00 2:34p $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef __TWIDDLER_H
#define __TWIDDLER_H
#include "definition.h"
#include "definitionclassids.h"
//////////////////////////////////////////////////////////////////////////////////
//
// TwiddlerClass
//
//////////////////////////////////////////////////////////////////////////////////
class TwiddlerClass : public DefinitionClass
{
public:
/////////////////////////////////////////////////////////////////////
// Editable interface requirements
/////////////////////////////////////////////////////////////////////
DECLARE_EDITABLE(TwiddlerClass, DefinitionClass);
/////////////////////////////////////////////////////////////////////
// Public constructors/destructors
/////////////////////////////////////////////////////////////////////
TwiddlerClass (void);
virtual ~TwiddlerClass (void);
/////////////////////////////////////////////////////////////////////
// Public methods
/////////////////////////////////////////////////////////////////////
//
// Type identification
//
uint32 Get_Class_ID (void) const { return CLASSID_TWIDDLERS; }
PersistClass * Create (void) const;
//
// From PersistClass
//
bool Save (ChunkSaveClass &csave);
bool Load (ChunkLoadClass &cload);
const PersistFactoryClass & Get_Factory (void) const;
//
// Twiddler specific
//
virtual DefinitionClass * Twiddle (void) const;
virtual uint32 Get_Indirect_Class_ID (void) const;
virtual void Set_Indirect_Class_ID (uint32 class_id);
private:
/////////////////////////////////////////////////////////////////////
// Private methods
/////////////////////////////////////////////////////////////////////
bool Save_Variables (ChunkSaveClass &csave);
bool Load_Variables (ChunkLoadClass &cload);
/////////////////////////////////////////////////////////////////////
// Private member data
/////////////////////////////////////////////////////////////////////
uint32 m_IndirectClassID;
DynamicVectorClass<int> m_DefinitionList;
};
/////////////////////////////////////////////////////////////////////
// Get_Indirect_Class_ID
/////////////////////////////////////////////////////////////////////
inline uint32
TwiddlerClass::Get_Indirect_Class_ID (void) const
{
return m_IndirectClassID;
}
/////////////////////////////////////////////////////////////////////
// Set_Indirect_Class_ID
/////////////////////////////////////////////////////////////////////
inline void
TwiddlerClass::Set_Indirect_Class_ID (uint32 class_id)
{
m_IndirectClassID = class_id;
return ;
}
#endif //__TWIDDLER_H

View file

@ -0,0 +1,52 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : wwsaveload *
* *
* $Archive:: /Commando/Code/wwsaveload/wwsaveload.cpp $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 3/28/00 9:18a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "wwsaveload.h"
#include "definitionmgr.h"
void WWSaveLoad::Init(void)
{
}
void WWSaveLoad::Shutdown(void)
{
_TheDefinitionMgr.Free_Definitions();
}

View file

@ -0,0 +1,331 @@
# Microsoft Developer Studio Project File - Name="wwsaveload" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=wwsaveload - Win32 DebugW3D
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "wwsaveload.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "wwsaveload.mak" CFG="wwsaveload - Win32 DebugW3D"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "wwsaveload - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "wwsaveload - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "wwsaveload - Win32 Profile" (based on "Win32 (x86) Static Library")
!MESSAGE "wwsaveload - Win32 ProfileE" (based on "Win32 (x86) Static Library")
!MESSAGE "wwsaveload - Win32 DebugE" (based on "Win32 (x86) Static Library")
!MESSAGE "wwsaveload - Win32 Internal" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Commando/Code/wwsaveload", RPFCAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "wwsaveload - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /G6 /MD /W3 /WX /GX /O2 /Ob2 /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D WINVER=0x400 /D "_WINDOWS" /D "NDEBUG" /D "WIN32" /D "IG_DEBUG_STACKTRACE" /Fr /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\..\..\Lib\WWSaveLoad.lib"
!ELSEIF "$(CFG)" == "wwsaveload - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /G6 /MDd /W3 /WX /GX /Zi /O2 /Ob2 /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D "_DEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32" /Fr /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\..\..\Lib\WWSaveLoadDebug.lib"
!ELSEIF "$(CFG)" == "wwsaveload - Win32 Profile"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Profile"
# PROP BASE Intermediate_Dir "Profile"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Profile"
# PROP Intermediate_Dir "Profile"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MD /W3 /WX /Gm /GX /Zi /O2 /Op /Ob2 /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D "NDEBUG" /D "WWDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32" /YX /FD /c
# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo /out:"..\..\..\Lib\WWSaveLoadProfile.lib"
!ELSEIF "$(CFG)" == "wwsaveload - Win32 ProfileE"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "ProfileE"
# PROP BASE Intermediate_Dir "ProfileE"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "ProfileE"
# PROP Intermediate_Dir "ProfileE"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /Gm /GX /Zi /Od /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D "NDEBUG" /D "WWDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32" /YX /FD /GZ /c
# ADD CPP /nologo /MD /W3 /WX /Gm /GX /Zi /Od /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D "NDEBUG" /D "WWDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32" /D "PARAM_EDITING_ON" /YX /FD /GZ /c
# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo /out:"..\Libs\profile\wwsaveload.lib"
# ADD LIB32 /nologo /out:"..\..\..\Lib\WWSaveLoadProfileE.lib"
!ELSEIF "$(CFG)" == "wwsaveload - Win32 DebugE"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "DebugE"
# PROP BASE Intermediate_Dir "DebugE"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "DebugE"
# PROP Intermediate_Dir "DebugE"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D "_DEBUG" /D "WWDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /WX /Gm /GX /ZI /Od /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D "_DEBUG" /D "WWDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32" /D "PARAM_EDITING_ON" /YX /FD /GZ /c
# SUBTRACT CPP /Fr
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo /out:"..\Libs\debug\wwsaveload.lib"
# ADD LIB32 /nologo /out:"..\..\..\Lib\WWSaveLoadDebugE.lib"
!ELSEIF "$(CFG)" == "wwsaveload - Win32 Internal"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Internal"
# PROP BASE Intermediate_Dir "Internal"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Internal"
# PROP Intermediate_Dir "Internal"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MD /W3 /GX /O2 /Ob2 /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D "NDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32" /YX /FD /c
# ADD CPP /nologo /G6 /MD /W3 /WX /GX /Zi /O2 /I "..\wwlib" /I "..\wwdebug" /I "..\wwmath" /D "NDEBUG" /D WINVER=0x400 /D "_WINDOWS" /D "WIN32" /D "_INTERNAL" /Fr /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo /out:"..\..\..\Lib\WWSaveLoad.lib"
# ADD LIB32 /nologo /out:"..\..\..\Lib\WWSaveLoadInternal.lib"
!ENDIF
# Begin Target
# Name "wwsaveload - Win32 Release"
# Name "wwsaveload - Win32 Debug"
# Name "wwsaveload - Win32 Profile"
# Name "wwsaveload - Win32 ProfileE"
# Name "wwsaveload - Win32 DebugE"
# Name "wwsaveload - Win32 Internal"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\definition.cpp
# End Source File
# Begin Source File
SOURCE=.\definitionfactory.cpp
# End Source File
# Begin Source File
SOURCE=.\definitionfactorymgr.cpp
# End Source File
# Begin Source File
SOURCE=.\definitionmgr.cpp
# End Source File
# Begin Source File
SOURCE=.\parameter.cpp
# End Source File
# Begin Source File
SOURCE=.\persistfactory.cpp
# End Source File
# Begin Source File
SOURCE=.\pointerremap.cpp
# End Source File
# Begin Source File
SOURCE=.\saveload.cpp
# End Source File
# Begin Source File
SOURCE=.\saveloadstatus.cpp
# End Source File
# Begin Source File
SOURCE=.\saveloadsubsystem.cpp
# End Source File
# Begin Source File
SOURCE=.\twiddler.cpp
# End Source File
# Begin Source File
SOURCE=.\wwsaveload.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\definition.h
# End Source File
# Begin Source File
SOURCE=.\definitionclassids.h
# End Source File
# Begin Source File
SOURCE=.\definitionfactory.h
# End Source File
# Begin Source File
SOURCE=.\definitionfactorymgr.h
# End Source File
# Begin Source File
SOURCE=.\definitionmgr.h
# End Source File
# Begin Source File
SOURCE=.\editable.h
# End Source File
# Begin Source File
SOURCE=.\parameter.h
# End Source File
# Begin Source File
SOURCE=.\parameterlist.h
# End Source File
# Begin Source File
SOURCE=.\parametertypes.h
# End Source File
# Begin Source File
SOURCE=.\persist.h
# End Source File
# Begin Source File
SOURCE=.\persistfactory.h
# End Source File
# Begin Source File
SOURCE=.\pointerremap.h
# End Source File
# Begin Source File
SOURCE=.\postloadable.h
# End Source File
# Begin Source File
SOURCE=.\saveload.h
# End Source File
# Begin Source File
SOURCE=.\saveloadids.h
# End Source File
# Begin Source File
SOURCE=.\saveloadstatus.h
# End Source File
# Begin Source File
SOURCE=.\saveloadstatus.h
# End Source File
# Begin Source File
SOURCE=.\saveloadsubsystem.h
# End Source File
# Begin Source File
SOURCE=.\simpledefinitionfactory.h
# End Source File
# Begin Source File
SOURCE=.\simpleparameter.h
# End Source File
# Begin Source File
SOURCE=.\twiddler.h
# End Source File
# Begin Source File
SOURCE=.\wwsaveload.h
# End Source File
# End Group
# End Target
# End Project

View file

@ -0,0 +1,60 @@
/*
** 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 O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : WWSaveLoad *
* *
* $Archive:: /Commando/Code/wwsaveload/wwsaveload.h $*
* *
* Original Author:: Greg Hjelstrom *
* *
* $Author:: Greg_h $*
* *
* $Modtime:: 3/28/00 9:20a $*
* *
* $Revision:: 2 $*
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#if defined(_MSC_VER)
#pragma once
#endif
#ifndef WWSAVELOAD_H
#define WWSAVELOAD_H
/**
** WWSaveLoad
** The Init and Shutdown functions should be called once by the App.
*/
class WWSaveLoad
{
public:
static void Init(void);
static void Shutdown(void);
};
#endif