/Code/GameSDK/GameDll/Effects/GameEffectsSystem.cpp

https://gitlab.com/dahbearz/CRYENGINE · C++ · 895 lines · 656 code · 94 blank · 145 comment · 97 complexity · 63223310bb58eeed545c1712667662cc MD5 · raw file

  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2. // Includes
  3. #include "StdAfx.h"
  4. #include "GameEffectsSystem.h"
  5. #include "Effects/GameEffects/GameEffect.h"
  6. #include "GameCVars.h"
  7. #include "ItemSystem.h"
  8. #include <CryCore/BitFiddling.h>
  9. #include "Effects/RenderNodes/IGameRenderNode.h"
  10. #include "Effects/RenderElements/GameRenderElement.h"
  11. #include "GameRules.h"
  12. //--------------------------------------------------------------------------------------------------
  13. // Desc: Defines
  14. //--------------------------------------------------------------------------------------------------
  15. #define GAME_FX_DATA_FILE "scripts/effects/gameeffects.xml"
  16. //--------------------------------------------------------------------------------------------------
  17. //--------------------------------------------------------------------------------------------------
  18. // Desc: Debug data
  19. //--------------------------------------------------------------------------------------------------
  20. #if DEBUG_GAME_FX_SYSTEM
  21. int CGameEffectsSystem::s_currentDebugEffectId = 0;
  22. const char* GAME_FX_DEBUG_VIEW_NAMES[eMAX_GAME_FX_DEBUG_VIEWS] = { "None",
  23. "Profiling",
  24. "Effect List",
  25. "Bounding Box",
  26. "Bounding Sphere",
  27. "Particles" };
  28. #endif
  29. //--------------------------------------------------------------------------------------------------
  30. //--------------------------------------------------------------------------------------------------
  31. // Desc: Static data
  32. //--------------------------------------------------------------------------------------------------
  33. CGameEffectsSystem* CGameEffectsSystem::s_singletonInstance = NULL;
  34. bool CGameEffectsSystem::s_hasLoadedData = false;
  35. int CGameEffectsSystem::s_postEffectCVarNameOffset = 0;
  36. //--------------------------------------------------------------------------------------------------
  37. //--------------------------------------------------------------------------------------------------
  38. // Desc: Game Effect System Static data - contains access to any data where static initialisation
  39. // order is critical, this will enforce initialisation on first use
  40. //--------------------------------------------------------------------------------------------------
  41. struct SGameEffectSystemStaticData
  42. {
  43. static PodArray<DataLoadCallback>& GetDataLoadCallbackList()
  44. {
  45. static PodArray<DataLoadCallback> dataLoadCallbackList;
  46. return dataLoadCallbackList;
  47. }
  48. static PodArray<DataReleaseCallback>& GetDataReleaseCallbackList()
  49. {
  50. static PodArray<DataReleaseCallback> dataReleaseCallbackList;
  51. return dataReleaseCallbackList;
  52. }
  53. static PodArray<DataReloadCallback>& GetDataReloadCallbackList()
  54. {
  55. static PodArray<DataReloadCallback> dataReloadCallbackList;
  56. return dataReloadCallbackList;
  57. }
  58. static PodArray<EnteredGameCallback>& GetEnteredGameCallbackList()
  59. {
  60. static PodArray<EnteredGameCallback> enteredGameCallbackList;
  61. return enteredGameCallbackList;
  62. }
  63. #if DEBUG_GAME_FX_SYSTEM
  64. static PodArray<CGameEffectsSystem::SEffectDebugData>& GetEffectDebugList()
  65. {
  66. static PodArray<CGameEffectsSystem::SEffectDebugData> effectDebugList;
  67. return effectDebugList;
  68. }
  69. #endif
  70. };
  71. // Easy access macros
  72. #define s_dataLoadCallbackList SGameEffectSystemStaticData::GetDataLoadCallbackList()
  73. #define s_dataReleaseCallbackList SGameEffectSystemStaticData::GetDataReleaseCallbackList()
  74. #define s_dataReloadCallbackList SGameEffectSystemStaticData::GetDataReloadCallbackList()
  75. #define s_enteredGameCallbackList SGameEffectSystemStaticData::GetEnteredGameCallbackList()
  76. #if DEBUG_GAME_FX_SYSTEM
  77. #define s_effectDebugList SGameEffectSystemStaticData::GetEffectDebugList()
  78. #endif
  79. //--------------------------------------------------------------------------------------------------
  80. //--------------------------------------------------------------------------------------------------
  81. // Name: CGameEffectsSystem
  82. // Desc: Constructor
  83. //--------------------------------------------------------------------------------------------------
  84. CGameEffectsSystem::CGameEffectsSystem()
  85. {
  86. #if DEBUG_GAME_FX_SYSTEM
  87. if(gEnv->pInput)
  88. {
  89. gEnv->pInput->AddEventListener(this);
  90. }
  91. #endif
  92. Reset();
  93. }//-------------------------------------------------------------------------------------------------
  94. //--------------------------------------------------------------------------------------------------
  95. // Name: ~CGameEffectsSystem
  96. // Desc: Destructor
  97. //--------------------------------------------------------------------------------------------------
  98. CGameEffectsSystem::~CGameEffectsSystem()
  99. {
  100. #if DEBUG_GAME_FX_SYSTEM
  101. if(gEnv->pInput)
  102. {
  103. gEnv->pInput->RemoveEventListener(this);
  104. }
  105. #endif
  106. // Remove as game rules listener
  107. if(g_pGame)
  108. {
  109. CGameRules* pGameRules = g_pGame->GetGameRules();
  110. if(pGameRules)
  111. {
  112. pGameRules->RemoveGameRulesListener(this);
  113. }
  114. }
  115. }//-------------------------------------------------------------------------------------------------
  116. //--------------------------------------------------------------------------------------------------
  117. // Name: Destroy
  118. // Desc: Destroys effects system
  119. //--------------------------------------------------------------------------------------------------
  120. void CGameEffectsSystem::Destroy()
  121. {
  122. if(s_singletonInstance)
  123. {
  124. s_singletonInstance->AutoReleaseAndDeleteFlaggedEffects(s_singletonInstance->m_effectsToUpdate);
  125. s_singletonInstance->AutoReleaseAndDeleteFlaggedEffects(s_singletonInstance->m_effectsNotToUpdate);
  126. FX_ASSERT_MESSAGE( (s_singletonInstance->m_effectsToUpdate==NULL) &&
  127. (s_singletonInstance->m_effectsNotToUpdate==NULL),
  128. "Game Effects System being destroyed even though game effects still exist!");
  129. }
  130. SAFE_DELETE(s_singletonInstance);
  131. }//-------------------------------------------------------------------------------------------------
  132. //--------------------------------------------------------------------------------------------------
  133. // Name: Reset
  134. // Desc: Resets effects systems data
  135. //--------------------------------------------------------------------------------------------------
  136. void CGameEffectsSystem::Reset()
  137. {
  138. m_isInitialised = false;
  139. m_effectsToUpdate = NULL;
  140. m_effectsNotToUpdate = NULL;
  141. m_nextEffectToUpdate = NULL;
  142. s_postEffectCVarNameOffset = 0;
  143. #if DEBUG_GAME_FX_SYSTEM
  144. m_debugView = eGAME_FX_DEBUG_VIEW_None;
  145. #endif
  146. }//-------------------------------------------------------------------------------------------------
  147. //--------------------------------------------------------------------------------------------------
  148. // Name: Initialise
  149. // Desc: Initialises effects system
  150. //--------------------------------------------------------------------------------------------------
  151. void CGameEffectsSystem::Initialise()
  152. {
  153. if(m_isInitialised == false)
  154. {
  155. Reset();
  156. SetPostEffectCVarCallbacks();
  157. m_isInitialised = true;
  158. }
  159. }//-------------------------------------------------------------------------------------------------
  160. //--------------------------------------------------------------------------------------------------
  161. // Name: GameRulesInitialise
  162. // Desc: Game Rules initialise
  163. //--------------------------------------------------------------------------------------------------
  164. void CGameEffectsSystem::GameRulesInitialise()
  165. {
  166. // Add as game rules listener
  167. if(g_pGame)
  168. {
  169. CGameRules* pGameRules = g_pGame->GetGameRules();
  170. if(pGameRules)
  171. {
  172. pGameRules->AddGameRulesListener(this);
  173. }
  174. }
  175. }//-------------------------------------------------------------------------------------------------
  176. //--------------------------------------------------------------------------------------------------
  177. // Name: LoadData
  178. // Desc: Loads data for game effects system and effects
  179. //--------------------------------------------------------------------------------------------------
  180. void CGameEffectsSystem::LoadData()
  181. {
  182. if(s_hasLoadedData == false)
  183. {
  184. XmlNodeRef rootNode = gEnv->pSystem->LoadXmlFromFile(GAME_FX_DATA_FILE);
  185. if(!rootNode)
  186. {
  187. GameWarning("Could not load game effects data. Invalid XML file '%s'! ", GAME_FX_DATA_FILE);
  188. return;
  189. }
  190. IItemParamsNode* paramNode = g_pGame->GetIGameFramework()->GetIItemSystem()->CreateParams();
  191. if(paramNode)
  192. {
  193. paramNode->ConvertFromXML(rootNode);
  194. // Pass data to any callback functions registered
  195. int callbackCount = s_dataLoadCallbackList.size();
  196. DataLoadCallback dataLoadCallbackFunc = NULL;
  197. for(int i=0; i<callbackCount; i++)
  198. {
  199. dataLoadCallbackFunc = s_dataLoadCallbackList[i];
  200. if(dataLoadCallbackFunc)
  201. {
  202. dataLoadCallbackFunc(paramNode);
  203. }
  204. }
  205. paramNode->Release();
  206. s_hasLoadedData = true;
  207. }
  208. }
  209. }//-------------------------------------------------------------------------------------------------
  210. //--------------------------------------------------------------------------------------------------
  211. // Name: ReleaseData
  212. // Desc: Releases any loaded data for game effects system and any effects with registered callbacks
  213. //--------------------------------------------------------------------------------------------------
  214. void CGameEffectsSystem::ReleaseData()
  215. {
  216. if(s_hasLoadedData)
  217. {
  218. #if DEBUG_GAME_FX_SYSTEM
  219. // Unload all debug effects which rely on effect data
  220. for(size_t i=0; i<s_effectDebugList.Size(); i++)
  221. {
  222. if(s_effectDebugList[i].inputCallback)
  223. {
  224. s_effectDebugList[i].inputCallback(GAME_FX_INPUT_ReleaseDebugEffect);
  225. }
  226. }
  227. #endif
  228. // Pass data to any callback functions registered
  229. int callbackCount = s_dataReleaseCallbackList.size();
  230. DataReleaseCallback dataReleaseCallbackFunc = NULL;
  231. for(int i=0; i<callbackCount; i++)
  232. {
  233. dataReleaseCallbackFunc = s_dataReleaseCallbackList[i];
  234. if(dataReleaseCallbackFunc)
  235. {
  236. dataReleaseCallbackFunc();
  237. }
  238. }
  239. s_hasLoadedData = false;
  240. }
  241. }//-------------------------------------------------------------------------------------------------
  242. //--------------------------------------------------------------------------------------------------
  243. // Name: ReloadData
  244. // Desc: Reloads any loaded data for game effects registered callbacks
  245. //--------------------------------------------------------------------------------------------------
  246. void CGameEffectsSystem::ReloadData()
  247. {
  248. XmlNodeRef rootNode = gEnv->pSystem->LoadXmlFromFile(GAME_FX_DATA_FILE);
  249. if(!rootNode)
  250. {
  251. GameWarning("Could not load game effects data. Invalid XML file '%s'! ", GAME_FX_DATA_FILE);
  252. return;
  253. }
  254. IItemParamsNode* paramNode = g_pGame->GetIGameFramework()->GetIItemSystem()->CreateParams();
  255. if(paramNode)
  256. {
  257. paramNode->ConvertFromXML(rootNode);
  258. // Pass data to any callback functions registered
  259. int callbackCount = s_dataReloadCallbackList.size();
  260. DataReloadCallback dataReloadCallbackFunc = NULL;
  261. for(int i=0; i<callbackCount; i++)
  262. {
  263. dataReloadCallbackFunc = s_dataReloadCallbackList[i];
  264. if(dataReloadCallbackFunc)
  265. {
  266. dataReloadCallbackFunc(paramNode);
  267. }
  268. }
  269. paramNode->Release();
  270. }
  271. }//-------------------------------------------------------------------------------------------------
  272. //--------------------------------------------------------------------------------------------------
  273. // Name: EnteredGame
  274. // Desc: Called when entering a game
  275. //--------------------------------------------------------------------------------------------------
  276. void CGameEffectsSystem::EnteredGame()
  277. {
  278. const int callbackCount = s_enteredGameCallbackList.size();
  279. EnteredGameCallback enteredGameCallbackFunc = NULL;
  280. for(int i=0; i<callbackCount; i++)
  281. {
  282. enteredGameCallbackFunc = s_enteredGameCallbackList[i];
  283. if(enteredGameCallbackFunc)
  284. {
  285. enteredGameCallbackFunc();
  286. }
  287. }
  288. }//-------------------------------------------------------------------------------------------------
  289. //--------------------------------------------------------------------------------------------------
  290. // Name: RegisterDataLoadCallback
  291. // Desc: Registers data load callback
  292. //--------------------------------------------------------------------------------------------------
  293. void CGameEffectsSystem::RegisterDataLoadCallback(DataLoadCallback dataLoadCallback)
  294. {
  295. if(dataLoadCallback)
  296. {
  297. s_dataLoadCallbackList.push_back(dataLoadCallback);
  298. }
  299. }//-------------------------------------------------------------------------------------------------
  300. //--------------------------------------------------------------------------------------------------
  301. // Name: RegisterDataReleaseCallback
  302. // Desc: Registers data release callback
  303. //--------------------------------------------------------------------------------------------------
  304. void CGameEffectsSystem::RegisterDataReleaseCallback(DataReleaseCallback dataReleaseCallback)
  305. {
  306. if(dataReleaseCallback)
  307. {
  308. s_dataReleaseCallbackList.push_back(dataReleaseCallback);
  309. }
  310. }//-------------------------------------------------------------------------------------------------
  311. //--------------------------------------------------------------------------------------------------
  312. // Name: RegisterDataReloadCallback
  313. // Desc: Registers data reload callback
  314. //--------------------------------------------------------------------------------------------------
  315. void CGameEffectsSystem::RegisterDataReloadCallback(DataReloadCallback dataReloadCallback)
  316. {
  317. if(dataReloadCallback)
  318. {
  319. s_dataReloadCallbackList.push_back(dataReloadCallback);
  320. }
  321. }//-------------------------------------------------------------------------------------------------
  322. //--------------------------------------------------------------------------------------------------
  323. // Name: RegisterEnteredGameCallback
  324. // Desc: Registers entered game callback
  325. //--------------------------------------------------------------------------------------------------
  326. void CGameEffectsSystem::RegisterEnteredGameCallback(EnteredGameCallback enteredGameCallback)
  327. {
  328. if(enteredGameCallback)
  329. {
  330. s_enteredGameCallbackList.push_back(enteredGameCallback);
  331. }
  332. }//-------------------------------------------------------------------------------------------------
  333. //--------------------------------------------------------------------------------------------------
  334. // Name: AutoReleaseAndDeleteFlaggedEffects
  335. // Desc: Calls release and delete on any effects with the these flags set
  336. //--------------------------------------------------------------------------------------------------
  337. void CGameEffectsSystem::AutoReleaseAndDeleteFlaggedEffects(IGameEffect* effectList)
  338. {
  339. if(effectList)
  340. {
  341. IGameEffect* effect = effectList;
  342. while(effect)
  343. {
  344. m_nextEffectToUpdate = effect->Next();
  345. bool autoRelease = effect->IsFlagSet(GAME_EFFECT_AUTO_RELEASE);
  346. bool autoDelete = effect->IsFlagSet(GAME_EFFECT_AUTO_DELETE);
  347. if(autoRelease || autoDelete)
  348. {
  349. effect->Release();
  350. if(autoDelete)
  351. {
  352. SAFE_DELETE(effect);
  353. }
  354. }
  355. effect = m_nextEffectToUpdate;
  356. }
  357. m_nextEffectToUpdate = NULL;
  358. }
  359. }//-------------------------------------------------------------------------------------------------
  360. //--------------------------------------------------------------------------------------------------
  361. // Name: SetPostEffectCVarCallbacks
  362. // Desc: Sets Post effect CVar callbacks for testing and tweaking post effect values
  363. //--------------------------------------------------------------------------------------------------
  364. void CGameEffectsSystem::SetPostEffectCVarCallbacks()
  365. {
  366. #if DEBUG_GAME_FX_SYSTEM
  367. ICVar* postEffectCvar = NULL;
  368. const char postEffectNames[][64] = { "g_postEffect.FilterGrain_Amount",
  369. "g_postEffect.FilterRadialBlurring_Amount",
  370. "g_postEffect.FilterRadialBlurring_ScreenPosX",
  371. "g_postEffect.FilterRadialBlurring_ScreenPosY",
  372. "g_postEffect.FilterRadialBlurring_Radius",
  373. "g_postEffect.Global_User_ColorC",
  374. "g_postEffect.Global_User_ColorM",
  375. "g_postEffect.Global_User_ColorY",
  376. "g_postEffect.Global_User_ColorK",
  377. "g_postEffect.Global_User_Brightness",
  378. "g_postEffect.Global_User_Contrast",
  379. "g_postEffect.Global_User_Saturation",
  380. "g_postEffect.Global_User_ColorHue",
  381. "g_postEffect.HUD3D_Interference",
  382. "g_postEffect.HUD3D_FOV"};
  383. int postEffectNameCount = sizeof(postEffectNames)/sizeof(*postEffectNames);
  384. if(postEffectNameCount > 0)
  385. {
  386. // Calc name offset
  387. const char* postEffectName = postEffectNames[0];
  388. s_postEffectCVarNameOffset = 0;
  389. while((*postEffectName) != 0)
  390. {
  391. s_postEffectCVarNameOffset++;
  392. if((*postEffectName) == '.')
  393. {
  394. break;
  395. }
  396. postEffectName++;
  397. }
  398. // Set callback functions
  399. for(int i=0; i<postEffectNameCount; i++)
  400. {
  401. postEffectCvar = gEnv->pConsole->GetCVar(postEffectNames[i]);
  402. if(postEffectCvar)
  403. {
  404. postEffectCvar->SetOnChangeCallback(PostEffectCVarCallback);
  405. }
  406. }
  407. }
  408. #endif
  409. }//-------------------------------------------------------------------------------------------------
  410. //--------------------------------------------------------------------------------------------------
  411. // Name: PostEffectCVarCallback
  412. // Desc: Callback function of post effect cvars to set their values
  413. //--------------------------------------------------------------------------------------------------
  414. void CGameEffectsSystem::PostEffectCVarCallback(ICVar* cvar)
  415. {
  416. const char* effectName = cvar->GetName() + s_postEffectCVarNameOffset;
  417. gEnv->p3DEngine->SetPostEffectParam(effectName,cvar->GetFVal());
  418. }//-------------------------------------------------------------------------------------------------
  419. //--------------------------------------------------------------------------------------------------
  420. // Name: RegisterEffect
  421. // Desc: Registers effect with effect system
  422. //--------------------------------------------------------------------------------------------------
  423. void CGameEffectsSystem::RegisterEffect(IGameEffect* effect)
  424. {
  425. FX_ASSERT_MESSAGE(m_isInitialised,"Game Effects System trying to register an effect without being initialised");
  426. FX_ASSERT_MESSAGE(effect,"Trying to Register a NULL effect");
  427. if(effect)
  428. {
  429. // If effect is registered, then unregister first
  430. if(effect->IsFlagSet(GAME_EFFECT_REGISTERED))
  431. {
  432. UnRegisterEffect(effect);
  433. }
  434. // Add effect to effect list
  435. IGameEffect** effectList = NULL;
  436. bool isActive = effect->IsFlagSet(GAME_EFFECT_ACTIVE);
  437. bool autoUpdatesWhenActive = effect->IsFlagSet(GAME_EFFECT_AUTO_UPDATES_WHEN_ACTIVE);
  438. bool autoUpdatesWhenNotActive = effect->IsFlagSet(GAME_EFFECT_AUTO_UPDATES_WHEN_NOT_ACTIVE);
  439. if((isActive && autoUpdatesWhenActive) ||
  440. ((!isActive) && autoUpdatesWhenNotActive))
  441. {
  442. effectList = &m_effectsToUpdate;
  443. }
  444. else
  445. {
  446. effectList = &m_effectsNotToUpdate;
  447. }
  448. if(*effectList)
  449. {
  450. (*effectList)->SetPrev(effect);
  451. effect->SetNext(*effectList);
  452. }
  453. (*effectList) = effect;
  454. effect->SetFlag(GAME_EFFECT_REGISTERED,true);
  455. }
  456. }//-------------------------------------------------------------------------------------------------
  457. //--------------------------------------------------------------------------------------------------
  458. // Name: UnRegisterEffect
  459. // Desc: UnRegisters effect from effect system
  460. //--------------------------------------------------------------------------------------------------
  461. void CGameEffectsSystem::UnRegisterEffect(IGameEffect* effect)
  462. {
  463. FX_ASSERT_MESSAGE(m_isInitialised,"Game Effects System trying to unregister an effect without being initialised");
  464. FX_ASSERT_MESSAGE(effect,"Trying to UnRegister a NULL effect");
  465. if(effect && effect->IsFlagSet(GAME_EFFECT_REGISTERED))
  466. {
  467. // If the effect is the next one to be updated, then point m_nextEffectToUpdate to the next effect after it
  468. if(effect == m_nextEffectToUpdate)
  469. {
  470. m_nextEffectToUpdate = m_nextEffectToUpdate->Next();
  471. }
  472. if(effect->Prev())
  473. {
  474. effect->Prev()->SetNext(effect->Next());
  475. }
  476. else
  477. {
  478. if(m_effectsToUpdate == effect)
  479. {
  480. m_effectsToUpdate = effect->Next();
  481. }
  482. else
  483. {
  484. FX_ASSERT_MESSAGE((m_effectsNotToUpdate == effect),"Effect isn't either updating list");
  485. m_effectsNotToUpdate = effect->Next();
  486. }
  487. }
  488. if(effect->Next())
  489. {
  490. effect->Next()->SetPrev(effect->Prev());
  491. }
  492. effect->SetNext(NULL);
  493. effect->SetPrev(NULL);
  494. effect->SetFlag(GAME_EFFECT_REGISTERED,false);
  495. }
  496. }//-------------------------------------------------------------------------------------------------
  497. //--------------------------------------------------------------------------------------------------
  498. // Name: Update
  499. // Desc: Updates effects system and any effects registered in it's update list
  500. //--------------------------------------------------------------------------------------------------
  501. void CGameEffectsSystem::Update(float frameTime)
  502. {
  503. FX_ASSERT_MESSAGE(m_isInitialised,"Game Effects System trying to update without being initialised");
  504. // Get pause state
  505. bool isPaused = false;
  506. IGame* pGame = gEnv->pGame;
  507. if(pGame)
  508. {
  509. IGameFramework* pGameFramework = pGame->GetIGameFramework();
  510. if(pGameFramework)
  511. {
  512. isPaused = pGameFramework->IsGamePaused();
  513. }
  514. }
  515. // Update effects
  516. IViewSystem *pViewSystem = g_pGame->GetIGameFramework()->GetIViewSystem();
  517. if(pViewSystem && m_effectsToUpdate)
  518. {
  519. IGameEffect* effect = m_effectsToUpdate;
  520. while(effect)
  521. {
  522. m_nextEffectToUpdate = effect->Next();
  523. if((!isPaused) || (effect->IsFlagSet(GAME_EFFECT_UPDATE_WHEN_PAUSED)))
  524. {
  525. effect->Update(frameTime);
  526. }
  527. if (!pViewSystem->IsClientActorViewActive())
  528. {
  529. effect->ResetRenderParameters();
  530. }
  531. effect = m_nextEffectToUpdate;
  532. }
  533. }
  534. m_nextEffectToUpdate = NULL;
  535. #if DEBUG_GAME_FX_SYSTEM
  536. DrawDebugDisplay();
  537. #endif
  538. }//-------------------------------------------------------------------------------------------------
  539. //--------------------------------------------------------------------------------------------------
  540. // Name: DrawDebugDisplay
  541. // Desc: Draws debug display
  542. //--------------------------------------------------------------------------------------------------
  543. #if DEBUG_GAME_FX_SYSTEM
  544. void CGameEffectsSystem::DrawDebugDisplay()
  545. {
  546. static ColorF textCol(1.0f,1.0f,1.0f,1.0f);
  547. static ColorF controlCol(0.6f,0.6f,0.6f,1.0f);
  548. static Vec2 textPos(10.0f,10.0f);
  549. static float textSize = 1.4f;
  550. static float textYSpacing = 18.0f;
  551. static float effectNameXOffset = 100.0f;
  552. static ColorF effectNameCol(0.0f,1.0f,0.0f,1.0f);
  553. Vec2 currentTextPos = textPos;
  554. int debugEffectCount = s_effectDebugList.Size();
  555. if((g_pGameCVars->g_gameFXSystemDebug) && (debugEffectCount > 0))
  556. {
  557. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&textCol.r,false,"Debug view:");
  558. gEnv->pRenderer->Draw2dLabel(currentTextPos.x+effectNameXOffset,currentTextPos.y,textSize,&effectNameCol.r,false, "%s", GAME_FX_DEBUG_VIEW_NAMES[m_debugView]);
  559. currentTextPos.y += textYSpacing;
  560. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&controlCol.r,false,"(Change debug view: Left/Right arrows)");
  561. currentTextPos.y += textYSpacing;
  562. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&textCol.r,false,"Debug effect:");
  563. gEnv->pRenderer->Draw2dLabel(currentTextPos.x+effectNameXOffset,currentTextPos.y,textSize,&effectNameCol.r,false, "%s", s_effectDebugList[s_currentDebugEffectId].effectName);
  564. currentTextPos.y += textYSpacing;
  565. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&controlCol.r,false,"(Change effect: NumPad +/-)");
  566. currentTextPos.y += textYSpacing;
  567. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&controlCol.r,false,"(Reload effect data: NumPad .)");
  568. currentTextPos.y += textYSpacing;
  569. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&controlCol.r,false,"(Reset Particle System: Delete)");
  570. currentTextPos.y += textYSpacing;
  571. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&controlCol.r,false,"(Pause Particle System: End)");
  572. currentTextPos.y += textYSpacing;
  573. if(s_effectDebugList[s_currentDebugEffectId].displayCallback)
  574. {
  575. s_effectDebugList[s_currentDebugEffectId].displayCallback(currentTextPos,textSize,textYSpacing);
  576. }
  577. if(m_debugView==eGAME_FX_DEBUG_VIEW_EffectList)
  578. {
  579. static Vec2 listPos(350.0f,50.0f);
  580. static float nameSize = 150.0f;
  581. static float tabSize = 60.0f;
  582. currentTextPos = listPos;
  583. const int EFFECT_LIST_COUNT = 2;
  584. IGameEffect* pEffectListArray[EFFECT_LIST_COUNT] = {m_effectsToUpdate,m_effectsNotToUpdate};
  585. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&effectNameCol.r,false,"Name");
  586. currentTextPos.x += nameSize;
  587. const int FLAG_COUNT = 9;
  588. const char* flagName[FLAG_COUNT] = {"Init","Rel","ARels","ADels","AUWA","AUWnA","Reg","Actv","DBG"};
  589. const int flag[FLAG_COUNT] = {GAME_EFFECT_INITIALISED,
  590. GAME_EFFECT_RELEASED,
  591. GAME_EFFECT_AUTO_RELEASE,
  592. GAME_EFFECT_AUTO_DELETE,
  593. GAME_EFFECT_AUTO_UPDATES_WHEN_ACTIVE,
  594. GAME_EFFECT_AUTO_UPDATES_WHEN_NOT_ACTIVE,
  595. GAME_EFFECT_REGISTERED,
  596. GAME_EFFECT_ACTIVE,
  597. GAME_EFFECT_DEBUG_EFFECT};
  598. for(int i=0; i<FLAG_COUNT; i++)
  599. {
  600. gEnv->pRenderer->Draw2dLabel(currentTextPos.x, currentTextPos.y, textSize, &effectNameCol.r, false, "%s", flagName[i]);
  601. currentTextPos.x += tabSize;
  602. }
  603. currentTextPos.y += textYSpacing;
  604. for(int l=0; l<EFFECT_LIST_COUNT; l++)
  605. {
  606. IGameEffect* pCurrentEffect = pEffectListArray[l];
  607. while(pCurrentEffect)
  608. {
  609. currentTextPos.x = listPos.x;
  610. gEnv->pRenderer->Draw2dLabel(currentTextPos.x, currentTextPos.y, textSize, &textCol.r, false, "%s", pCurrentEffect->GetName());
  611. currentTextPos.x += nameSize;
  612. for(int i=0; i<FLAG_COUNT; i++)
  613. {
  614. gEnv->pRenderer->Draw2dLabel(currentTextPos.x,currentTextPos.y,textSize,&textCol.r,false,pCurrentEffect->IsFlagSet(flag[i])?"1":"0");
  615. currentTextPos.x += tabSize;
  616. }
  617. currentTextPos.y += textYSpacing;
  618. pCurrentEffect = pCurrentEffect->Next();
  619. }
  620. }
  621. }
  622. }
  623. }
  624. #endif
  625. //--------------------------------------------------------------------------------------------------
  626. //--------------------------------------------------------------------------------------------------
  627. // Name: OnInputEvent
  628. // Desc: Handles any debug input for the game effects system to test effects
  629. //--------------------------------------------------------------------------------------------------
  630. bool CGameEffectsSystem::OnInputEvent(const SInputEvent& inputEvent)
  631. {
  632. #if DEBUG_GAME_FX_SYSTEM
  633. int debugEffectCount = s_effectDebugList.Size();
  634. if((g_pGameCVars->g_gameFXSystemDebug) && (debugEffectCount > 0))
  635. {
  636. if(inputEvent.deviceType == eIDT_Keyboard && inputEvent.state == eIS_Pressed)
  637. {
  638. switch(inputEvent.keyId)
  639. {
  640. case GAME_FX_INPUT_IncrementDebugEffectId:
  641. {
  642. if(s_currentDebugEffectId < (debugEffectCount-1))
  643. {
  644. s_currentDebugEffectId++;
  645. }
  646. break;
  647. }
  648. case GAME_FX_INPUT_DecrementDebugEffectId:
  649. {
  650. if(s_currentDebugEffectId > 0)
  651. {
  652. s_currentDebugEffectId--;
  653. }
  654. break;
  655. }
  656. case GAME_FX_INPUT_DecrementDebugView:
  657. {
  658. if(m_debugView > 0)
  659. {
  660. OnDeActivateDebugView(m_debugView);
  661. m_debugView--;
  662. OnActivateDebugView(m_debugView);
  663. }
  664. break;
  665. }
  666. case GAME_FX_INPUT_IncrementDebugView:
  667. {
  668. if(m_debugView < (eMAX_GAME_FX_DEBUG_VIEWS-1))
  669. {
  670. OnDeActivateDebugView(m_debugView);
  671. m_debugView++;
  672. OnActivateDebugView(m_debugView);
  673. }
  674. break;
  675. }
  676. case GAME_FX_INPUT_ReloadEffectData:
  677. {
  678. ReloadData();
  679. break;
  680. }
  681. case GAME_FX_INPUT_ResetParticleManager:
  682. {
  683. gEnv->pParticleManager->Reset();
  684. break;
  685. }
  686. case GAME_FX_INPUT_PauseParticleManager:
  687. {
  688. #if DEBUG_GAME_FX_SYSTEM
  689. ICVar* pParticleDebugCVar = gEnv->pConsole->GetCVar("e_ParticlesDebug");
  690. if(pParticleDebugCVar)
  691. {
  692. int flagValue = pParticleDebugCVar->GetIVal();
  693. if(flagValue & AlphaBit('z'))
  694. {
  695. flagValue &= ~AlphaBit('z');
  696. }
  697. else
  698. {
  699. flagValue |= AlphaBit('z');
  700. }
  701. pParticleDebugCVar->Set(flagValue);
  702. }
  703. #endif
  704. break;
  705. }
  706. }
  707. // Send input to current debug effect
  708. if(s_effectDebugList[s_currentDebugEffectId].inputCallback)
  709. {
  710. s_effectDebugList[s_currentDebugEffectId].inputCallback(inputEvent.keyId);
  711. }
  712. }
  713. }
  714. #endif
  715. return false; // Return false so that other listeners will get this event
  716. }//-------------------------------------------------------------------------------------------------
  717. //--------------------------------------------------------------------------------------------------
  718. // Name: GetDebugEffect
  719. // Desc: Gets debug instance of effect
  720. //--------------------------------------------------------------------------------------------------
  721. #if DEBUG_GAME_FX_SYSTEM
  722. IGameEffect* CGameEffectsSystem::GetDebugEffect(const char* pEffectName) const
  723. {
  724. const int EFFECT_LIST_COUNT = 2;
  725. IGameEffect* pEffectListArray[EFFECT_LIST_COUNT] = {m_effectsToUpdate,m_effectsNotToUpdate};
  726. for(int l=0; l<EFFECT_LIST_COUNT;l++)
  727. {
  728. IGameEffect* pCurrentEffect = pEffectListArray[l];
  729. while(pCurrentEffect)
  730. {
  731. if(pCurrentEffect->IsFlagSet(GAME_EFFECT_DEBUG_EFFECT) &&
  732. (strcmp(pCurrentEffect->GetName(),pEffectName) == 0))
  733. {
  734. return pCurrentEffect;
  735. }
  736. pCurrentEffect = pCurrentEffect->Next();
  737. }
  738. }
  739. return NULL;
  740. }
  741. #endif
  742. //--------------------------------------------------------------------------------------------------
  743. //--------------------------------------------------------------------------------------------------
  744. // Name: OnActivateDebugView
  745. // Desc: Called on debug view activation
  746. //--------------------------------------------------------------------------------------------------
  747. #if DEBUG_GAME_FX_SYSTEM
  748. void CGameEffectsSystem::OnActivateDebugView(int debugView)
  749. {
  750. switch(debugView)
  751. {
  752. case eGAME_FX_DEBUG_VIEW_Profiling:
  753. {
  754. ICVar* r_displayInfoCVar = gEnv->pConsole->GetCVar("r_DisplayInfo");
  755. if(r_displayInfoCVar)
  756. {
  757. r_displayInfoCVar->Set(1);
  758. }
  759. break;
  760. }
  761. }
  762. }
  763. #endif
  764. //--------------------------------------------------------------------------------------------------
  765. //--------------------------------------------------------------------------------------------------
  766. // Name: OnDeActivateDebugView
  767. // Desc: Called on debug view de-activation
  768. //--------------------------------------------------------------------------------------------------
  769. #if DEBUG_GAME_FX_SYSTEM
  770. void CGameEffectsSystem::OnDeActivateDebugView(int debugView)
  771. {
  772. switch(debugView)
  773. {
  774. case eGAME_FX_DEBUG_VIEW_Profiling:
  775. {
  776. ICVar* r_displayInfoCVar = gEnv->pConsole->GetCVar("r_DisplayInfo");
  777. if(r_displayInfoCVar)
  778. {
  779. r_displayInfoCVar->Set(0);
  780. }
  781. break;
  782. }
  783. }
  784. }
  785. #endif
  786. //--------------------------------------------------------------------------------------------------
  787. //--------------------------------------------------------------------------------------------------
  788. // Name: RegisterEffectDebugData
  789. // Desc: Registers effect's debug data with the game effects system, which will then call the
  790. // relevant debug callback functions for the for the effect when its selected using the
  791. // s_currentDebugEffectId
  792. //--------------------------------------------------------------------------------------------------
  793. #if DEBUG_GAME_FX_SYSTEM
  794. void CGameEffectsSystem::RegisterEffectDebugData( DebugOnInputEventCallback inputEventCallback,
  795. DebugDisplayCallback displayCallback,
  796. const char* effectName)
  797. {
  798. s_effectDebugList.push_back(SEffectDebugData(inputEventCallback,displayCallback,effectName));
  799. }
  800. #endif
  801. //--------------------------------------------------------------------------------------------------