ff7DataInstaller.h 13 KB

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