ff7DataInstaller.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. #include "ff7DataInstaller.h"
  2. #include <boost/filesystem.hpp>
  3. #include <boost/program_options.hpp>
  4. #include <OgreConfigFile.h>
  5. #include <OgreArchiveManager.h>
  6. #include <OgreMeshSerializer.h>
  7. #include <OgreSkeletonSerializer.h>
  8. #include <OgreMeshManager.h>
  9. #include <OgreRenderWindow.h>
  10. #include <OgreHardwarePixelBuffer.h>
  11. #include "QGearsGameState.h"
  12. #include "data/QGearsAFileManager.h"
  13. #include "data/QGearsBackgroundFileManager.h"
  14. #include "data/QGearsCameraMatrixFileManager.h"
  15. #include "data/QGearsHRCFileManager.h"
  16. #include "data/QGearsLZSFLevelFileManager.h"
  17. #include "data/QGearsPaletteFileManager.h"
  18. #include "data/QGearsPFileManager.h"
  19. #include "data/QGearsRSDFileManager.h"
  20. #include "data/QGearsTexCodec.h"
  21. #include "map/QGearsBackground2DFileManager.h"
  22. #include "map/QGearsWalkmeshFileManager.h"
  23. #include "data/FF7ModelListFileManager.h"
  24. #include "data/QGearsLGPArchiveFactory.h"
  25. #include "common/QGearsStringUtil.h"
  26. #include "common/FF7NameLookup.h"
  27. #include "data/QGearsTexCodec.h"
  28. #include "decompiler/sudm.h"
  29. FF7DataInstaller::FF7DataInstaller()
  30. #ifdef _DEBUG
  31. : mApp("plugins_d.cfg", "resources_d.cfg", "install_d.log")
  32. #else
  33. : mApp("plugins.cfg", "resources.cfg", "install.log")
  34. #endif
  35. {
  36. mApp.initOgre(true);
  37. }
  38. FF7DataInstaller::~FF7DataInstaller()
  39. {
  40. }
  41. void FF7DataInstaller::Convert(std::string inputDir, std::string outputDir, const std::vector<std::string>& files)
  42. {
  43. for (const auto& file : files)
  44. {
  45. if (file == "field/char.lgp")
  46. {
  47. /*
  48. auto fullPath = inputDir + file;
  49. mApp.getRoot()->addResourceLocation(fullPath, "LGP", "FFVII");
  50. ConvertFieldModels(fullPath, outputDir);
  51. mApp.getRoot()->removeResourceLocation(fullPath, "FFVII");*/
  52. }
  53. else if (file == "field/flevel.lgp")
  54. {
  55. auto fullPath = inputDir + file;
  56. mApp.getRoot()->addResourceLocation(fullPath, "LGP", "FFVIIFields");
  57. ConvertFields(fullPath, outputDir);
  58. mApp.getRoot()->removeResourceLocation(fullPath, "FFVIIFields");
  59. }
  60. }
  61. }
  62. // TOOD: Share with pc model exporter
  63. static void exportMesh(std::string outdir, const Ogre::MeshPtr &mesh)
  64. {
  65. Ogre::MeshSerializer mesh_ser;
  66. mesh_ser.exportMesh(mesh.getPointer(), outdir + mesh->getName());
  67. Ogre::SkeletonPtr skeleton(mesh->getSkeleton());
  68. Ogre::SkeletonSerializer sk_ser;
  69. sk_ser.exportSkeleton(skeleton.getPointer(), outdir + skeleton->getName());
  70. Ogre::Mesh::SubMeshIterator it(mesh->getSubMeshIterator());
  71. Ogre::MaterialSerializer mat_ser;
  72. size_t i(0);
  73. while (it.hasMoreElements())
  74. {
  75. Ogre::SubMesh *sub_mesh(it.getNext());
  76. Ogre::MaterialPtr mat(Ogre::MaterialManager::getSingleton().getByName(sub_mesh->getMaterialName()));
  77. if (!mat.isNull())
  78. {
  79. mat_ser.queueForExport(mat);
  80. }
  81. ++i;
  82. }
  83. QGears::String base_name;
  84. QGears::StringUtil::splitFull(mesh->getName(), base_name);
  85. mat_ser.exportQueued(outdir + base_name + QGears::EXT_MATERIAL);
  86. }
  87. void FF7DataInstaller::ConvertFieldModels(std::string archive, std::string outDir)
  88. {
  89. Ogre::StringVectorPtr resources = mApp.ResMgr()->listResourceNames("FFVII", "*.hrc");
  90. for (auto& resourceName : *resources)
  91. {
  92. if (QGears::StringUtil::endsWith(resourceName, ".hrc"))
  93. {
  94. //try
  95. {
  96. Ogre::ResourcePtr hrc = QGears::HRCFileManager::getSingleton().load(resourceName, "FFVII");
  97. Ogre::String baseName;
  98. QGears::StringUtil::splitBase(resourceName, baseName);
  99. auto meshName = QGears::FF7::NameLookup::model(baseName) + ".mesh";
  100. Ogre::MeshPtr mesh(Ogre::MeshManager::getSingleton().load(meshName, "FFVII"));
  101. Ogre::SkeletonPtr skeleton(mesh->getSkeleton());
  102. exportMesh(outDir, mesh);
  103. }
  104. // catch (const Ogre::Exception& ex)
  105. {
  106. // std::cout << "ERROR converting: " << resourceName << " Exception: " << ex.what() << std::endl;
  107. }
  108. }
  109. }
  110. /*
  111. TODO:
  112. To figure out what .a files relate to which .hrc files, we need to enumerate every field
  113. and check its model loader data. These are always Idle, Walk, Run and then field specific
  114. ordering.
  115. Model loader is section 3 of the field file.
  116. */
  117. }
  118. class FF7FieldScriptFormatter : public SUDM::IScriptFormatter
  119. {
  120. public:
  121. virtual bool ExcludeFunction(const std::string& ) override
  122. {
  123. // Include everything for now
  124. return false;
  125. }
  126. virtual std::string RenameIdentifer(const std::string& name) override
  127. {
  128. // Don't rename anything for now
  129. return name;
  130. }
  131. };
  132. static void FF7PcFieldToQGearsField(QGears::FLevelFilePtr& field, const std::string& outDir)
  133. {
  134. // Save out the tiles as a PNG image
  135. const QGears::BackgroundFilePtr& bg = field->getBackground();
  136. try
  137. {
  138. // Get the raw script bytes
  139. const std::vector<u8> rawFieldData = field->getRawScript();
  140. // Decompile to LUA
  141. FF7FieldScriptFormatter formatter;
  142. std::string luaScript = SUDM::FF7::Field::Decompile(field->getName(), rawFieldData, formatter);
  143. std::cout << luaScript << std::endl;
  144. }
  145. catch (const ::InternalDecompilerError& ex)
  146. {
  147. std::cerr << "InternalDecompilerError: " << ex.what() << std::endl;
  148. }
  149. const QGears::PaletteFilePtr& pal = field->getPalette();
  150. std::unique_ptr<Ogre::Image> bgImage(bg->createImage(pal));
  151. bgImage->save(outDir + "/" + field->getName() + ".png");
  152. {
  153. TiXmlDocument doc;
  154. std::unique_ptr<TiXmlElement> element(new TiXmlElement("background2d"));
  155. auto& layers = bg->getLayers();
  156. const QGears::CameraMatrixFilePtr& camMatrix = field->getCameraMatrix();
  157. // TODO: Write out the *_BG.XML data
  158. for (auto& layer : layers)
  159. {
  160. // if (layer.enabled)
  161. {
  162. for (QGears::BackgroundFile::SpriteData& sprite : layer.sprites)
  163. {
  164. std::unique_ptr<TiXmlElement> xmlElement(new TiXmlElement("tile"));
  165. xmlElement->SetAttribute("destination", Ogre::StringConverter::toString(sprite.dst.x * 3) + " " + Ogre::StringConverter::toString(sprite.dst.y * 3));
  166. // Where to get UVs??
  167. //sprite.dst.x; layer.width
  168. //sprite.dst.y;
  169. // sprite.depth;
  170. // Where to get blend mode??
  171. element->LinkEndChild(xmlElement.release());
  172. }
  173. }
  174. }
  175. doc.LinkEndChild(element.release());
  176. doc.SaveFile(outDir + "/" + field->getName() + "_bg.xml");
  177. }
  178. {
  179. // Save out the walk mesh as XML
  180. const QGears::WalkmeshFilePtr& walkmesh = field->getWalkmesh();
  181. TiXmlDocument doc;
  182. std::unique_ptr<TiXmlElement> element(new TiXmlElement("walkmesh"));
  183. for (QGears::WalkmeshFile::Triangle& tri : walkmesh->getTriangles())
  184. {
  185. std::unique_ptr<TiXmlElement> xmlElement(new TiXmlElement("triangle"));
  186. xmlElement->SetAttribute("a", Ogre::StringConverter::toString(tri.a));
  187. xmlElement->SetAttribute("b", Ogre::StringConverter::toString(tri.b));
  188. xmlElement->SetAttribute("c", Ogre::StringConverter::toString(tri.c));
  189. xmlElement->SetAttribute("a_b", std::to_string(tri.access_side[0]));
  190. xmlElement->SetAttribute("b_c", std::to_string(tri.access_side[1]));
  191. xmlElement->SetAttribute("c_a", std::to_string(tri.access_side[2]));
  192. element->LinkEndChild(xmlElement.release());
  193. }
  194. doc.LinkEndChild(element.release());
  195. doc.SaveFile(outDir + "/" + field->getName() + "_wm.xml");
  196. }
  197. }
  198. void FF7DataInstaller::ConvertFields(std::string archive, std::string outDir)
  199. {
  200. // Everything in here is a field
  201. Ogre::StringVectorPtr resources = mApp.ResMgr()->listResourceNames("FFVIIFields", "*");
  202. for (auto& resourceName : *resources)
  203. {
  204. if (!QGears::StringUtil::endsWith(resourceName, ".tex")
  205. && !QGears::StringUtil::endsWith(resourceName, ".tut")
  206. && !QGears::StringUtil::endsWith(resourceName, ".siz")
  207. && resourceName != "maplist" && resourceName == "md1_2")
  208. {
  209. //try
  210. {
  211. QGears::FLevelFilePtr field = QGears::LZSFLevelFileManager::getSingleton().load(resourceName, "FFVIIFields").staticCast<QGears::FLevelFile>();
  212. FF7PcFieldToQGearsField(field, outDir);
  213. }
  214. /*
  215. catch (const Ogre::Exception& ex)
  216. {
  217. std::cout << "ERROR converting: " << resourceName << " Exception: " << ex.what() << std::endl;
  218. }
  219. catch (const std::exception& ex)
  220. {
  221. std::cout << "ERROR converting: " << resourceName << " Exception: " << ex.what() << std::endl;
  222. }*/
  223. }
  224. }
  225. }