소스 검색

Merge https://github.com/q-gears/q-gears

sithlord48 11 년 전
부모
커밋
0ef56c7d2a

+ 1 - 0
PlugIns/Data/CMakeLists.txt

@@ -68,6 +68,7 @@ include_directories(
     ${OGRE_SAMPLES_INCLUDEPATH}
     ${QGearsMain_SOURCE_DIR}/include
     ${CMAKE_CURRENT_SOURCE_DIR}/include
+    ${CMAKE_CURRENT_SOURCE_DIR}/../../dependencies
 )
 
 #defines

+ 6 - 2
QGearsMain/include/common/QGearsApplication.h

@@ -27,9 +27,14 @@ namespace QGears
     class Application : public Ogre::Singleton<Application>
     {
     public:
+        Application(Ogre::String pluginsFileName, Ogre::String resourcesFile, Ogre::String logFileName)
+            : m_plugins_filename(pluginsFileName), m_resources_filename(resourcesFile), m_log_filename(logFileName)
+        {
+
+        }
         Application( int argc, char *argv[] );
         virtual ~Application();
-        bool                initOgre( void );
+        bool                initOgre( bool hideWindow = false );
         Ogre::Root*         getRoot( void );
         Ogre::RenderWindow* getRenderWindow( void );
         const String&       getResourcesFilename( void );
@@ -46,7 +51,6 @@ namespace QGears
     private:
         typedef std::vector<std::shared_ptr<Ogre::ResourceManager>> ResourceManagerVector;
 
-        Application();
 
         static const char*      CLI_SECTION_GENERIC;
         static const char*      CLI_HELP;

+ 19 - 5
QGearsMain/src/common/QGearsApplication.cpp

@@ -72,7 +72,7 @@ namespace QGears
 
     //--------------------------------------------------------------------------
     bool
-    Application::initOgre()
+    Application::initOgre(bool hideWindow)
     {
         if( m_initialized )
         {
@@ -81,9 +81,12 @@ namespace QGears
 
         m_initialized = true;
 
-        if( !processCommandLine( m_argc, m_argv ) )
+        if (m_argc && m_argv)
         {
-            return false;
+            if (!processCommandLine(m_argc, m_argv))
+            {
+                return false;
+            }
         }
 
         m_root = std::make_unique<Ogre::Root>( m_plugins_filename, m_config_filename, m_log_filename );
@@ -98,11 +101,22 @@ namespace QGears
         // Show the configuration dialog and initialise the system
         // You can skip this and use root.restoreConfig() to load configuration
         // settings if you were sure there are valid ones saved in ogre.cfg
-        if( !m_root->restoreConfig() && !m_root->showConfigDialog() )
+        if(/* !m_root->restoreConfig() &&*/ !m_root->showConfigDialog() )
         {
             return false;
         }
-        m_render_window = m_root->initialise( true, getWindowTitle() );
+
+        if (hideWindow)
+        {
+            Ogre::NameValuePairList list;
+            list.emplace("hidden", "true");
+            m_root->initialise(false, getWindowTitle());
+            m_render_window = m_root->createRenderWindow(getWindowTitle(), 1, 1, false, &list);
+        }
+        else
+        {
+            m_render_window = m_root->initialise(true, getWindowTitle());
+        }
 
         registerArchiveFactories();
         loadResourcesConfig();

+ 1 - 1
QGearsMain/src/data/QGearsLGPArchive.cpp

@@ -73,7 +73,7 @@ namespace QGears
             file_info.uncompressedSize = it->data_size;
             file_info.compressedSize = file_info.uncompressedSize;
 
-            LOG_DEBUG( "add file:" + file_info.filename );
+            //LOG_DEBUG( "add file:" + file_info.filename );
             m_file_infos.push_back( file_info );
             ++it;
         }

+ 95 - 42
SupportedGames/FinalFantasy7/include/common/FF7NameLookup.h

@@ -18,72 +18,125 @@ GNU General Public License for more details.
 #define __FF7NameLookup_H__
 
 #include "common/TypeDefine.h"
+#include "common/QGearsStringUtil.h"
+#include "core/XmlFile.h"
 
 namespace QGears
 {
     namespace FF7
     {
-        class NameLookup
+        class FF7FiledModelsAndAnimationMetadata : public XmlFile
         {
         public:
-            NameLookup() = default;
-            virtual ~NameLookup() = default;
-
-            static const String& animation(const String &key)
+            FF7FiledModelsAndAnimationMetadata(Ogre::String file)
+                : XmlFile(file)
             {
-                return lookup(key, ms_animations);
+                TiXmlNode* node = m_File.RootElement();
+
+                if (node == nullptr || node->ValueStr() != "metadata")
+                {
+                    throw std::runtime_error("FF7FiledModelsAndAnimationMetadata: " + m_File.ValueStr() + " is not a valid metadata file! No <metadata> in root.");
+                }
+
+                node = node->FirstChild();
+                while (node)
+                {
+                    if (node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "models")
+                    {
+                        ReadModels(node->FirstChild());
+                    }
+                    else if (node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "animations")
+                    {
+                        ReadAnimations(node->FirstChild());
+                    }
+                    node = node->NextSibling();
+                }
             }
 
-            static const String& model(const String &key)
+            const String& Animation(const String &key) const
             {
-                return lookup(key, ms_models);
+                auto it = mAnimations.find(key);
+                if (it != std::end(mAnimations))
+                {
+                    return it->second;
+                }
+
+                String base_name;
+                StringUtil::splitBase(key, base_name);
+                it = mAnimations.find(base_name);
+                if (it != std::end(mAnimations))
+                {
+                    return it->second;
+                }
+                return key;
             }
 
-        protected:
-            typedef std::map<const String, const String>    LookupMap;
-
-            static LookupMap createAnimations()
+            const String& Model(const String &key) const
             {
-                LookupMap lookup;
-                lookup.insert(LookupMap::value_type("acfe", "Idle"));
-                lookup.insert(LookupMap::value_type("aaff", "Walk"));
-                lookup.insert(LookupMap::value_type("aaga", "Run"));
-                lookup.insert(LookupMap::value_type("bvjf", "JumpFromTrain"));
-
-                // barret
-                lookup.insert(LookupMap::value_type("adcb", "Idle"));
-                lookup.insert(LookupMap::value_type("adcc", "Walk"));
-                lookup.insert(LookupMap::value_type("adcd", "Run"));
-                lookup.insert(LookupMap::value_type("bwaa", "Invitation"));
-
-                // sd_red
-                lookup.insert(LookupMap::value_type("aeae", "Idle"));
-                lookup.insert(LookupMap::value_type("aeaf", "Walk"));
-                lookup.insert(LookupMap::value_type("aeba", "Run"));
-
-                return lookup;
+                auto it = mModels.find(key);
+                if (it != std::end(mModels))
+                {
+                    return it->second;
+                }
+
+                String base_name;
+                StringUtil::splitBase(key, base_name);
+                it = mModels.find(base_name);
+                if (it != std::end(mModels))
+                {
+                    return it->second;
+                }
+                return key;
             }
 
-            static LookupMap createModels()
+        private:
+            void ReadModels(TiXmlNode* node)
             {
-                LookupMap lookup;
-                lookup.insert(LookupMap::value_type("aaaa", "n_cloud"));
-                lookup.insert(LookupMap::value_type("adda", "sd_red"));
+                while (node)
+                {
+                    const auto src = GetString(node, "name");
+                    const auto dst = GetString(node, "target");
+                    mModels[src] = dst;
+                    node = node->NextSibling();
+                }
+            }
 
-                return lookup;
+            void ReadAnimations(TiXmlNode* node)
+            {
+                while (node)
+                {
+                    const auto src = GetString(node, "name");
+                    const auto dst = GetString(node, "target");
+                    mAnimations[src] = dst;
+                    node = node->NextSibling();
+                }
             }
 
-            static const String& lookup(const String &key, const LookupMap &data)
+            typedef std::map<String, String> LookupMap;
+            LookupMap mModels;
+            LookupMap mAnimations;
+        };
+
+        class NameLookup
+        {
+        public:
+            NameLookup() = delete;
+
+            static const String& animation(const String &key)
             {
-                LookupMap::const_iterator found(data.find(key));
-                if (found == data.end()) return key;
+                return Data().Animation(key);
+            }
 
-                return found->second;
+            static const String& model(const String &key)
+            {
+                return Data().Model(key);
             }
 
-        private:
-            static LookupMap  ms_animations;
-            static LookupMap  ms_models;
+            static FF7FiledModelsAndAnimationMetadata& Data()
+            {
+                static FF7FiledModelsAndAnimationMetadata data("field_models_and_animation_metadata.xml");
+                return data;
+            }
         };
     }
 }

+ 0 - 3
SupportedGames/FinalFantasy7/src/common/FF7NameLookup.cpp

@@ -15,6 +15,3 @@ GNU General Public License for more details.
 -----------------------------------------------------------------------------
 */
 #include "common/FF7NameLookup.h"
-
-QGears::FF7::NameLookup::LookupMap QGears::FF7::NameLookup::ms_animations(NameLookup::createAnimations());
-QGears::FF7::NameLookup::LookupMap QGears::FF7::NameLookup::ms_models(NameLookup::createModels());

+ 23 - 0
output/field_models_and_animation_metadata.xml

@@ -0,0 +1,23 @@
+<metadata>
+	<models>
+		<model name="aaaa" target="n_cloud"></model>
+		<model name="adda" target="sd_red"></model>
+	</models>
+    
+	<animations>
+		<animation name="acfe" target="Idle"></animation>
+		<animation name="aaff" target="Walk"></animation>
+		<animation name="aaga" target="Run"></animation>
+		<animation name="bvjf" target="JumpFromTrain"></animation>
+		
+		<animation name="adcb" target="Idle"></animation>
+		<animation name="adcc" target="Walk"></animation>
+		<animation name="adcd" target="Run"></animation>
+		<animation name="bwaa" target="Invitation"></animation>
+		
+		<animation name="aeae" target="Idle"></animation>
+		<animation name="aeaf" target="Walk"></animation>
+		<animation name="aeba" target="Run"></animation>
+	</animations>
+	
+</metadata>

+ 84 - 61
utilities/ffvii_field_model_exporter_pc/src/main.cpp

@@ -35,6 +35,7 @@ THE SOFTWARE.
 #include "data/QGearsAFileManager.h"
 #include "data/QGearsHRCFileManager.h"
 #include "data/QGearsLZSFLevelFileManager.h"
+#include "common/FF7NameLookup.h"
 
 void attachMesh( Ogre::MeshPtr &mesh )
 {
@@ -42,12 +43,12 @@ void attachMesh( Ogre::MeshPtr &mesh )
     Ogre::Entity* entity = scene_manager->createEntity( mesh );
     entity->setDisplaySkeleton( true );
     entity->setDebugDisplayEnabled( true );
-    entity->getAnimationState( "Idle" )->setEnabled( true );
-    entity->getAnimationState( "Idle" )->setLoop( true );
+   // entity->getAnimationState( "Idle" )->setEnabled( true );
+  //  entity->getAnimationState( "Idle" )->setLoop( true );
     Ogre::SceneNode* root_node = scene_manager->getRootSceneNode();
     root_node->showBoundingBox( true );
-    root_node->attachObject( entity );
-    entity->setVisible( false );
+   // root_node->attachObject( entity );
+    entity->setVisible( true );
 
     entitys.push_back( entity );
 }
@@ -79,62 +80,84 @@ void exportMesh( const Ogre::MeshPtr &mesh )
     mat_ser.exportQueued( base_name + QGears::EXT_MATERIAL );
 }
 
-int
-main( int argc, char *argv[] )
+
+
+int main( int argc, char *argv[] )
 {
-    QGears::FF7::FieldModelExporterPC app( argc, argv );
-    if( !app.initOgre() ) return 0;
-
-    Ogre::SceneManager*         scene_manager( Ogre::Root::getSingleton().getSceneManager( "Scene" ) );
-    QGears::AFilePtr            a;
-    QGears::HRCFilePtr          hrc = QGears::HRCFileManager::getSingleton().load( "adda.hrc", "FFVII" ).staticCast<QGears::HRCFile>();
-    QGears::AFileManager       &afl_mgr( QGears::AFileManager::getSingleton() );
-
-    Ogre::MeshPtr mesh( Ogre::MeshManager::getSingleton().load( "sd_red.mesh", "FFVII" ) );
-    Ogre::SkeletonPtr skeleton( mesh->getSkeleton() );
-
-    a = afl_mgr.load( "aeae.a", "FFVII" ).staticCast<QGears::AFile>();
-    a->addTo( skeleton, "Idle" );
-    a = afl_mgr.load( "aeaf.a", "FFVII" ).staticCast<QGears::AFile>();
-    a->addTo( skeleton, "Walk" );
-    a = afl_mgr.load( "aeba.a", "FFVII" ).staticCast<QGears::AFile>();
-    a->addTo( skeleton, "Run" );
-
-    attachMesh( mesh );
-    entitys[0]->setVisible( true );
-
-    QGears::LZSFLevelFileManager   &fmgr( QGears::LZSFLevelFileManager::getSingleton() );
-    QGears::FLevelFilePtr           f = fmgr.load( "ancnt1", "FFVII" ).staticCast<QGears::FLevelFile>();
-
-    mesh = Ogre::MeshManager::getSingleton().load( "n_cloud.mesh", "FFVII" );
-    skeleton = mesh->getSkeleton();
-    a = afl_mgr.load( "bvjf.a", "FFVII" ).staticCast<QGears::AFile>();
-    a->addTo( skeleton, "JumpFromTrain" );
-    attachMesh( mesh );
-
-    // Create background rectangle covering the whole screen
-    Ogre::Rectangle2D* rect = new Ogre::Rectangle2D(true);
-    rect->setCorners(-1.0, 1.0, 1.0, -1.0);
-    rect->setMaterial( "map" );
-
-    // Render the background before everything else
-    rect->setRenderQueueGroup( Ogre::RENDER_QUEUE_BACKGROUND );
-
-    // Use infinite AAB to always stay visible
-    Ogre::AxisAlignedBox aabInf;
-    aabInf.setInfinite();
-    rect->setBoundingBox( aabInf );
-
-    // Attach background to the scene
-    Ogre::SceneNode* node = scene_manager->getRootSceneNode()->createChildSceneNode("Background");
-    node->attachObject( rect );
-
-    Ogre::Root::getSingleton().startRendering();
-    skeleton.setNull();
-    mesh.setNull();
-    f.setNull();
-    hrc.setNull();
-    delete rect;
-
-    return 0;
+    try
+    {
+        QGears::FF7::FieldModelExporterPC app(argc, argv);
+        if (!app.initOgre()) return 0;
+
+        Ogre::SceneManager*         scene_manager(Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC, "Scene"));
+        QGears::AFilePtr            a;
+        QGears::HRCFilePtr          hrc = QGears::HRCFileManager::getSingleton().load("adda.hrc", "FFVII").staticCast<QGears::HRCFile>();
+        QGears::AFileManager       &afl_mgr(QGears::AFileManager::getSingleton());
+
+        auto meshName = QGears::FF7::NameLookup::model("adda.hrc") + ".mesh";
+
+        Ogre::MeshPtr mesh(Ogre::MeshManager::getSingleton().load(meshName, "FFVII"));
+        Ogre::SkeletonPtr skeleton(mesh->getSkeleton());
+
+
+        a = afl_mgr.load("aeae.a", "FFVII").staticCast<QGears::AFile>();
+        a->addTo(skeleton, "Idle");
+        a = afl_mgr.load("aeaf.a", "FFVII").staticCast<QGears::AFile>();
+        a->addTo(skeleton, "Walk");
+        a = afl_mgr.load("aeba.a", "FFVII").staticCast<QGears::AFile>();
+        a->addTo(skeleton, "Run");
+
+
+        attachMesh(mesh);
+        exportMesh(mesh);
+
+
+        entitys[0]->setVisible(true);
+
+        QGears::LZSFLevelFileManager   &fmgr(QGears::LZSFLevelFileManager::getSingleton());
+        // QGears::FLevelFilePtr           f = fmgr.load( "ancnt1", "FFVII" ).staticCast<QGears::FLevelFile>();
+
+        /*
+        mesh = Ogre::MeshManager::getSingleton().load(meshName, "FFVII");
+        skeleton = mesh->getSkeleton();
+        a = afl_mgr.load("bvjf.a", "FFVII").staticCast<QGears::AFile>();
+        a->addTo(skeleton, "JumpFromTrain");
+        */
+
+        //attachMesh( mesh );
+
+
+        // Create background rectangle covering the whole screen
+        //Ogre::Rectangle2D* rect = new Ogre::Rectangle2D(true);
+        //rect->setCorners(-1.0, 1.0, 1.0, -1.0);
+        // rect->setMaterial( "map" );
+
+        // Render the background before everything else
+        //rect->setRenderQueueGroup( Ogre::RENDER_QUEUE_BACKGROUND );
+
+        // Use infinite AAB to always stay visible
+        //Ogre::AxisAlignedBox aabInf;
+        //aabInf.setInfinite();
+        //rect->setBoundingBox( aabInf );
+
+        // Attach background to the scene
+        Ogre::SceneNode* node = scene_manager->getRootSceneNode()->createChildSceneNode("Background");
+
+        node->attachObject(entitys[0]);
+
+        //   node->attachObject( entitys[0] );
+
+        Ogre::Root::getSingleton().startRendering();
+        skeleton.setNull();
+        mesh.setNull();
+        //    f.setNull();
+        hrc.setNull();
+        //delete rect;
+        return 0;
+    }
+    catch (const Ogre::Exception& ex)
+    {
+        std::cout << "Ogre::Exception: " << ex.what() << std::endl;
+        return 1;
+    }
 }

+ 2 - 0
utilities/installer/CMakeLists.txt

@@ -11,10 +11,12 @@ include_directories(
 # define header and source files
 set(HEADER_FILES
     src/mainwindow.h
+	src/ff7DataInstaller.h
 )
 set(SOURCE_FILES
     src/Main.cpp
     src/mainwindow.cpp
+	src/ff7DataInstaller.cpp
 )
 
 set(INSTALLER_FORMS

+ 128 - 0
utilities/installer/src/ff7DataInstaller.cpp

@@ -0,0 +1,128 @@
+#include "ff7DataInstaller.h"
+
+#include <boost/filesystem.hpp>
+#include <boost/program_options.hpp>
+#include <OgreConfigFile.h>
+#include <OgreArchiveManager.h>
+#include <OgreMeshSerializer.h>
+#include <OgreSkeletonSerializer.h>
+#include <OgreMeshManager.h>
+#include <OgreRenderWindow.h>
+#include <OgreHardwarePixelBuffer.h>
+
+#include "QGearsGameState.h"
+#include "data/QGearsAFileManager.h"
+#include "data/QGearsBackgroundFileManager.h"
+#include "data/QGearsCameraMatrixFileManager.h"
+#include "data/QGearsHRCFileManager.h"
+#include "data/QGearsLZSFLevelFileManager.h"
+#include "data/QGearsPaletteFileManager.h"
+#include "data/QGearsPFileManager.h"
+#include "data/QGearsRSDFileManager.h"
+#include "data/QGearsTexCodec.h"
+#include "map/QGearsBackground2DFileManager.h"
+#include "map/QGearsWalkmeshFileManager.h"
+#include "data/FF7ModelListFileManager.h"
+#include "data/QGearsLGPArchiveFactory.h"
+#include "common/QGearsStringUtil.h"
+#include "common/FF7NameLookup.h"
+#include "data/QGearsTexCodec.h"
+
+FF7DataInstaller::FF7DataInstaller()
+#ifdef _DEBUG
+    : mApp("plugins_d.cfg", "resources_d.cfg", "install_d.log")
+#else
+    : mApp("plugins.cfg", "resources.cfg", "install.log")
+#endif
+{
+    mApp.initOgre(true);
+}
+
+FF7DataInstaller::~FF7DataInstaller()
+{
+
+}
+
+void FF7DataInstaller::Convert(std::string inputDir, std::string outputDir, const std::vector<std::string>& files)
+{
+    for (const auto& file : files)
+    {
+        // TODO: Comparison will be incorrect on some platforms
+        if (file == "field\\char.lgp")
+        {
+            auto fullPath = inputDir + file;
+            mApp.getRoot()->addResourceLocation(fullPath, "LGP", "FFVII");
+            ConvertFieldModels(fullPath, outputDir);
+        }
+    }
+}
+
+// TOOD: Share with pc model exporter
+static void exportMesh(std::string outdir, const Ogre::MeshPtr &mesh)
+{
+    Ogre::MeshSerializer        mesh_ser;
+    mesh_ser.exportMesh(mesh.getPointer(), outdir +  mesh->getName());
+
+    Ogre::SkeletonPtr           skeleton(mesh->getSkeleton());
+    Ogre::SkeletonSerializer    sk_ser;
+    sk_ser.exportSkeleton(skeleton.getPointer(), outdir +  skeleton->getName());
+
+    Ogre::Mesh::SubMeshIterator it(mesh->getSubMeshIterator());
+    Ogre::MaterialSerializer    mat_ser;
+    size_t i(0);
+    while (it.hasMoreElements())
+    {
+        Ogre::SubMesh *sub_mesh(it.getNext());
+        Ogre::MaterialPtr mat(Ogre::MaterialManager::getSingleton().getByName(sub_mesh->getMaterialName()));
+        if (!mat.isNull())
+        {
+            mat_ser.queueForExport(mat);
+        }
+        ++i;
+    }
+    QGears::String base_name;
+    QGears::StringUtil::splitFull(mesh->getName(), base_name);
+    mat_ser.exportQueued(outdir + base_name + QGears::EXT_MATERIAL);
+}
+
+
+void FF7DataInstaller::ConvertFieldModels(std::string archive, std::string outDir)
+{
+    // TODO: Find a way to query the file list from the added resource else we're having
+    // to parse/load the LGP archive twice
+    QGears::LGPArchive lgp(archive, "LGP");
+    lgp.open(archive);
+    lgp.load();
+    auto files = lgp.find("*.hrc");
+    for (const auto& file : *files)
+    {
+        try
+        {
+            Ogre::ResourcePtr hrc = QGears::HRCFileManager::getSingleton().load(file, "FFVII");
+
+            Ogre::String baseName;
+            QGears::StringUtil::splitBase(file, baseName);
+
+            auto meshName = QGears::FF7::NameLookup::model(baseName) + ".mesh";
+
+            Ogre::MeshPtr mesh(Ogre::MeshManager::getSingleton().load(meshName, "FFVII"));
+            Ogre::SkeletonPtr skeleton(mesh->getSkeleton());
+            exportMesh(outDir, mesh);
+        }
+        catch (const Ogre::Exception& ex)
+        {
+            std::cout << "ERROR converting: " << file << " Exception: " << ex.what() << std::endl;
+        }
+    }
+
+
+
+    /*
+    TODO:
+    To figure out what .a files relate to which .hrc files, we need to enumerate every field
+    and check its model loader data. These are always Idle, Walk, Run and then field specific
+    ordering.
+    Model loader is section 3 of the field file.
+    */
+}
+

+ 19 - 0
utilities/installer/src/ff7DataInstaller.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#include <string>
+#include <vector>
+#include "common/make_unique.h"
+#include "common/QGearsApplication.h"
+
+class FF7DataInstaller
+{
+public:
+    FF7DataInstaller();
+    ~FF7DataInstaller();
+    void Convert(std::string inputDir, std::string outputDir, const std::vector<std::string>& files);
+
+private:
+    void ConvertFieldModels(std::string archive, std::string outDir);
+
+    QGears::Application mApp;
+};

+ 32 - 2
utilities/installer/src/mainwindow.cpp

@@ -1,5 +1,7 @@
 #include "mainwindow.h"
 #include "ui_mainwindow.h"
+#include "ff7DataInstaller.h"
+#include <QDir>
 
 MainWindow::MainWindow(QWidget *parent) :
     QMainWindow(parent),
@@ -7,9 +9,17 @@ MainWindow::MainWindow(QWidget *parent) :
 {
     ui->setupUi(this);
     /*
-     set any options here
-     */
+    * set any options here
+    */
 
+    // Default output to "home" dir
+    ui->lineOutput->setText(QDir::toNativeSeparators(QDir::homePath() + "/qgears"));
+
+#ifdef _DEBUG
+    // Hard coded prebaked paths for debugging to save time
+    ui->lineInput->setText("C:\\Games\\FF7\\data");
+    ui->lineOutput->setText("C:\\Users\\paul\\Desktop\\q-gears\\output\\_data");
+#endif
 }
 
 MainWindow::~MainWindow()
@@ -44,5 +54,25 @@ void MainWindow::on_btnGO_clicked()
     else
     {
         QMessageBox::information(this,tr("Converting Data"),tr("Attempt to convert with \n Input: %1 \n Output: %2").arg(ui->lineInput->text(),ui->lineOutput->text()));
+
+        QString input = QDir::fromNativeSeparators(ui->lineInput->text());
+        if (!input.endsWith("/"))
+        {
+            input += "/";
+        }
+
+        QString output = QDir::fromNativeSeparators(ui->lineOutput->text());
+        if (!output.endsWith("/"))
+        {
+            output += "/";
+        }
+
+        // TODO: Enumerate files or find some better way to do this :)
+        std::vector<std::string> vec;
+        vec.push_back(QDir::toNativeSeparators("field/char.lgp").toStdString());
+        vec.push_back(QDir::toNativeSeparators("field/flevel.lgp").toStdString());
+
+        FF7DataInstaller conversion;
+        conversion.Convert(QDir::toNativeSeparators(input).toStdString(), QDir::toNativeSeparators(output).toStdString(), vec);
     }
 }

+ 1 - 1
utilities/installer/src/mainwindow.ui

@@ -72,7 +72,7 @@
     <item>
      <widget class="QPushButton" name="btnGO">
       <property name="text">
-       <string>PushButton</string>
+       <string>Install data</string>
       </property>
      </widget>
     </item>