Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
saveload.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** 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 ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WWSaveLoad *
24 * *
25 * $Archive:: /Commando/Code/wwsaveload/saveload.cpp $*
26 * *
27 * Author:: Greg Hjelstrom *
28 * *
29 * $Modtime:: 12/09/01 6:42p $*
30 * *
31 * $Revision:: 19 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
36
37
38#include "saveload.h"
39#include "saveloadsubsystem.h"
40#include "persist.h"
41#include "persistfactory.h"
42#include "chunkio.h"
43#include "wwdebug.h"
44#include "saveloadstatus.h"
45#include "wwhack.h"
46#include "wwprofile.h"
47
48#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union
49#include <windows.h>
50#include "systimer.h"
51
52
57
58
59
61{
62 bool ok = true;
63
64 if (subsystem.Contains_Data()) {
65 csave.Begin_Chunk (subsystem.Chunk_ID ());
66 ok &= subsystem.Save (csave);
67 csave.End_Chunk ();
68 }
69
70 return ok;
71}
72
73bool SaveLoadSystemClass::Load (ChunkLoadClass &cload,bool auto_post_load)
74{
75 WWLOG_PREPARE_TIME_AND_MEMORY("SaveLoadSystemClass::Load");
76 PointerRemapper.Reset();
77 WWLOG_INTERMEDIATE("PointerRemapper.Reset()");
78 bool ok = true;
79
80 // Load each chunk we encounter and link the manager into the PostLoad list
81 while (cload.Open_Chunk ()) {
82 SaveLoadStatus::Inc_Status_Count(); // Count the sub systems loaded
84 WWLOG_INTERMEDIATE("Find_Sub_System");
85 if (sys != NULL) {
86//WWRELEASE_SAY((" Name: %s\n",sys->Name()));
87 INIT_SUB_STATUS(sys->Name());
88 ok &= sys->Load(cload);
90 }
91 cload.Close_Chunk();
92 }
93
94 // Process all of the pointer remap requests
95 PointerRemapper.Process();
96 WWLOG_INTERMEDIATE("PointerRemapper.Process()");
97 PointerRemapper.Reset();
98 WWLOG_INTERMEDIATE("PointerRemapper.Reset()");
99
100 // Call PostLoad on each PersistClass that wanted post-load
101 if (auto_post_load) {
103 }
104 WWLOG_INTERMEDIATE("PostLoadProcessing");
105
106 return ok;
107}
108
109// Nework update macro for post loader.
110#define UPDATE_NETWORK \
111 if (network_callback) { \
112 unsigned long time2 = TIMEGETTIME(); \
113 if (time2 - time > 20) { \
114 network_callback(); \
115 time = time2; \
116 } \
117 } \
118
119bool SaveLoadSystemClass::Post_Load_Processing (void(*network_callback)(void))
120{
121 unsigned long time = TIMEGETTIME();
122
123 // Call PostLoad on each PersistClass that wanted post-load
124 PostLoadableClass * obj = PostLoadList.Remove_Head();
125 while (obj) {
127 obj->On_Post_Load();
128 obj->Set_Post_Load_Registered(false);
129 obj = PostLoadList.Remove_Head();
130 }
131
132 return true;
133}
134
140
141
147
148
150{
151 // TODO: need a d-s that gives fast searching based on chunk_id!!
153 for ( sys = SubSystemListHead; sys != NULL; sys = sys->NextSubSystem ) {
154 if ( sys->Chunk_ID() == chunk_id ) {
155 break;
156 }
157 }
158 return sys;
159}
160
162{
163 WWASSERT(factory != NULL);
164 Link_Factory(factory);
165}
166
172
174{
175 // TODO: need a d-s that gives fast searching based on chunk_id!!
176 PersistFactoryClass * fact;
177 for ( fact = FactoryListHead; fact != NULL; fact = fact->NextFactory ) {
178 if ( fact->Chunk_ID() == chunk_id ) {
179 break;
180 }
181 }
182 return fact;
183}
184
186{
187 // obsolete!
188 bool retval = false;
189
190 SLNode<PostLoadableClass> *list_node = NULL;
191 for ( list_node = PostLoadList.Head();
192 retval == false && list_node != NULL;
193 list_node = list_node->Next())
194 {
195 retval = (list_node->Data() == obj);
196 }
197
198 return retval;
199}
200
202{
203 WWASSERT(obj != NULL);
204 if (!obj->Is_Post_Load_Registered()) {
205 obj->Set_Post_Load_Registered(true);
206 PostLoadList.Add_Head(obj);
207 }
208}
209
210void SaveLoadSystemClass::Register_Pointer (void *old_pointer, void *new_pointer)
211{
212 PointerRemapper.Register_Pointer(old_pointer,new_pointer);
213}
214
215#ifdef WWDEBUG
216
217void SaveLoadSystemClass::Request_Pointer_Remap (void **pointer_to_convert,const char * file,int line)
218{
219 PointerRemapper.Request_Pointer_Remap(pointer_to_convert,file,line);
220}
221
222void SaveLoadSystemClass::Request_Ref_Counted_Pointer_Remap (RefCountClass **pointer_to_convert,const char * file,int line)
223{
224 PointerRemapper.Request_Ref_Counted_Pointer_Remap(pointer_to_convert,file,line);
225}
226
227#else
228
229void SaveLoadSystemClass::Request_Pointer_Remap (void **pointer_to_convert)
230{
231 PointerRemapper.Request_Pointer_Remap(pointer_to_convert);
232}
233
235{
236 PointerRemapper.Request_Ref_Counted_Pointer_Remap(pointer_to_convert);
237}
238
239#endif
240
242{
243 WWASSERT(sys != NULL);
244 if (sys != NULL) {
245 WWASSERT(sys->NextSubSystem == NULL); // sys should never be registered twice!
246 sys->NextSubSystem = SubSystemListHead;
247 SubSystemListHead = sys;
248 }
249}
250
252{
253 WWASSERT(sys != NULL);
256
257 while (cursys != sys) {
258 prev = cursys;
259 cursys = cursys->NextSubSystem;
260 }
261
262 if (prev == NULL) {
263 SubSystemListHead = sys->NextSubSystem;
264 } else {
265 prev->NextSubSystem = sys->NextSubSystem;
266 }
267
268 sys->NextSubSystem = NULL;
269}
270
271
273{
274 WWASSERT(fact != NULL);
275 if (fact != NULL) {
276 WWASSERT(fact->NextFactory == NULL); // factories should never be registered twice!
277 fact->NextFactory = FactoryListHead;
278 FactoryListHead = fact;
279 }
280}
281
283{
284 WWASSERT(fact != NULL);
285
287 PersistFactoryClass * prev = NULL;
288
289 while (curfact != fact) {
290 prev = curfact;
291 curfact = curfact->NextFactory;
292 }
293
294 if (prev == NULL) {
295 FactoryListHead = fact->NextFactory;
296 } else {
297 prev->NextFactory = fact->NextFactory;
298 }
299
300 fact->NextFactory = NULL;
301}
302
304{
305 FORCE_LINK( Twiddler );
306 return ;
307}
#define NULL
Definition BaseType.h:92
#define WWASSERT
unsigned long uint32
Definition bittype.h:46
bool Close_Chunk()
Definition chunkio.cpp:448
uint32 Cur_Chunk_ID()
Definition chunkio.cpp:484
bool Open_Chunk()
Definition chunkio.cpp:412
bool Begin_Chunk(uint32 id)
Definition chunkio.cpp:108
bool End_Chunk()
Definition chunkio.cpp:148
virtual uint32 Chunk_ID(void) const =0
void Request_Pointer_Remap(void **pointer_to_convert)
bool Is_Post_Load_Registered(void)
void Set_Post_Load_Registered(bool onoff)
virtual void On_Post_Load(void)
SLNode< T > * Next(void)
Definition SLNODE.H:99
T * Data(void)
Definition SLNODE.H:100
Definition SLIST.H:67
virtual uint32 Chunk_ID(void) const =0
virtual const char * Name() const =0
virtual bool Save(ChunkSaveClass &csave)=0
virtual bool Contains_Data(void) const
virtual bool Load(ChunkLoadClass &cload)=0
static void Link_Sub_System(SaveLoadSubSystemClass *subsys)
Definition saveload.cpp:241
static PointerRemapClass PointerRemapper
Definition saveload.h:198
static void Unlink_Factory(PersistFactoryClass *factory)
Definition saveload.cpp:282
friend class SaveLoadSubSystemClass
Definition saveload.h:204
static void Unlink_Sub_System(SaveLoadSubSystemClass *subsys)
Definition saveload.cpp:251
static void Register_Pointer(void *old_pointer, void *new_pointer)
Definition saveload.cpp:210
static void Register_Persist_Factory(PersistFactoryClass *factory)
Definition saveload.cpp:161
static SaveLoadSubSystemClass * Find_Sub_System(uint32 chunk_id)
Definition saveload.cpp:149
friend class PersistFactoryClass
Definition saveload.h:205
static PersistFactoryClass * FactoryListHead
Definition saveload.h:197
static bool Save(ChunkSaveClass &csave, SaveLoadSubSystemClass &subsystem)
Definition saveload.cpp:60
static bool Is_Post_Load_Callback_Registered(PostLoadableClass *obj)
Definition saveload.cpp:185
static void Unregister_Sub_System(SaveLoadSubSystemClass *subsys)
Definition saveload.cpp:142
static void Link_Factory(PersistFactoryClass *factory)
Definition saveload.cpp:272
static void Register_Sub_System(SaveLoadSubSystemClass *subsys)
Definition saveload.cpp:135
static PersistFactoryClass * Find_Persist_Factory(uint32 chunk_id)
Definition saveload.cpp:173
static SaveLoadSubSystemClass * SubSystemListHead
Definition saveload.h:196
static bool Load(ChunkLoadClass &cload, bool auto_post_load=true)
Definition saveload.cpp:73
static bool Post_Load_Processing(void(*network_callback)(void))
Definition saveload.cpp:119
static void Register_Post_Load_Callback(PostLoadableClass *obj)
Definition saveload.cpp:201
static SList< PostLoadableClass > PostLoadList
Definition saveload.h:199
static void Request_Pointer_Remap(void **pointer_to_convert)
Definition saveload.cpp:229
static void Unregister_Persist_Factory(PersistFactoryClass *factory)
Definition saveload.cpp:167
static void Request_Ref_Counted_Pointer_Remap(RefCountClass **pointer_to_convert)
Definition saveload.cpp:234
void Inc_Status_Count(void)
else return(RetVal)
void Force_Link_WWSaveLoad(void)
Definition saveload.cpp:303
#define INIT_SUB_STATUS(t)
#define TIMEGETTIME
Definition systimer.h:44
#define UPDATE_NETWORK
#define FORCE_LINK(module)
Definition wwhack.h:47
#define WWLOG_PREPARE_TIME_AND_MEMORY(t)
Definition wwprofile.h:322
#define WWLOG_INTERMEDIATE(t)
Definition wwprofile.h:323