ff7DataInstaller.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /*
  2. * Copyright (C) 2022 The V-Gears Team
  3. *
  4. * This file is part of V-Gears
  5. *
  6. * V-Gears is free software: you can redistribute it and/or modify it under
  7. * terms of the GNU General Public License as published by the Free Software
  8. * Foundation, version 3.0 (GPLv3) of the License.
  9. *
  10. * V-Gears 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. #pragma once
  16. #include <string>
  17. #include <vector>
  18. #include <iostream>
  19. #include "common/make_unique.h"
  20. #include "common/VGearsApplication.h"
  21. #include "common/FinalFantasy7/FF7NameLookup.h"
  22. #include "data/VGearsTriggersFile.h"
  23. #include "common/VGearsStringUtil.h"
  24. #include "data/VGearsFLevelFile.h"
  25. #include "ff7FieldTextWriter.h"
  26. // TODO: Separate classes in files.
  27. // TODO: Move implementations to cpp file.
  28. /**
  29. * Handles a scoped LGP archive.
  30. */
  31. class ScopedLgp{
  32. public:
  33. /**
  34. * Constructor.
  35. *
  36. * Don't use directly.
  37. */
  38. ScopedLgp(const ScopedLgp&) = delete;
  39. /**
  40. * Copy constructor.
  41. *
  42. * Don't use directly.
  43. */
  44. ScopedLgp& operator = (const ScopedLgp&) = delete;
  45. /**
  46. * Constructor.
  47. */
  48. ScopedLgp(
  49. Ogre::Root* root, std::string full_path,
  50. std::string type, std::string group
  51. ) : root_(root), full_path_(full_path), group_(group) {
  52. if (root_){
  53. std::cout << "[RESOURCE] " << full_path_ << ", "
  54. << type << ", " << group_ << std::endl;
  55. Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
  56. full_path_, type, group_
  57. );
  58. }
  59. }
  60. /**
  61. * Destructor.
  62. */
  63. ~ScopedLgp(){
  64. if (root_){
  65. Ogre::ResourceGroupManager::getSingleton()
  66. .removeResourceLocation(full_path_, group_);
  67. }
  68. }
  69. private:
  70. /**
  71. * The Ogre root system.
  72. */
  73. Ogre::Root* root_;
  74. /**
  75. * Full path to the LGP archive.
  76. */
  77. std::string full_path_;
  78. /**
  79. * Group for the resource.
  80. */
  81. std::string group_;
  82. };
  83. typedef std::set<std::string> MapCollection;
  84. /**
  85. * A database of spawn points.
  86. */
  87. class SpawnPointDb{
  88. public:
  89. /**
  90. * Field IDs.
  91. *
  92. * ID of the field the gateways records from N other number of fields
  93. * are linking to.
  94. */
  95. u16 target_field_id = 0;
  96. /**
  97. * A spawn point database record.
  98. */
  99. class Record{
  100. public:
  101. /**
  102. * Field that links to {@see SpawnPointDb::target_field_id}.
  103. */
  104. u16 field_id = 0;
  105. /**
  106. * Index of the gateway in {@see field_id}.
  107. */
  108. u32 gateway_index_or_map_jump_address = 0;
  109. /**
  110. * Gateway data.
  111. */
  112. VGears::TriggersFile::Gateway gateway;
  113. /**
  114. * Indicates if the gateway is a map jump from a script.
  115. */
  116. bool from_script = false;
  117. /**
  118. * @todo Understand and document.
  119. *
  120. * Only used from script calls.
  121. */
  122. std::string entity_name;
  123. /**
  124. * @todo Understand and document.
  125. *
  126. * Only used from script calls.
  127. */
  128. std::string script_function_name;
  129. };
  130. /**
  131. * List of gateways to this field.
  132. */
  133. std::vector<Record> gateways_to_this_field;
  134. };
  135. typedef std::map<u16, SpawnPointDb> FieldSpawnPointsMap;
  136. typedef std::map<u16, float> FieldScaleFactorMap;
  137. typedef std::map<std::string, std::set<std::string>> ModelAnimationMap;
  138. /**
  139. * Database of model animations.
  140. */
  141. class ModelsAndAnimationsDb{
  142. public:
  143. /**
  144. * Normalizes an animation name.
  145. *
  146. * Generates a normalized file name, without path, lowercase, and an
  147. * '.a' extension.
  148. *
  149. * @param name[in] Current name.
  150. * @return The normalized name.
  151. */
  152. std::string NormalizeAnimationName(const std::string& name){
  153. Ogre::String base_name;
  154. VGears::StringUtil::splitBase(name, base_name);
  155. std::transform(
  156. base_name.begin(), base_name.end(), base_name.begin(), ::tolower
  157. );
  158. return base_name + ".a";
  159. }
  160. /**
  161. * @todo Understand and document.
  162. *
  163. * @param model[in] @todo Understand and document.
  164. * @return @todo Understand and document.
  165. */
  166. std::set<std::string>& ModelAnimations(const std::string model){
  167. // HACK FIX LGP READING
  168. std::string model_lower = model;
  169. std::transform(
  170. model_lower.begin(), model_lower.end(),
  171. model_lower.begin(), ::tolower
  172. );
  173. return map[model_lower];
  174. }
  175. /**
  176. * Retrieves the metadata file name associated to a model.
  177. *
  178. * @param model_name[in] The model name.
  179. * @return Name of the metadata file.
  180. */
  181. std::string ModelMetaDataName(const std::string& model_name){
  182. // If not in meta data then just replace .hrc with .mesh.
  183. Ogre::String base_name;
  184. VGears::StringUtil::splitBase(model_name, base_name);
  185. return VGears::FF7::NameLookup::model(base_name) + ".mesh";
  186. }
  187. //private:
  188. ModelAnimationMap map;
  189. };
  190. /**
  191. * The data installer.
  192. */
  193. class FF7DataInstaller{
  194. public:
  195. static float LINE_SCALE_FACTOR;
  196. /**
  197. * Installer constructor
  198. *
  199. * @param input_dir[in] Path to the directory containing the original
  200. * data to parse.
  201. * @param output_dir[in] Path to the directory to write generated data
  202. * to.
  203. * @param write_output_line Pointer to function to write output.
  204. */
  205. FF7DataInstaller(
  206. std::string input_dir, std::string output_dir,
  207. std::function<void(std::string)> write_output_line
  208. );
  209. /**
  210. * Installer destructor.
  211. */
  212. ~FF7DataInstaller();
  213. /**
  214. * Handle the installation progress.
  215. *
  216. * @return Installation progress [0-100].
  217. */
  218. int Progress();
  219. private:
  220. /**
  221. * Calculates the installation progress.
  222. *
  223. * @return Installation progress [0-100]
  224. */
  225. int CalcProgress();
  226. /**
  227. * Creates a directory in the outputh path.
  228. *
  229. * @param dir[in] Path of the directory to create, relative to the
  230. * output path..
  231. * @throws std::runtime_error If the directory can't be created.
  232. */
  233. void CreateDir(const std::string& dir);
  234. /**
  235. * Initializer for {@see CollectionFieldSpawnAndScaleFactors}.
  236. *
  237. * Installation step 1.
  238. */
  239. void InitCollectSpawnAndScaleFactors();
  240. /**
  241. * Reads spawn points and scale factors from flevel files.
  242. *
  243. * Installation step 2.
  244. */
  245. void CollectionFieldSpawnAndScaleFactors();
  246. /**
  247. * Converts FFVII PC fields to V-Gears format.
  248. */
  249. void ConvertFieldsIteration();
  250. /**
  251. * Initializer for {@see WriteMapsXmlIteration}.
  252. *
  253. * Installation step 3.
  254. */
  255. void WriteMapsXmlBegin();
  256. /**
  257. * Saves the game maps to XML files.
  258. *
  259. * Installation step 4.
  260. */
  261. void WriteMapsXmlIteration();
  262. /**
  263. * Cleans up after {@see WriteMapsXmlIteration}.
  264. *
  265. * Installation step 5.
  266. */
  267. void EndWriteMapsXml();
  268. /**
  269. * Initializer for {@see ConvertFieldModelsIteration}.
  270. *
  271. * Installation step 6.
  272. */
  273. void ConvertFieldModelsBegin();
  274. /**
  275. * Converts the field models to V-Gears format.
  276. *
  277. * Installation step 7 and final.
  278. */
  279. void ConvertFieldModelsIteration();
  280. /**
  281. * Installation steps.
  282. */
  283. enum InstallationSteps{
  284. /**
  285. * Installation not started.
  286. */
  287. IDLE = 0,
  288. /**
  289. * Initializer for {@see SPAWN_POINTS_AND_SCALE_FACTORS}.
  290. */
  291. SPAWN_POINTS_AND_SCALE_FACTORS_INIT = 1,
  292. /**
  293. * Step that collects spawn points and sclae factors.
  294. */
  295. SPAWN_POINTS_AND_SCALE_FACTORS = 2,
  296. /**
  297. * Step that convets fields to V-Gears format.
  298. */
  299. CONVERT_FIELDS = 3,
  300. /**
  301. * Initializer for {@see WRITE_MAPS}.
  302. */
  303. WRITE_MAPS_INIT = 4,
  304. /**
  305. * Step that writes XML maps.
  306. */
  307. WRITE_MAPS = 5,
  308. /**
  309. * Clean up after {@see WRITE_MAPS}.
  310. */
  311. WRITE_MAPS_CLEAN = 6,
  312. /**
  313. * Initializer for {@see CONVERT_FIELD_MODELS}.
  314. */
  315. CONVERT_FIELD_MODELS_INIT = 7,
  316. /**
  317. * Step that converts field models.
  318. */
  319. CONVERT_FIELD_MODELS = 8,
  320. /**
  321. * Number of installation steps.
  322. */
  323. STATE_COUNT,
  324. /**
  325. * Installation finished.
  326. */
  327. DONE = 100,
  328. };
  329. /**
  330. * Current installation status.
  331. */
  332. InstallationSteps installation_state_ = IDLE;
  333. /**
  334. * The path to the directory from which to read the PC game data.
  335. */
  336. std::string input_dir_;
  337. /**
  338. * The path to the directory where to sve the V-Gears data.
  339. */
  340. std::string output_dir_;
  341. /**
  342. * The installer application.
  343. *
  344. * It's a singleton so it can't be recreated. It will crash the second
  345. * time round.
  346. */
  347. VGears::Application application_;
  348. /**
  349. * LGP archive with field data.
  350. */
  351. std::unique_ptr<ScopedLgp> fields_lgp_;
  352. /**
  353. * LGP archive with texture data.
  354. */
  355. std::unique_ptr<ScopedLgp> textures_lgp_;
  356. /**
  357. * LGP archive with field model data.
  358. */
  359. std::unique_ptr<ScopedLgp> field_models_lgp_;
  360. /**
  361. * List of flevel files.
  362. */
  363. Ogre::StringVectorPtr flevel_file_list_;
  364. /**
  365. * The list of maps.
  366. */
  367. std::vector<std::string> map_list_;
  368. /**
  369. * Map of the collected spawn points.
  370. */
  371. FieldSpawnPointsMap spawn_points_;
  372. /**
  373. * Map of th collected scale factors.
  374. */
  375. FieldScaleFactorMap scale_factors_;
  376. /**
  377. * ModelsAndAnimationsUsedByConvertedFields
  378. */
  379. ModelsAndAnimationsDb used_models_and_anims_;
  380. /**
  381. * List of converted maps.
  382. */
  383. MapCollection converted_map_list_;
  384. /**
  385. * Iterator for {@see converted_map_list}.
  386. */
  387. MapCollection::iterator converted_map_list_iterator_;
  388. /**
  389. * Iterator counter.
  390. */
  391. size_t iterator_counter_;
  392. /**
  393. * Helper variable to indicate internal progress of installation steps.
  394. */
  395. size_t conversion_step_;
  396. /**
  397. * Helper variable to indicate internal progress of installation steps.
  398. */
  399. size_t progress_step_num_elements_;
  400. /**
  401. * Field currently being processed.
  402. */
  403. VGears::FLevelFilePtr field_;
  404. /**
  405. * List of model files.
  406. */
  407. Ogre::StringVectorPtr field_model_file_list_;
  408. /**
  409. * An XML document.
  410. *
  411. * Internally used during some installation steps.
  412. */
  413. std::unique_ptr<TiXmlDocument> doc_;
  414. /**
  415. * An XML element.
  416. *
  417. * Internally used during some installation steps.
  418. */
  419. std::unique_ptr<TiXmlElement> element_;
  420. /**
  421. * Iterator for {@see used_models_and_anims_}.
  422. */
  423. ModelAnimationMap::iterator model_animation_map_iterator_;
  424. /**
  425. * Function used to print text.
  426. */
  427. std::function<void(std::string)> write_output_line;
  428. /**
  429. * Field text writer.
  430. */
  431. FF7FieldTextWriter field_text_writer_;
  432. /**
  433. * Written materials.
  434. */
  435. std::vector<std::string> materials_;
  436. };