@@ -162,49 +162,59 @@ DEFINE_HOOK(0x67FD26, LoadOptionsClass_ReadSaveInfo_SGInSubdir, 0x5)
162162 return 0 ;
163163}
164164
165- // issue #18
166- #define NEW_SAVEGAME_META_INFO
167- #ifdef NEW_SAVEGAME_META_INFO
168165#include < HouseClass.h>
169166#include < AnimClass.h>
170167
171168namespace SavedGames
172169{
173- // What do you need, man?
170+ // issue #18
171+ struct CampaignID
172+ {
173+ uint64_t Number;
174+
175+ explicit CampaignID () :
176+ Number { SessionClass::IsCampaign () ? (uint64_t )Spawner::GetConfig ()->CampaignID : 0 }
177+ {
178+ }
179+
180+ CampaignID (noinit_t ()) { }
181+ };
182+
183+ // More fun
174184 struct ExtraMetaInfo
175185 {
176- int CampaignID { - 1 } ;
186+ int CurrentFrame ;
177187 int PlayerCount;
178188 int TechnoCount;
179189 int AnimCount;
180- int CurrentFrame;
181-
190+
182191 explicit ExtraMetaInfo ()
192+ :CurrentFrame { Unsorted::CurrentFrame }
193+ , PlayerCount { HouseClass::Array->Count }
194+ , TechnoCount { TechnoClass::Array->Count }
195+ , AnimCount { AnimClass::Array->Count }
183196 {
184- if (SessionClass::IsCampaign ())
185- CampaignID = Spawner::GetConfig ()->CampaignID ;
186- PlayerCount = HouseClass::Array->Count ;
187- TechnoCount = TechnoClass::Array->Count ;
188- AnimCount = AnimClass::Array->Count ;
189- CurrentFrame = Unsorted::CurrentFrame;
190197 }
198+
199+ ExtraMetaInfo (noinit_t ()) { }
191200 };
192201
193- bool AppendExtraMetaInfo (IStorage* pStorage)
202+ template <typename T>
203+ bool AppendToStorage (IStorage* pStorage,const OLECHAR * name)
194204 {
195205 IStream* pStream = nullptr ;
196206 bool ret = false ;
197207 HRESULT hr = pStorage->CreateStream (
198- L" Spawner MetaInfo " ,
199- STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE ,
208+ name ,
209+ STGM_WRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE ,
200210 0 ,
201211 0 ,
202212 &pStream
203213 );
204214
205215 if (SUCCEEDED (hr) && pStream != nullptr )
206216 {
207- ExtraMetaInfo info {};
217+ T info {};
208218 ULONG written = 0 ;
209219 hr = pStream->Write (&info, sizeof (info), &written);
210220 ret = SUCCEEDED (hr) && written == sizeof (info);
@@ -213,31 +223,50 @@ namespace SavedGames
213223
214224 return ret;
215225 }
226+
227+ /*
228+ template<typename T>
229+ bool ReadFromStorage(IStorage* pStorage, const OLECHAR* name)
230+ {
231+ IStream* pStream = nullptr;
232+ bool ret = false;
233+ HRESULT hr = pStorage->OpenStream(
234+ name,
235+ NULL,
236+ STGM_READ | STGM_SHARE_EXCLUSIVE,
237+ 0,
238+ &pStream
239+ );
240+
241+ if (SUCCEEDED(hr) && pStream != nullptr)
242+ {
243+ T info;
244+ ULONG read = 0;
245+ hr = pStream->Read(&info, sizeof(info), &read);
246+ ret = SUCCEEDED(hr) && read == sizeof(info);
247+ pStream->Release();
248+ }
249+
250+ return ret;
251+ }
252+ */
216253}
217254
255+ // Write : A la fin
218256DEFINE_HOOK (0x67D2E3 , GameSave_AdditionalInfoForClient, 0x6 )
219257{
220258 GET_STACK (IStorage*, pStorage, STACK_OFFSET (0x4A0 , -0x490 ));
259+ using namespace SavedGames ;
221260
222- if (pStorage && SavedGames::AppendExtraMetaInfo (pStorage))
261+ if (pStorage
262+ && AppendToStorage<CampaignID>(pStorage, L" Campaign ID" )
263+ && AppendToStorage<ExtraMetaInfo>(pStorage, L" Spawner extra info" )
264+ )
223265 Debug::Log (" [Spawner] Extra meta info appended on sav file\n " );
224266 else
225267 Debug::Log (" [Spawner] Cannot write extra meta info to sav file\n " );
226268
227269 return 0 ;
228270}
229-
230- #else
231-
232- DEFINE_HOOK (0x67D04E , GameSave_SavegameInformation, 0x7 )
233- {
234- REF_STACK (SavegameInformation, Info, STACK_OFFSET (0x4A4 , -0x3F4 ));
235-
236- // Are you sure this is unused when spawner active? I don't think so
237- Info.ScenarioNumber = SessionClass::IsCampaign () ? Spawner::GetConfig ()->CampaignID : -1 ;
238-
239- return 0 ;
240- }
241-
242- DEFINE_JUMP (LJMP , 0x681AF1 , 0x681B30 );// skip reading ScenarioNumber
243- #endif
271+ // Read : TODO
272+ // TODO : the requirement and solution on the client side needs better formulation
0 commit comments