hanimmgr.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  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. /* $Header: /Commando/Code/ww3d2/hanimmgr.cpp 3 1/16/02 9:51a Jani_p $ */
  19. /***********************************************************************************************
  20. *** Confidential - Westwood Studios ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Commando / G 3D Library *
  24. * *
  25. * $Archive:: /Commando/Code/ww3d2/hanimmgr.cpp $*
  26. * *
  27. * Author:: Greg_h *
  28. * *
  29. * $Modtime:: 1/16/02 9:49a $*
  30. * *
  31. * $Revision:: 3 $*
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * HAnimManagerClass::HAnimManagerClass -- constructor *
  36. * HAnimManagerClass::~HAnimManagerClass -- destructor *
  37. * HAnimManagerClass::Load_Anim -- loads a set of motion data from a file *
  38. * HAnimManagerClass::Get_Anim_ID -- looks up the ID of a named Hierarchy Animation *
  39. * HAnimManagerClass::Get_Anim -- returns a pointer to the specified animation data *
  40. * HAnimManagerClass::Get_Anim -- returns a pointer to the specified Hierarchy Animation *
  41. * HAnimManagerClass::Free -- de-allocate all memory in use *
  42. * HAnimManagerClass::Free_All_Anims -- de-allocate all currently loaded animations *
  43. * HAnimManagerClass::Load_Raw_Anim -- Load a raw anim *
  44. * HAnimManagerClass::Load_Compressed_Anim -- load a compressed animation *
  45. * HAnimManagerClass::Add_Anim -- Adds an externally created animation to the manager *
  46. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  47. #include "hanimmgr.h"
  48. #include <string.h>
  49. #include "hanim.h"
  50. #include "hrawanim.h"
  51. #include "hcanim.h"
  52. #include "hmorphanim.h"
  53. #include "chunkio.h"
  54. #include "wwmemlog.h"
  55. #include "w3dexclusionlist.h"
  56. #include "animatedsoundmgr.h"
  57. /***********************************************************************************************
  58. * HAnimManagerClass::HAnimManagerClass -- constructor *
  59. * *
  60. * INPUT: *
  61. * *
  62. * OUTPUT: *
  63. * *
  64. * WARNINGS: *
  65. * *
  66. * HISTORY: *
  67. * 08/11/1997 GH : Created. *
  68. *=============================================================================================*/
  69. HAnimManagerClass::HAnimManagerClass(void)
  70. {
  71. // Create the hash tables
  72. AnimPtrTable = W3DNEW HashTableClass( 2048 );
  73. MissingAnimTable = W3DNEW HashTableClass( 2048 );
  74. }
  75. /***********************************************************************************************
  76. * HAnimManagerClass::~HAnimManagerClass -- destructor *
  77. * *
  78. * INPUT: *
  79. * *
  80. * OUTPUT: *
  81. * *
  82. * WARNINGS: *
  83. * *
  84. * HISTORY: *
  85. * 08/11/1997 GH : Created. *
  86. *=============================================================================================*/
  87. HAnimManagerClass::~HAnimManagerClass(void)
  88. {
  89. Free_All_Anims();
  90. Reset_Missing(); // Jani: Deleting missing animations as well
  91. delete AnimPtrTable;
  92. AnimPtrTable = NULL;
  93. Reset_Missing();
  94. delete MissingAnimTable;
  95. MissingAnimTable = NULL;
  96. }
  97. /***********************************************************************************************
  98. * HAnimManagerClass::Load_Anim -- loads a set of motion data from a file *
  99. * *
  100. * INPUT: *
  101. * *
  102. * OUTPUT: *
  103. * *
  104. * WARNINGS: *
  105. * *
  106. * HISTORY: *
  107. * 08/11/1997 GH : Created. *
  108. *=============================================================================================*/
  109. int HAnimManagerClass::Load_Anim(ChunkLoadClass & cload)
  110. {
  111. WWMEMLOG(MEM_ANIMATION);
  112. switch (cload.Cur_Chunk_ID())
  113. {
  114. case W3D_CHUNK_ANIMATION:
  115. return Load_Raw_Anim(cload);
  116. break;
  117. case W3D_CHUNK_COMPRESSED_ANIMATION:
  118. return Load_Compressed_Anim(cload);
  119. break;
  120. case W3D_CHUNK_MORPH_ANIMATION:
  121. return Load_Morph_Anim(cload);
  122. break;
  123. }
  124. return 0;
  125. }
  126. /***********************************************************************************************
  127. * HAnimManagerClass::Load_Morph_Anim -- Load a HMorphAnimClass *
  128. * *
  129. * INPUT: *
  130. * *
  131. * OUTPUT: *
  132. * *
  133. * WARNINGS: *
  134. * *
  135. * HISTORY: *
  136. * 5/23/2000 pds : Created. *
  137. *=============================================================================================*/
  138. int HAnimManagerClass::Load_Morph_Anim(ChunkLoadClass & cload)
  139. {
  140. HMorphAnimClass * newanim = W3DNEW HMorphAnimClass;
  141. if (newanim == NULL) {
  142. goto Error;
  143. }
  144. SET_REF_OWNER( newanim );
  145. if (newanim->Load_W3D(cload) != HMorphAnimClass::OK) {
  146. // load failed!
  147. newanim->Release_Ref();
  148. goto Error;
  149. } else if (Peek_Anim(newanim->Get_Name()) != NULL) {
  150. // duplicate exists!
  151. newanim->Release_Ref(); // Release the one we just loaded
  152. goto Error;
  153. } else {
  154. Add_Anim( newanim );
  155. newanim->Release_Ref();
  156. }
  157. return 0;
  158. Error:
  159. return 1;
  160. }
  161. /***********************************************************************************************
  162. * HAnimManagerClass::Load_Raw_Anim -- Load a raw anim *
  163. * *
  164. * INPUT: *
  165. * *
  166. * OUTPUT: *
  167. * *
  168. * WARNINGS: *
  169. * *
  170. * HISTORY: *
  171. * 5/23/2000 gth : Created. *
  172. *=============================================================================================*/
  173. int HAnimManagerClass::Load_Raw_Anim(ChunkLoadClass & cload)
  174. {
  175. HRawAnimClass * newanim = W3DNEW HRawAnimClass;
  176. if (newanim == NULL) {
  177. goto Error;
  178. }
  179. SET_REF_OWNER( newanim );
  180. if (newanim->Load_W3D(cload) != HRawAnimClass::OK) {
  181. // load failed!
  182. newanim->Release_Ref();
  183. goto Error;
  184. } else if (Peek_Anim(newanim->Get_Name()) != NULL) {
  185. // duplicate exists!
  186. newanim->Release_Ref(); // Release the one we just loaded
  187. goto Error;
  188. } else {
  189. Add_Anim( newanim );
  190. newanim->Release_Ref();
  191. }
  192. return 0;
  193. Error:
  194. return 1;
  195. }
  196. /***********************************************************************************************
  197. * HAnimManagerClass::Load_Compressed_Anim -- load a compressed animation *
  198. * *
  199. * INPUT: *
  200. * *
  201. * OUTPUT: *
  202. * *
  203. * WARNINGS: *
  204. * *
  205. * HISTORY: *
  206. * 5/23/2000 gth : Created. *
  207. *=============================================================================================*/
  208. int HAnimManagerClass::Load_Compressed_Anim(ChunkLoadClass & cload)
  209. {
  210. HCompressedAnimClass * newanim = W3DNEW HCompressedAnimClass;
  211. if (newanim == NULL) {
  212. goto Error;
  213. }
  214. SET_REF_OWNER( newanim );
  215. if (newanim->Load_W3D(cload) != HCompressedAnimClass::OK) {
  216. // load failed!
  217. newanim->Release_Ref();
  218. goto Error;
  219. } else if (Peek_Anim(newanim->Get_Name()) != NULL) {
  220. // duplicate exists!
  221. newanim->Release_Ref(); // Release the one we just loaded
  222. goto Error;
  223. } else {
  224. Add_Anim( newanim );
  225. newanim->Release_Ref();
  226. }
  227. return 0;
  228. Error:
  229. return 1;
  230. }
  231. /***********************************************************************************************
  232. * HAnimManagerClass::Peek_Anim -- returns a pointer to the specified animation data *
  233. * *
  234. * INPUT: *
  235. * *
  236. * OUTPUT: *
  237. * *
  238. * WARNINGS: *
  239. * *
  240. * HISTORY: *
  241. * 08/11/1997 GH : Created. *
  242. *=============================================================================================*/
  243. HAnimClass * HAnimManagerClass::Peek_Anim(const char * name)
  244. {
  245. return (HAnimClass*)AnimPtrTable->Find( name );
  246. }
  247. /***********************************************************************************************
  248. * HAnimManagerClass::Get_Anim -- returns a pointer to the specified animation data *
  249. * *
  250. * INPUT: *
  251. * *
  252. * OUTPUT: *
  253. * *
  254. * WARNINGS: *
  255. * *
  256. * HISTORY: *
  257. * 08/11/1997 GH : Created. *
  258. *=============================================================================================*/
  259. HAnimClass * HAnimManagerClass::Get_Anim(const char * name)
  260. {
  261. HAnimClass * anim = Peek_Anim( name );
  262. if ( anim != NULL ) {
  263. anim->Add_Ref();
  264. }
  265. return anim;
  266. }
  267. /***********************************************************************************************
  268. * HAnimManagerClass::Free_All_Anims -- de-allocate all currently loaded animations *
  269. * *
  270. * INPUT: *
  271. * *
  272. * OUTPUT: *
  273. * *
  274. * WARNINGS: *
  275. * *
  276. * HISTORY: *
  277. * 08/11/1997 GH : Created. *
  278. *=============================================================================================*/
  279. void HAnimManagerClass::Free_All_Anims(void)
  280. {
  281. // Make an iterator, and release all ptrs
  282. HAnimManagerIterator it( *this );
  283. for( it.First(); !it.Is_Done(); it.Next() ) {
  284. HAnimClass *anim = it.Get_Current_Anim();
  285. anim->Release_Ref();
  286. }
  287. // Then clear the table
  288. AnimPtrTable->Reset();
  289. }
  290. /***********************************************************************************************
  291. * HAnimManagerClass::Free_All_Anims_With_Exclusion_List -- release animations not in the list *
  292. * *
  293. * INPUT: *
  294. * *
  295. * OUTPUT: *
  296. * *
  297. * WARNINGS: *
  298. * *
  299. * HISTORY: *
  300. * 12/12/2002 GH : Created. *
  301. *=============================================================================================*/
  302. void HAnimManagerClass::Free_All_Anims_With_Exclusion_List(const W3DExclusionListClass & exclusion_list)
  303. {
  304. // Remove and Release_Ref any animation not in the exclusion list.
  305. HAnimManagerIterator it( *this );
  306. for( it.First(); !it.Is_Done(); it.Next() ) {
  307. HAnimClass *anim = it.Get_Current_Anim();
  308. if ((anim->Num_Refs() == 1) && (exclusion_list.Is_Excluded(anim) == false)) {
  309. //WWDEBUG_SAY(("deleting HAnim %s\n",anim->Get_Name()));
  310. AnimPtrTable->Remove(anim);
  311. anim->Release_Ref();
  312. }
  313. //else
  314. //{
  315. // WWDEBUG_SAY(("keeping HAnim %s (ref %d)\n",anim->Get_Name(),anim->Num_Refs()));
  316. //}
  317. }
  318. }
  319. /***********************************************************************************************
  320. * HAnimManagerClass::Create_Asset_List -- Create a list of the W3D files that are loaded *
  321. * *
  322. * INPUT: *
  323. * *
  324. * OUTPUT: *
  325. * *
  326. * WARNINGS: *
  327. * *
  328. * HISTORY: *
  329. * 12/12/2002 GH : Created. *
  330. *=============================================================================================*/
  331. void HAnimManagerClass::Create_Asset_List(DynamicVectorClass<StringClass> & exclusion_list)
  332. {
  333. HAnimManagerIterator it( *this );
  334. for( it.First(); !it.Is_Done(); it.Next() ) {
  335. HAnimClass *anim = it.Get_Current_Anim();
  336. // File that this anim came from should be the name after the '.'
  337. // Anims are named in the format: <skeleton>.<animname>
  338. const char * anim_name = anim->Get_Name();
  339. char * filename = strchr(anim_name,'.');
  340. if (filename != NULL) {
  341. exclusion_list.Add(StringClass(filename+1));
  342. }
  343. }
  344. }
  345. /***********************************************************************************************
  346. * HAnimManagerClass::Add_Anim -- Adds an externally created animation to the manager *
  347. * *
  348. * INPUT: *
  349. * *
  350. * OUTPUT: *
  351. * *
  352. * WARNINGS: *
  353. * *
  354. * HISTORY: *
  355. * 05/31/2000 PDS : Created. *
  356. *=============================================================================================*/
  357. bool HAnimManagerClass::Add_Anim(HAnimClass *new_anim)
  358. {
  359. WWASSERT (new_anim != NULL);
  360. // Increment the refcount on the W3DNEW animation and add it to our table.
  361. new_anim->Add_Ref ();
  362. AnimPtrTable->Add( new_anim );
  363. return true;
  364. }
  365. /*
  366. ** Missing Anims
  367. **
  368. ** The idea here, allow the system to register which anims are determined to be missing
  369. ** so that if they are asked for again, we can quickly return NULL, without searching the
  370. ** disk again.
  371. */
  372. void HAnimManagerClass::Register_Missing( const char * name )
  373. {
  374. MissingAnimTable->Add( W3DNEW MissingAnimClass( name ) );
  375. }
  376. bool HAnimManagerClass::Is_Missing( const char * name )
  377. {
  378. return ( MissingAnimTable->Find( name ) != NULL );
  379. }
  380. void HAnimManagerClass::Reset_Missing( void )
  381. {
  382. // Make an iterator, and release all ptrs
  383. HashTableIteratorClass it( *MissingAnimTable );
  384. for( it.First(); !it.Is_Done(); it.Next() ) {
  385. MissingAnimClass *missing = (MissingAnimClass *)it.Get_Current();
  386. delete missing;
  387. }
  388. // Then clear the table
  389. MissingAnimTable->Reset();
  390. }
  391. /*
  392. ** Iterator converter from HashableClass to HAnimClass
  393. */
  394. HAnimClass * HAnimManagerIterator::Get_Current_Anim( void )
  395. {
  396. return (HAnimClass *)Get_Current();
  397. }