screenfademanager.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /*
  2. ** Command & Conquer Renegade(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. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Combat *
  23. * *
  24. * $Archive:: /Commando/Code/Combat/screenfademanager.cpp $*
  25. * *
  26. * Original Author:: Greg Hjelstrom *
  27. * *
  28. * $Author:: Byon_g $*
  29. * *
  30. * $Modtime:: 1/17/02 12:09p $*
  31. * *
  32. * $Revision:: 8 $*
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  37. #include "screenfademanager.h"
  38. #include "render2d.h"
  39. #include "vector3.h"
  40. #include "timemgr.h"
  41. #include "chunkio.h"
  42. #include "debug.h"
  43. /**
  44. ** FloatInterpolatorClass
  45. ** This class can be used to manage a single floating point number which linearly
  46. ** interpolates towards target values that you give it.
  47. */
  48. class FloatInterpolatorClass
  49. {
  50. public:
  51. FloatInterpolatorClass(float init) { Value = init; TargetValue = init; Rate = 0.0f; }
  52. bool Save( ChunkSaveClass &csave );
  53. bool Load( ChunkLoadClass &cload );
  54. float Get_Value(void) const { return Value; }
  55. void Set_Target_Value(float new_val,float time);
  56. void Update(float dt);
  57. protected:
  58. float Value;
  59. float TargetValue;
  60. float Rate;
  61. };
  62. /*
  63. **
  64. */
  65. enum {
  66. CHUNKID_VARIABLES = 117021207,
  67. MICROCHUNKID_VALUE = 1,
  68. MICROCHUNKID_TARGET_VALUE,
  69. MICROCHUNKID_RATE,
  70. };
  71. /*
  72. **
  73. */
  74. bool FloatInterpolatorClass::Save( ChunkSaveClass &csave )
  75. {
  76. csave.Begin_Chunk( CHUNKID_VARIABLES );
  77. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_VALUE, Value );
  78. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_TARGET_VALUE, TargetValue );
  79. WRITE_MICRO_CHUNK( csave, MICROCHUNKID_RATE, Rate );
  80. csave.End_Chunk();
  81. return true;
  82. }
  83. bool FloatInterpolatorClass::Load( ChunkLoadClass &cload )
  84. {
  85. while (cload.Open_Chunk()) {
  86. switch(cload.Cur_Chunk_ID()) {
  87. case CHUNKID_VARIABLES:
  88. while (cload.Open_Micro_Chunk()) {
  89. switch(cload.Cur_Micro_Chunk_ID()) {
  90. READ_MICRO_CHUNK( cload, MICROCHUNKID_VALUE, Value );
  91. READ_MICRO_CHUNK( cload, MICROCHUNKID_TARGET_VALUE, TargetValue );
  92. READ_MICRO_CHUNK( cload, MICROCHUNKID_RATE, Rate );
  93. default:
  94. Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  95. break;
  96. }
  97. cload.Close_Micro_Chunk();
  98. }
  99. break;
  100. default:
  101. Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  102. break;
  103. }
  104. cload.Close_Chunk();
  105. }
  106. return true;
  107. }
  108. void FloatInterpolatorClass::Set_Target_Value(float new_val,float time)
  109. {
  110. TargetValue = new_val;
  111. if (time < WWMATH_EPSILON) {
  112. Value = new_val;
  113. Rate = 0.0f;
  114. } else {
  115. Rate = (new_val - Value)/time;
  116. }
  117. }
  118. void FloatInterpolatorClass::Update(float dt)
  119. {
  120. float step = Rate * dt;
  121. if (WWMath::Fabs(step) > WWMath::Fabs(TargetValue - Value)) {
  122. Value = TargetValue;
  123. } else {
  124. Value += step;
  125. }
  126. }
  127. /*
  128. ** Static variables
  129. */
  130. static FloatInterpolatorClass _LetterboxFraction(0.0f);
  131. static FloatInterpolatorClass _OverlayOpacity(0.0f);
  132. static FloatInterpolatorClass _OverlayRed(0.0f);
  133. static FloatInterpolatorClass _OverlayGreen(0.0f);
  134. static FloatInterpolatorClass _OverlayBlue(0.0f);
  135. static Render2DClass * _Renderer = NULL;
  136. /*
  137. ** Constants
  138. */
  139. const float LETTERBOX_SIZE = 0.125f;
  140. const Vector3 BLACK(0,0,0);
  141. const Vector3 WHITE(0,0,0);
  142. /*
  143. ** ScreenFadeManager implementation
  144. */
  145. void ScreenFadeManager::Init()
  146. {
  147. _Renderer = new Render2DClass();
  148. _Renderer->Set_Coordinate_Range( Render2DClass::Get_Screen_Resolution() );
  149. _Renderer->Enable_Alpha( true );
  150. _Renderer->Set_Coordinate_Range(RectClass(0,0,1,1));
  151. }
  152. void ScreenFadeManager::Shutdown()
  153. {
  154. delete _Renderer;
  155. _Renderer = NULL;
  156. }
  157. void ScreenFadeManager::Think()
  158. {
  159. /*
  160. ** Update the parameters
  161. */
  162. float seconds = TimeManager::Get_Frame_Seconds();
  163. _LetterboxFraction.Update(seconds);
  164. _OverlayOpacity.Update(seconds);
  165. _OverlayRed.Update(seconds);
  166. _OverlayGreen.Update(seconds);
  167. _OverlayBlue.Update(seconds);
  168. /*
  169. ** Build the letterbox polys
  170. */
  171. _Renderer->Reset();
  172. if (_OverlayOpacity.Get_Value() > 0.0f) {
  173. float r = _OverlayRed.Get_Value();
  174. float g = _OverlayGreen.Get_Value();
  175. float b = _OverlayBlue.Get_Value();
  176. float a = _OverlayOpacity.Get_Value();
  177. _Renderer->Add_Quad(RectClass(-1.0f,-1.0f,1.0f,1.0f),FRGBA_TO_INT32(r,g,b,a));
  178. }
  179. if (_LetterboxFraction.Get_Value() > 0.0f) {
  180. float lsize = _LetterboxFraction.Get_Value() * LETTERBOX_SIZE;
  181. _Renderer->Add_Quad(RectClass(0.0f,0.0f,1.0f,lsize),RGB_TO_INT32(0,0,0));
  182. _Renderer->Add_Quad(RectClass(0.0f,1.0f - lsize,1.0f,1.0f),RGB_TO_INT32(0,0,0));
  183. }
  184. }
  185. void ScreenFadeManager::Render()
  186. {
  187. _Renderer->Render();
  188. }
  189. void ScreenFadeManager::Enable_Letterbox(bool onoff, float time)
  190. {
  191. float new_val = (onoff ? 1.0f : 0.0f);
  192. _LetterboxFraction.Set_Target_Value(new_val,time);
  193. }
  194. void ScreenFadeManager::Set_Screen_Overlay_Color(const Vector3 & color,float time)
  195. {
  196. _OverlayRed.Set_Target_Value(WWMath::Clamp(color.X),time);
  197. _OverlayGreen.Set_Target_Value(WWMath::Clamp(color.Y),time);
  198. _OverlayBlue.Set_Target_Value(WWMath::Clamp(color.Z),time);
  199. }
  200. void ScreenFadeManager::Set_Screen_Overlay_Color(float r,float g, float b,float time)
  201. {
  202. _OverlayRed.Set_Target_Value(WWMath::Clamp(r),time);
  203. _OverlayGreen.Set_Target_Value(WWMath::Clamp(g),time);
  204. _OverlayBlue.Set_Target_Value(WWMath::Clamp(b),time);
  205. }
  206. void ScreenFadeManager::Set_Screen_Overlay_Opacity(float opacity,float time)
  207. {
  208. _OverlayOpacity.Set_Target_Value(opacity,time);
  209. }
  210. /*
  211. **
  212. */
  213. enum {
  214. CHUNKID_LETTERBOX_FRACTION = 117021200,
  215. CHUNKID_OVERLAY_OPACITY,
  216. CHUNKID_OVERLAY_RED,
  217. CHUNKID_OVERLAY_GREEN,
  218. CHUNKID_OVERLAY_BLUE,
  219. };
  220. /*
  221. **
  222. */
  223. bool ScreenFadeManager::Save( ChunkSaveClass &csave )
  224. {
  225. csave.Begin_Chunk( CHUNKID_LETTERBOX_FRACTION );
  226. _LetterboxFraction.Save( csave );
  227. csave.End_Chunk();
  228. csave.Begin_Chunk( CHUNKID_OVERLAY_OPACITY );
  229. _OverlayOpacity.Save( csave );
  230. csave.End_Chunk();
  231. csave.Begin_Chunk( CHUNKID_OVERLAY_RED );
  232. _OverlayRed.Save( csave );
  233. csave.End_Chunk();
  234. csave.Begin_Chunk( CHUNKID_OVERLAY_GREEN );
  235. _OverlayGreen.Save( csave );
  236. csave.End_Chunk();
  237. csave.Begin_Chunk( CHUNKID_OVERLAY_BLUE );
  238. _OverlayBlue.Save( csave );
  239. csave.End_Chunk();
  240. return true;
  241. }
  242. bool ScreenFadeManager::Load( ChunkLoadClass &cload )
  243. {
  244. while (cload.Open_Chunk()) {
  245. switch(cload.Cur_Chunk_ID()) {
  246. case CHUNKID_LETTERBOX_FRACTION:
  247. _LetterboxFraction.Load( cload );
  248. break;
  249. case CHUNKID_OVERLAY_OPACITY:
  250. _OverlayOpacity.Load( cload );
  251. break;
  252. case CHUNKID_OVERLAY_RED:
  253. _OverlayRed.Load( cload );
  254. break;
  255. case CHUNKID_OVERLAY_GREEN:
  256. _OverlayGreen.Load( cload );
  257. break;
  258. case CHUNKID_OVERLAY_BLUE:
  259. _OverlayBlue.Load( cload );
  260. break;
  261. default:
  262. Debug_Say(("Unhandled Chunk:%d File:%s Line:%d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  263. break;
  264. }
  265. cload.Close_Chunk();
  266. }
  267. return true;
  268. }