20
20
#include " CWorldSA.h"
21
21
#include " gamesa_renderware.h"
22
22
#include " CFxSA.h"
23
+ #include " C2DEffectSA.h"
23
24
24
25
extern CCoreInterface* g_pCore;
25
26
extern CGameSA* pGame;
@@ -1208,8 +1209,7 @@ void CModelInfoSA::StaticReset2DFXEffects()
1208
1209
}
1209
1210
1210
1211
// Delete copy of the default effect
1211
- delete innerIter->second ;
1212
- innerIter->second = nullptr ;
1212
+ C2DEffectSA::SafeDelete2DFXEffect (innerIter->second );
1213
1213
innerIter = iter->second .erase (innerIter);
1214
1214
}
1215
1215
@@ -1223,7 +1223,7 @@ void CModelInfoSA::StaticReset2DFXEffects()
1223
1223
// Destroy copies
1224
1224
auto & copies = MapGet (tempCopy2dfxEffects, iter->first );
1225
1225
for (auto copy : copies)
1226
- delete copy;
1226
+ C2DEffectSA::SafeDelete2DFXEffect ( copy) ;
1227
1227
}
1228
1228
1229
1229
// Clear maps & vectors
@@ -2173,6 +2173,10 @@ void CModelInfoSA::Update2DFXEffect(C2DEffectSAInterface* effect)
2173
2173
2174
2174
void CModelInfoSA::StoreDefault2DFXEffect (C2DEffectSAInterface* effect)
2175
2175
{
2176
+ // Is custom effect?
2177
+ if (std::find (d2fxEffects.begin (), d2fxEffects.end (), effect) != d2fxEffects.end ())
2178
+ return ;
2179
+
2176
2180
if (MapContains (ms_DefaultEffectsMap, m_dwModelID) && MapContains (MapGet (ms_DefaultEffectsMap, m_dwModelID), effect))
2177
2181
return ;
2178
2182
@@ -2188,13 +2192,19 @@ void CModelInfoSA::StoreDefault2DFXEffect(C2DEffectSAInterface* effect)
2188
2192
if (copy->type == e2dEffectType::LIGHT)
2189
2193
{
2190
2194
if (effect->effect .light .coronaTex && effect->effect .light .shadowTex )
2191
- PrepareTexturesForLightEffect (copy->effect .light .coronaTex , copy->effect .light .shadowTex , effect->effect .light .coronaTex ->name , effect->effect .light .shadowTex ->name , false );
2195
+ C2DEffectSA:: PrepareTexturesForLightEffect (copy->effect .light .coronaTex , copy->effect .light .shadowTex , effect->effect .light .coronaTex ->name , effect->effect .light .shadowTex ->name , false );
2192
2196
}
2193
2197
else if (copy->type == e2dEffectType::ROADSIGN)
2194
2198
{
2195
2199
// Create a copy of text and atomic for the roadsign
2196
2200
// We must to do this, because C2DEffect::Shutdown removes them
2197
- std::strncpy (copy->effect .roadsign .text , effect->effect .roadsign .text , 64 );
2201
+ copy->effect .roadsign .text = static_cast <char *>(std::malloc (64 ));
2202
+ if (copy->effect .roadsign .text )
2203
+ {
2204
+ std::memset (copy->effect .roadsign .text , 0 , 64 );
2205
+ std::strncpy (copy->effect .roadsign .text , effect->effect .roadsign .text , 64 );
2206
+ }
2207
+
2198
2208
copy->effect .roadsign .atomic = RpAtomicClone (effect->effect .roadsign .atomic );
2199
2209
}
2200
2210
@@ -2230,14 +2240,14 @@ bool CModelInfoSA::Reset2DFXEffects(bool removeCustomEffects)
2230
2240
2231
2241
// We no longer need a copy
2232
2242
// So delete it
2233
- delete it->second ;
2243
+ C2DEffectSA::SafeDelete2DFXEffect ( it->second ) ;
2234
2244
it = map.erase (it);
2235
2245
}
2236
2246
2237
2247
// Delete temp copies
2238
2248
auto & copies = MapGet (tempCopy2dfxEffects, m_dwModelID);
2239
2249
for (auto * copy : copies)
2240
- delete copy;
2250
+ C2DEffectSA::SafeDelete2DFXEffect ( copy) ;
2241
2251
2242
2252
// Clear maps
2243
2253
map.clear ();
@@ -2300,20 +2310,14 @@ bool CModelInfoSA::Remove2DFX(C2DEffectSAInterface* effect, bool includeDefault)
2300
2310
StoreDefault2DFXEffect (effect);
2301
2311
2302
2312
m_pInterface->ucNumOf2DEffects --;
2303
- if (isCustomEffect)
2304
- {
2305
- MapGet (numCustom2dfxEffects, m_pInterface)--;
2306
- d2fxEffects.erase (it);
2307
- }
2308
2313
2309
2314
switch (effect->type )
2310
2315
{
2311
2316
case e2dEffectType::ROADSIGN:
2312
2317
case e2dEffectType::LIGHT:
2313
2318
{
2314
- // Call C2DEffect::Shutdown
2315
- ((void (__thiscall*)(C2DEffectSAInterface*))FUNC_C2DEffect_Shutdown)(effect);
2316
-
2319
+ C2DEffectSA::Shutdown (effect);
2320
+
2317
2321
// Prevent creation when stream in but keep in memory so we can restore it later
2318
2322
effect->type = e2dEffectType::NONE;
2319
2323
break ;
@@ -2322,15 +2326,13 @@ bool CModelInfoSA::Remove2DFX(C2DEffectSAInterface* effect, bool includeDefault)
2322
2326
{
2323
2327
auto entities = GetEntitiesFromFx (m_dwModelID);
2324
2328
for (auto * entity : entities)
2325
- {
2326
2329
// Call Fx_c::DestroyEntityFx
2327
2330
((void (__thiscall*)(CFxSAInterface*, CEntitySAInterface*))FUNC_Fx_c_DestroyEntityFx)(fx, entity);
2328
2331
2329
- // Prevent creation when stream in but keep in memory so we can restore it later
2330
- effect->type = e2dEffectType::NONE;
2331
- }
2332
-
2333
2332
entities.clear ();
2333
+
2334
+ // Prevent creation when stream in but keep in memory so we can restore it later
2335
+ effect->type = e2dEffectType::NONE;
2334
2336
break ;
2335
2337
}
2336
2338
case e2dEffectType::ESCALATOR:
@@ -2358,11 +2360,16 @@ bool CModelInfoSA::Remove2DFX(C2DEffectSAInterface* effect, bool includeDefault)
2358
2360
effect->type = e2dEffectType::NONE;
2359
2361
break ;
2360
2362
}
2363
+ default :
2364
+ return false ;
2361
2365
}
2362
2366
2363
2367
// If it's custom effect then delete it. If it's default effect then store it as removed
2364
2368
if (isCustomEffect)
2365
2369
{
2370
+ MapGet (numCustom2dfxEffects, m_pInterface)--;
2371
+ d2fxEffects.erase (it);
2372
+
2366
2373
delete effect;
2367
2374
effect = nullptr ;
2368
2375
}
@@ -2462,7 +2469,7 @@ void CModelInfoSA::RestoreModified2DFXEffects()
2462
2469
if (tempVec[i])
2463
2470
{
2464
2471
MemCpyFast (effect, tempVec[i], sizeof (C2DEffectSAInterface));
2465
- delete tempVec[i];
2472
+ C2DEffectSA::SafeDelete2DFXEffect ( tempVec[i]) ;
2466
2473
}
2467
2474
2468
2475
Update2DFXEffect (effect);
0 commit comments