UpdateModule.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: UpdateModule.cpp /////////////////////////////////////////////////////////////////////////
  24. // Author: Colin Day, September 2002
  25. // Desc: Update module base class
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  28. #include "PreRTS.h"
  29. #include "Common/Xfer.h"
  30. #include "GameLogic/GameLogic.h"
  31. #include "GameLogic/Module/UpdateModule.h"
  32. #ifdef _INTERNAL
  33. // for occasional debugging...
  34. //#pragma optimize("", off)
  35. //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
  36. #endif
  37. // ------------------------------------------------------------------------------------------------
  38. // ------------------------------------------------------------------------------------------------
  39. UpdateSleepTime UpdateModule::frameToSleepTime(
  40. UnsignedInt frame1,
  41. UnsignedInt frame2,
  42. UnsignedInt frame3,
  43. UnsignedInt frame4
  44. )
  45. {
  46. DEBUG_ASSERTCRASH(frame1 != 0 && frame2 != 0 && frame3 != 0 && frame4 != 0, ("probably should not pass zero to frameToSleepTime."));
  47. if (frame1 > frame2) frame1 = frame2;
  48. if (frame1 > frame3) frame1 = frame3;
  49. if (frame1 > frame4) frame1 = frame4;
  50. UnsignedInt now = TheGameLogic->getFrame();
  51. if (frame1 > now)
  52. {
  53. return UPDATE_SLEEP(frame1 - now);
  54. }
  55. else if (frame1 == now)
  56. {
  57. return UPDATE_SLEEP_NONE;
  58. }
  59. else
  60. {
  61. DEBUG_CRASH(("frameToSleepTime: frame is in the past. oops."));
  62. return UPDATE_SLEEP_NONE;
  63. }
  64. }
  65. // ------------------------------------------------------------------------------------------------
  66. // ------------------------------------------------------------------------------------------------
  67. UpdateSleepTime UpdateModule::getWakeFrame() const
  68. {
  69. UnsignedInt now = TheGameLogic->getFrame();
  70. UnsignedInt nextCallFrame = m_nextCallFrameAndPhase >> 2;
  71. if (nextCallFrame > now)
  72. return UPDATE_SLEEP(nextCallFrame - now);
  73. else
  74. return UPDATE_SLEEP_NONE;
  75. }
  76. // ------------------------------------------------------------------------------------------------
  77. // ------------------------------------------------------------------------------------------------
  78. void UpdateModule::setWakeFrame(Object* obj, UpdateSleepTime wakeDelay)
  79. {
  80. UnsignedInt now = TheGameLogic->getFrame();
  81. TheGameLogic->friend_awakenUpdateModule(obj, this, now + (UnsignedInt)wakeDelay);
  82. }
  83. // ------------------------------------------------------------------------------------------------
  84. /** CRC */
  85. // ------------------------------------------------------------------------------------------------
  86. void UpdateModule::crc( Xfer *xfer )
  87. {
  88. // extend base class
  89. BehaviorModule::crc( xfer );
  90. } // end crc
  91. // ------------------------------------------------------------------------------------------------
  92. /** Xfer method
  93. * Version Info;
  94. * 1: Initial version
  95. */
  96. // ------------------------------------------------------------------------------------------------
  97. void UpdateModule::xfer( Xfer *xfer )
  98. {
  99. // version
  100. const XferVersion currentVersion = 1;
  101. XferVersion version = currentVersion;
  102. xfer->xferVersion( &version, currentVersion );
  103. // extend base class
  104. BehaviorModule::xfer( xfer );
  105. #if defined(_DEBUG) || defined(_INTERNAL)
  106. /*
  107. this is a fix for the following scenario:
  108. save a game that has an object that uses module "FOO"
  109. now change the code for module "FOO" from being nonsleepy to being sleepy
  110. now reload that saved game
  111. as soon as "FOO" attempts to wake itself up, you're dead.
  112. this fix simply looks to see if the module in question is now sleepy in code,
  113. but was saved in sleepy form, and if so, quietly nudges a reasonable
  114. value into m_nextCallFrameAndPhase.
  115. */
  116. #define FIX_OLD_SAVES
  117. #endif
  118. #ifdef FIX_OLD_SAVES
  119. #ifdef ALLOW_NONSLEEPY_UPDATES
  120. Bool thisModuleIsNowSleepy = (m_nextCallFrameAndPhase != 0);
  121. #else
  122. const Bool thisModuleIsNowSleepy = true;
  123. #endif
  124. #endif
  125. // next call frame and phase
  126. xfer->xferUnsignedInt( &m_nextCallFrameAndPhase );
  127. if (xfer->getXferMode() == XFER_LOAD)
  128. {
  129. /*
  130. ensure the phase matches.
  131. pre-Jan 2, 2003:
  132. PHASE_INITIAL = 0,
  133. PHASE_NORMAL = 1,
  134. PHASE_FINAL = 2
  135. post-Jan 2, 2003:
  136. PHASE_INITIAL = 0,
  137. PHASE_PHYSICS = 1,
  138. PHASE_NORMAL = 2,
  139. PHASE_FINAL = 3
  140. */
  141. m_nextCallFrameAndPhase &= ~3;
  142. m_nextCallFrameAndPhase |= getUpdatePhase();
  143. }
  144. #ifdef FIX_OLD_SAVES
  145. if (xfer->getXferMode() == XFER_LOAD
  146. && thisModuleIsNowSleepy
  147. && m_nextCallFrameAndPhase == 0)
  148. {
  149. #ifdef ALLOW_NONSLEEPY_UPDATES
  150. // when the file was saved, this module was nonsleepy, but now it is sleepy.
  151. #else
  152. // note that 'm_nextCallFrameAndPhase' should only be zero for legacy save files.
  153. #endif
  154. friend_setNextCallFrame(TheGameLogic->getFrame());
  155. }
  156. #endif
  157. // m_indexInLogic is not saved -- it's restored in gamelogic::postprocess.
  158. if( xfer->getXferMode() == XFER_LOAD )
  159. {
  160. m_indexInLogic = -1;
  161. }
  162. } // end xfer
  163. // ------------------------------------------------------------------------------------------------
  164. /** Load post process */
  165. // ------------------------------------------------------------------------------------------------
  166. void UpdateModule::loadPostProcess( void )
  167. {
  168. // extned base class
  169. BehaviorModule::loadPostProcess();
  170. } // end loadPostProcess