modpackagemgr.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  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 : commando *
  23. * *
  24. * $Archive:: /Commando/Code/Commando/modpackagemgr.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 7/09/02 11:13a $*
  29. * *
  30. * $Revision:: 5 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "modpackagemgr.h"
  36. #include "registry.h"
  37. #include "_globals.h"
  38. #include "realcrc.h"
  39. #include "ffactorylist.h"
  40. #include "ffactory.h"
  41. #include "mixfile.h"
  42. #include "gametype.h"
  43. /////////////////////////////////////////////////////////////////////
  44. // Local constants
  45. /////////////////////////////////////////////////////////////////////
  46. static const char * CURR_MOD_REG_VALUE = "CurrModPackage";
  47. //////////////////////////////////////////////////////////////////////
  48. // Static member initialization
  49. //////////////////////////////////////////////////////////////////////
  50. DynamicVectorClass<ModPackageClass> ModPackageMgrClass::PackageList;
  51. ModPackageClass ModPackageMgrClass::CurrentPackage;
  52. /////////////////////////////////////////////////////////////////////
  53. //
  54. // Initialize
  55. //
  56. //////////////////////////////////////////////////////////////////////
  57. void
  58. ModPackageMgrClass::Initialize (void)
  59. {
  60. Shutdown ();
  61. // (gth) Day 120 patch, don't re-load the package name from the registry
  62. #if 0
  63. //
  64. // Get the currently selected package name from the registry
  65. //
  66. RegistryClass registry (APPLICATION_SUB_KEY_NAME_OPTIONS);
  67. if (registry.Is_Valid ()) {
  68. //
  69. // Get the current package name from the registry
  70. //
  71. StringClass package_filename;
  72. registry.Get_String (CURR_MOD_REG_VALUE, package_filename, "");
  73. //
  74. // Initialize the current package
  75. //
  76. CurrentPackage.Set_Package_Filename (package_filename);
  77. }
  78. #endif
  79. return ;
  80. }
  81. /////////////////////////////////////////////////////////////////////
  82. //
  83. // Shutdown
  84. //
  85. //////////////////////////////////////////////////////////////////////
  86. void
  87. ModPackageMgrClass::Shutdown (void)
  88. {
  89. Reset_List ();
  90. return ;
  91. }
  92. //////////////////////////////////////////////////////////////////////
  93. //
  94. // Build_List
  95. //
  96. //////////////////////////////////////////////////////////////////////
  97. void
  98. ModPackageMgrClass::Build_List (void)
  99. {
  100. WIN32_FIND_DATA find_info = { 0 };
  101. BOOL keep_going = TRUE;
  102. HANDLE file_find = NULL;
  103. //
  104. // Build a list of all the saved games we know about
  105. //
  106. for (file_find = ::FindFirstFile ("data\\*.pkg", &find_info);
  107. (file_find != INVALID_HANDLE_VALUE) && keep_going;
  108. keep_going = ::FindNextFile (file_find, &find_info))
  109. {
  110. //
  111. // Create the package from the data in this mix file
  112. //
  113. ModPackageClass package;
  114. package.Set_Package_Filename (find_info.cFileName);
  115. //
  116. // Add the package to our list
  117. //
  118. PackageList.Add (package);
  119. }
  120. if (file_find != INVALID_HANDLE_VALUE) {
  121. ::FindClose (file_find);
  122. }
  123. return ;
  124. }
  125. //////////////////////////////////////////////////////////////////////
  126. //
  127. // Reset_List
  128. //
  129. //////////////////////////////////////////////////////////////////////
  130. void
  131. ModPackageMgrClass::Reset_List (void)
  132. {
  133. PackageList.Delete_All ();
  134. return ;
  135. }
  136. //////////////////////////////////////////////////////////////////////
  137. //
  138. // Set_Current_Package
  139. //
  140. //////////////////////////////////////////////////////////////////////
  141. void
  142. ModPackageMgrClass::Set_Current_Package (const char *package_filename)
  143. {
  144. //
  145. // Initialize the current package
  146. //
  147. CurrentPackage.Set_Package_Filename (package_filename);
  148. //
  149. // Write the name of hte package to the registry
  150. //
  151. RegistryClass registry (APPLICATION_SUB_KEY_NAME_OPTIONS);
  152. if (registry.Is_Valid ()) {
  153. registry.Set_String (CURR_MOD_REG_VALUE, package_filename);
  154. }
  155. return ;
  156. }
  157. //////////////////////////////////////////////////////////////////////
  158. //
  159. // Set_Current_Package
  160. //
  161. //////////////////////////////////////////////////////////////////////
  162. void
  163. ModPackageMgrClass::Set_Current_Package (int index)
  164. {
  165. Set_Current_Package (PackageList[index].Get_Package_Filename ());
  166. return ;
  167. }
  168. //////////////////////////////////////////////////////////////////////
  169. //
  170. // Find_Package
  171. //
  172. //////////////////////////////////////////////////////////////////////
  173. ModPackageClass *
  174. ModPackageMgrClass::Find_Package (const char *name)
  175. {
  176. ModPackageClass *retval = NULL;
  177. //
  178. // Loop over all the packages in the list until we've found the
  179. // one we want
  180. //
  181. for (int index = 0; index < PackageList.Count (); index ++) {
  182. if (PackageList[index].Get_Package_Filename ().Compare_No_Case (name) == 0) {
  183. retval = &PackageList[index];
  184. }
  185. }
  186. return retval;
  187. }
  188. //////////////////////////////////////////////////////////////////////
  189. //
  190. // Get_Mod_Map_Name_From_CRC
  191. //
  192. //////////////////////////////////////////////////////////////////////
  193. bool
  194. ModPackageMgrClass::Get_Mod_Map_Name_From_CRC_Index
  195. (
  196. uint32 mod_file_crc,
  197. int map_index,
  198. StringClass * mod_name,
  199. StringClass * map_name
  200. )
  201. {
  202. bool retval = false;
  203. (*mod_name) = "";
  204. (*map_name) = "";
  205. //
  206. // Try to find the mod from its CRC
  207. //
  208. if (Find_Package_From_CRC (mod_file_crc, mod_name)) {
  209. //
  210. // Get a pointer to this mod package
  211. //
  212. ModPackageClass *package = ModPackageMgrClass::Find_Package (mod_name->Peek_Buffer ());
  213. if (package != NULL) {
  214. //
  215. // Get the list of maps in this mod
  216. //
  217. DynamicVectorClass<StringClass> list;
  218. package->Build_Level_List (list);
  219. //
  220. // Is this map index in the valid range for the list?
  221. //
  222. if (map_index >= 0 && map_index < list.Count ()) {
  223. (*map_name) = list[map_index];
  224. retval = true;
  225. }
  226. }
  227. }
  228. return retval;
  229. }
  230. //////////////////////////////////////////////////////////////////////
  231. //
  232. // Get_Mod_Map_Name_From_CRC
  233. //
  234. //////////////////////////////////////////////////////////////////////
  235. bool
  236. ModPackageMgrClass::Get_Mod_Map_Name_From_CRC
  237. (
  238. uint32 mod_name_crc,
  239. uint32 map_name_crc,
  240. StringClass * mod_name,
  241. StringClass * map_name
  242. )
  243. {
  244. bool retval = false;
  245. //
  246. // Is there a mod name we need to lookup, or is this just the mapname?
  247. //
  248. if (mod_name_crc == 0) {
  249. //
  250. // Try to find the map from its CRC
  251. //
  252. retval = Find_Filename_From_CRC ("*.mix", map_name_crc, map_name);
  253. } else {
  254. (*mod_name) = "";
  255. (*map_name) = "";
  256. //
  257. // Try to find the mod from its CRC
  258. //
  259. if (Find_Filename_From_CRC ("*.pkg", mod_name_crc, mod_name)) {
  260. //
  261. // Get a pointer to this mod package
  262. //
  263. ModPackageClass *package = ModPackageMgrClass::Find_Package (mod_name->Peek_Buffer ());
  264. if (package != NULL) {
  265. //
  266. // Try to find the map from its CRC inside the mod package
  267. //
  268. retval = package->Find_Map_From_CRC (map_name_crc, map_name);
  269. }
  270. }
  271. }
  272. return retval;
  273. }
  274. //////////////////////////////////////////////////////////////////////
  275. //
  276. // Find_Filename_From_CRC
  277. //
  278. //////////////////////////////////////////////////////////////////////
  279. bool
  280. ModPackageMgrClass::Find_Filename_From_CRC
  281. (
  282. const char * search_mask,
  283. uint32 filename_crc,
  284. StringClass * filename
  285. )
  286. {
  287. if (search_mask == NULL || filename == NULL) {
  288. return false;
  289. }
  290. bool retval = false;
  291. WIN32_FIND_DATA find_info = { 0 };
  292. BOOL keep_going = TRUE;
  293. HANDLE file_find = NULL;
  294. (*filename) = "";
  295. StringClass full_search_mask = "data\\";
  296. full_search_mask += search_mask;
  297. //
  298. // Build a list of all the saved games we know about
  299. //
  300. for (file_find = ::FindFirstFile (full_search_mask, &find_info);
  301. (file_find != INVALID_HANDLE_VALUE) && keep_going;
  302. keep_going = ::FindNextFile (file_find, &find_info))
  303. {
  304. //
  305. // Is this the map we were looking for?
  306. //
  307. if (::CRC_Stringi (find_info.cFileName) == filename_crc) {
  308. //
  309. // Return the file name to the caller
  310. //
  311. (*filename) = find_info.cFileName;
  312. retval = true;
  313. break;
  314. }
  315. }
  316. if (file_find != INVALID_HANDLE_VALUE) {
  317. ::FindClose (file_find);
  318. }
  319. return retval;
  320. }
  321. //////////////////////////////////////////////////////////////////////
  322. //
  323. // Find_Package_From_CRC
  324. //
  325. //////////////////////////////////////////////////////////////////////
  326. bool
  327. ModPackageMgrClass::Find_Package_From_CRC
  328. (
  329. uint32 file_crc,
  330. StringClass * filename
  331. )
  332. {
  333. if (filename == NULL) {
  334. return false;
  335. }
  336. bool retval = false;
  337. //
  338. // Loop over all the packages
  339. //
  340. for (int index = 0; index < PackageList.Count (); index ++) {
  341. //
  342. // Does this package's CRC match the one we're looking for?
  343. //
  344. if (PackageList[index].Get_CRC () == file_crc) {
  345. (*filename) = PackageList[index].Get_Package_Filename ();
  346. retval = true;
  347. break;
  348. }
  349. }
  350. return retval;
  351. }
  352. //////////////////////////////////////////////////////////////////////
  353. //
  354. // Load_Current_Mod
  355. //
  356. //////////////////////////////////////////////////////////////////////
  357. void
  358. ModPackageMgrClass::Load_Current_Mod (void)
  359. {
  360. //
  361. // Return if there isn't a current mod selected
  362. //
  363. if (IS_SOLOPLAY || CurrentPackage.Get_Package_Filename ().Is_Empty ()) {
  364. return ;
  365. }
  366. FileFactoryListClass::Get_Instance ()->Remove_Temp_FileFactory ();
  367. FileFactoryListClass::Get_Instance ()->Add_Temp_FileFactory (new MixFileFactoryClass (CurrentPackage.Get_Package_Filename (), _TheFileFactory));
  368. return ;
  369. }
  370. //////////////////////////////////////////////////////////////////////
  371. //
  372. // Unload_Current_Mod
  373. //
  374. //////////////////////////////////////////////////////////////////////
  375. void
  376. ModPackageMgrClass::Unload_Current_Mod (void)
  377. {
  378. //
  379. // Return if there isn't a current mod selected
  380. //
  381. if ( CurrentPackage.Get_Package_Filename ().Is_Empty () ||
  382. FileFactoryListClass::Get_Instance () == NULL)
  383. {
  384. return ;
  385. }
  386. //
  387. // Delete the temp file factory
  388. //
  389. FileFactoryClass *factory = FileFactoryListClass::Get_Instance ()->Remove_Temp_FileFactory ();
  390. if (factory != NULL) {
  391. delete factory;
  392. factory = NULL;
  393. }
  394. return ;
  395. }