modpackage.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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/modpackage.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 2/14/02 4:09p $*
  29. * *
  30. * $Revision:: 6 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "modpackage.h"
  36. #include "init.h"
  37. #include "mixfile.h"
  38. #include "realcrc.h"
  39. #include "crc.h"
  40. #include "ffactory.h"
  41. #include "wwfile.h"
  42. //////////////////////////////////////////////////////////////////////
  43. //
  44. // ModPackageClass
  45. //
  46. //////////////////////////////////////////////////////////////////////
  47. ModPackageClass::ModPackageClass (void) :
  48. FileCRC (0)
  49. {
  50. return ;
  51. }
  52. //////////////////////////////////////////////////////////////////////
  53. //
  54. // ~ModPackageClass
  55. //
  56. //////////////////////////////////////////////////////////////////////
  57. ModPackageClass::~ModPackageClass (void)
  58. {
  59. return ;
  60. }
  61. //////////////////////////////////////////////////////////////////////
  62. //
  63. // Set_Package_Filename
  64. //
  65. //////////////////////////////////////////////////////////////////////
  66. void
  67. ModPackageClass::Set_Package_Filename (const char *name)
  68. {
  69. PackageFilename = name;
  70. //
  71. // Name the package from its filename minus the file extension.
  72. //
  73. StringClass temp_str = name;
  74. char *extension = ::strrchr (temp_str.Peek_Buffer (), '.');
  75. if (extension != NULL) {
  76. extension[0] = 0;
  77. Name = temp_str;
  78. } else {
  79. Name = name;
  80. }
  81. return ;
  82. }
  83. //////////////////////////////////////////////////////////////////////
  84. //
  85. // Build_Level_List
  86. //
  87. //////////////////////////////////////////////////////////////////////
  88. void
  89. ModPackageClass::Build_Level_List (DynamicVectorClass<StringClass> &list) const
  90. {
  91. MixFileFactoryClass factory (PackageFilename, &RenegadeBaseFileFactory);
  92. //
  93. // Get a list of all the files in this mix file
  94. //
  95. DynamicVectorClass<StringClass> files_in_mix;
  96. files_in_mix.Set_Growth_Step (1000);
  97. factory.Build_Filename_List (files_in_mix);
  98. //
  99. // Now, add any files that match the supplied wildcard to our master list
  100. //
  101. for (int file_index = 0; file_index < files_in_mix.Count (); file_index ++) {
  102. const char *filename = files_in_mix[file_index];
  103. StringClass temp_str (filename, true);
  104. ::strlwr (temp_str.Peek_Buffer ());
  105. //
  106. // Add this file to our list if it matches the mask
  107. //
  108. if (::strstr (filename, ".lsd") != 0) {
  109. list.Add (filename);
  110. }
  111. }
  112. return ;
  113. }
  114. //////////////////////////////////////////////////////////////////////
  115. //
  116. // Find_Map_From_CRC
  117. //
  118. //////////////////////////////////////////////////////////////////////
  119. bool
  120. ModPackageClass::Find_Map_From_CRC (uint32 crc, StringClass *map_name) const
  121. {
  122. bool retval = false;
  123. //
  124. // Build a list of levels inside this mod
  125. //
  126. DynamicVectorClass<StringClass> list;
  127. Build_Level_List (list);
  128. //
  129. // Check each level filename until we've found the one that
  130. // matches the CRC
  131. //
  132. for (int index = 0; index < list.Count (); index ++) {
  133. if (::CRC_Stringi (list[index]) == crc) {
  134. (*map_name) = list[index];
  135. retval = true;
  136. }
  137. }
  138. return retval;
  139. }
  140. //////////////////////////////////////////////////////////////////////
  141. //
  142. // Compute_CRC
  143. //
  144. //////////////////////////////////////////////////////////////////////
  145. void
  146. ModPackageClass::Compute_CRC (void)
  147. {
  148. FileCRC = 0;
  149. //
  150. // Get a file object for the package
  151. //
  152. FileClass *file = _TheFileFactory->Get_File (PackageFilename);
  153. if (file != NULL) {
  154. //
  155. // Open the file
  156. //
  157. if (file->Is_Available ()) {
  158. file->Open (FileClass::READ);
  159. CRCEngine crc_engine;
  160. //
  161. // Crc the contents of the file
  162. //
  163. int file_size = file->Size ();
  164. uint8 buffer[4096];
  165. while (file_size > 0) {
  166. //
  167. // Read the data from the source file
  168. //
  169. int bytes = min (file_size, (int)sizeof (buffer));
  170. int copied_size = file->Read (buffer, bytes);
  171. file_size -= copied_size;
  172. if (copied_size <= 0) {
  173. break;
  174. }
  175. //
  176. // Add this data to the CRC engine
  177. //
  178. crc_engine (buffer, copied_size);
  179. }
  180. //
  181. // Get the accumulated CRC result from the CRC engine
  182. //
  183. FileCRC = crc_engine ();
  184. //
  185. // Close the file
  186. //
  187. file->Close ();
  188. }
  189. //
  190. // Return the file
  191. //
  192. _TheFileFactory->Return_File (file);
  193. }
  194. return ;
  195. }
  196. //////////////////////////////////////////////////////////////////////
  197. //
  198. // Get_CRC
  199. //
  200. //////////////////////////////////////////////////////////////////////
  201. uint32
  202. ModPackageClass::Get_CRC (void)
  203. {
  204. if (FileCRC == 0) {
  205. Compute_CRC ();
  206. }
  207. return FileCRC;
  208. }
  209. //////////////////////////////////////////////////////////////////////
  210. //
  211. // Get_Map_Index
  212. //
  213. //////////////////////////////////////////////////////////////////////
  214. int
  215. ModPackageClass::Get_Map_Index (const char *map_name)
  216. {
  217. int retval = 0;
  218. //
  219. // Build the list of all maps in this mod
  220. //
  221. DynamicVectorClass<StringClass> list;
  222. Build_Level_List (list);
  223. //
  224. // Try to find the map in the list
  225. //
  226. for (int index = 0; index < list.Count (); index ++) {
  227. if (list[index].Compare_No_Case (map_name) == 0) {
  228. retval = index;
  229. break;
  230. }
  231. }
  232. return retval;
  233. }