Explorar o código

All of the installer files refactored.

Iñigo Valentin %!s(int64=3) %!d(string=hai) anos
pai
achega
5a646dfeb3

+ 4 - 0
.gitignore

@@ -18,3 +18,7 @@ output/include
 output/lib
 CMakeLists.txt.user
 doc/FFVII/RAW/
+.settings/
+.project
+.cproject
+

+ 13 - 8
V-Gears-Installer/CMakeLists.txt

@@ -90,6 +90,9 @@ set(HEADER_FILES
     include/common/scummsys.h
     include/common/BinaryReader.h
     include/common/Lzs.h
+    include/ModelsAndAnimationsDb.h
+    include/ScopedLgp.h
+    include/SpawnPointDb.h
 )
 
 
@@ -160,6 +163,8 @@ set(SOURCE_FILES
     src/decompiler/world/WorldCodeGenerator.cpp
     src/decompiler/world/WorldDisassembler.cpp
     src/decompiler/world/WorldEngine.cpp
+    src/ModelsAndAnimationsDb.cpp
+    src/ScopedLgp.cpp
 )
 
 # For SUDM. TODO: Add elses.
@@ -188,27 +193,27 @@ include_directories (
     ${QT_QTCORE_INCLUDE_DIR} ${QT_QTGUI_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR} ${QT_QTGUI_INCLUDE_DIR}
 )
 set ( v-gears-launcher_HDRS
-    include/mainwindow.h
-    include/ff7DataInstaller.h
-    include/ff7FieldTextWriter.h
+    include/MainWindow.h
+    include/DataInstaller.h
+    include/FieldTextWriter.h
 )
 
 set(v-gears-launcher_SRCS
     src/main.cpp
-    src/mainwindow.cpp
-    src/ff7DataInstaller.cpp
-    src/ff7FieldTextWriter.cpp
+    src/MainWindow.cpp
+    src/DataInstaller.cpp
+    src/FieldTextWriter.cpp
 )
 
 set(v-gears-launcher_UIS
-    src/mainwindow.ui
+    src/MainWindow.ui
 )
 QT5_WRAP_UI(UIS ${v-gears-launcher_UIS})
 
 message(UIS: ${UIS})
 
 set(v-gears-launcher_MOCS
-    include/mainwindow.h
+    include/MainWindow.h
 )
 QT5_WRAP_CPP(MOCS ${v-gears-launcher_MOCS})
 

+ 8 - 194
V-Gears-Installer/include/ff7DataInstaller.h → V-Gears-Installer/include/DataInstaller.h

@@ -21,211 +21,25 @@
 #include "common/VGearsApplication.h"
 #include "common/FinalFantasy7/FF7NameLookup.h"
 #include "data/VGearsTriggersFile.h"
-#include "common/VGearsStringUtil.h"
 #include "data/VGearsFLevelFile.h"
-#include "ff7FieldTextWriter.h"
+#include "FieldTextWriter.h"
+#include "ModelsAndAnimationsDb.h"
+#include "ScopedLgp.h"
+#include "SpawnPointDb.h"
 
 // TODO: Separate classes in files.
 // TODO: Move implementations to cpp file.
 
-/**
- * Handles a scoped LGP archive.
- */
-class ScopedLgp{
-
-    public:
-
-        /**
-         * Constructor.
-         *
-         * Don't use directly.
-         */
-        ScopedLgp(const ScopedLgp&) = delete;
-
-        /**
-         * Copy constructor.
-         *
-         * Don't use directly.
-         */
-        ScopedLgp& operator = (const ScopedLgp&) = delete;
-
-        /**
-         * Constructor.
-         */
-        ScopedLgp(
-          Ogre::Root* root, std::string full_path,
-          std::string type, std::string group
-        ) : root_(root), full_path_(full_path), group_(group) {
-            if (root_){
-                std::cout << "[RESOURCE] " << full_path_ << ", "
-                  << type << ", " << group_ << std::endl;
-                Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
-                  full_path_, type, group_
-                );
-            }
-        }
-
-        /**
-         * Destructor.
-         */
-        ~ScopedLgp(){
-            if (root_){
-                Ogre::ResourceGroupManager::getSingleton()
-                  .removeResourceLocation(full_path_, group_);
-            }
-        }
-
-    private:
-
-        /**
-         * The Ogre root system.
-         */
-        Ogre::Root* root_;
-
-        /**
-         * Full path to the LGP archive.
-         */
-        std::string full_path_;
-
-        /**
-         * Group for the resource.
-         */
-        std::string group_;
-};
-
-
 typedef std::set<std::string> MapCollection;
 
-/**
- * A database of spawn points.
- */
-class SpawnPointDb{
-
-    public:
-        /**
-         * Field IDs.
-         *
-         * ID of the field the gateways records from N other number of fields
-         * are linking to.
-         */
-        u16 target_field_id = 0;
-
-        /**
-         * A spawn point database record.
-         */
-        class Record{
-
-            public:
-
-                /**
-                 * Field that links to {@see SpawnPointDb::target_field_id}.
-                 */
-                u16 field_id = 0;
-
-                /**
-                 * Index of the gateway in {@see field_id}.
-                 */
-                u32 gateway_index_or_map_jump_address = 0;
-
-                /**
-                 * Gateway data.
-                 */
-                VGears::TriggersFile::Gateway gateway;
-
-                /**
-                 * Indicates if the gateway is a map jump from a script.
-                 */
-                bool from_script = false;
-
-                /**
-                 * @todo Understand and document.
-                 *
-                 * Only used from script calls.
-                 */
-                std::string entity_name;
-
-                /**
-                 * @todo Understand and document.
-                 *
-                 * Only used from script calls.
-                 */
-                std::string script_function_name;
-        };
-
-        /**
-         * List of gateways to this field.
-         */
-        std::vector<Record> gateways_to_this_field;
-};
-
 typedef std::map<u16, SpawnPointDb> FieldSpawnPointsMap;
 
 typedef std::map<u16, float> FieldScaleFactorMap;
 
-typedef std::map<std::string, std::set<std::string>> ModelAnimationMap;
-
-/**
- * Database of model animations.
- */
-class ModelsAndAnimationsDb{
-
-    public:
-
-        /**
-         * Normalizes an animation name.
-         *
-         * Generates a normalized file name, without path, lowercase, and an
-         * '.a' extension.
-         *
-         * @param name[in] Current name.
-         * @return The normalized name.
-         */
-        std::string NormalizeAnimationName(const std::string& name){
-            Ogre::String base_name;
-            VGears::StringUtil::splitBase(name, base_name);
-            std::transform(
-              base_name.begin(), base_name.end(), base_name.begin(), ::tolower
-            );
-            return base_name + ".a";
-        }
-
-        /**
-         * @todo Understand and document.
-         *
-         * @param model[in] @todo Understand and document.
-         * @return @todo Understand and document.
-         */
-        std::set<std::string>& ModelAnimations(const std::string model){
-            // HACK FIX LGP READING
-            std::string model_lower = model;
-            std::transform(
-              model_lower.begin(), model_lower.end(),
-              model_lower.begin(), ::tolower
-            );
-            return map[model_lower];
-        }
-
-        /**
-         * Retrieves the metadata file name associated to a model.
-         *
-         * @param model_name[in] The model name.
-         * @return Name of the metadata file.
-         */
-        std::string ModelMetaDataName(const std::string& model_name){
-            // If not in meta data then just replace .hrc with .mesh.
-            Ogre::String base_name;
-            VGears::StringUtil::splitBase(model_name, base_name);
-            return VGears::FF7::NameLookup::model(base_name) + ".mesh";
-        }
-
-        //private:
-        ModelAnimationMap map;
-};
-
 /**
  * The data installer.
  */
-class FF7DataInstaller{
+class DataInstaller{
 
     public:
 
@@ -240,7 +54,7 @@ class FF7DataInstaller{
          * to.
          * @param write_output_line Pointer to function to write output.
          */
-        FF7DataInstaller(
+        DataInstaller(
           std::string input_dir, std::string output_dir,
           std::function<void(std::string)> write_output_line
         );
@@ -248,7 +62,7 @@ class FF7DataInstaller{
         /**
          * Installer destructor.
          */
-        ~FF7DataInstaller();
+        ~DataInstaller();
 
         /**
          * Handle the installation progress.
@@ -516,7 +330,7 @@ class FF7DataInstaller{
         /**
          * Field text writer.
          */
-        FF7FieldTextWriter field_text_writer_;
+        FieldTextWriter field_text_writer_;
 
         /**
          * Written materials.

+ 4 - 5
V-Gears-Installer/include/ff7FieldTextWriter.h → V-Gears-Installer/include/FieldTextWriter.h

@@ -23,7 +23,7 @@
 /**
  * Handles the
  */
-class FF7FieldTextWriter{
+class FieldTextWriter{
 
     public:
 
@@ -41,11 +41,10 @@ class FF7FieldTextWriter{
          *
          * @param script_section_buffer[in] The text data to write.
          * @param field_name[in] The field of the text.
-         * @param english[in] True if the language to write.
+         * @param english[in] True if the language to write is english.
          */
         void Write(
-          const std::vector<u8>& script_section_buffer, std::string field_name,
-          bool english = true
+          const std::vector<u8>& script_section_buffer, std::string field_name, bool english = true
         );
 
         /**
@@ -93,7 +92,7 @@ class FF7FieldTextWriter{
         std::vector<u8> data_;
 
         /**
-         * Indicates if the text XML tag has been openend and not closed.
+         * Indicates if the text XML tag has been opened and not closed.
          */
         bool tag_open_ = false;
 };

+ 14 - 14
V-Gears-Installer/include/mainwindow.h → V-Gears-Installer/include/MainWindow.h

@@ -28,9 +28,6 @@ namespace Ui {
  */
 class MainWindow : public QMainWindow{
 
-    // TODO ??? What is this.
-    Q_OBJECT
-
     public:
 
         /**
@@ -52,63 +49,63 @@ class MainWindow : public QMainWindow{
          *
          * Sets the selected directory.
          */
-        void on_lineConfigDir_editingFinished();
+        void on_line_vgears_config_editingFinished();
 
         /**
          * Triggered when the configuration directory button is clicked.
          *
          * Opens a file manager for directory selection.
          */
-        void on_btnConfigDir_clicked();
+        void on_btn_vgears_config_clicked();
 
         /**
          * Triggered when the executable directory has done being edited.
          *
          * Sets the selected directory.
          */
-        void on_lineVGearsExe_editingFinished();
+        void on_line_vgears_exe_editingFinished();
 
         /**
          * Triggered when the executable directory button is clicked.
          *
          * Opens a file manager for file selection.
          */
-        void on_btnVGearsExe_clicked();
+        void on_btn_vgears_exe_clicked();
 
         /**
          * Triggered when the launch button is clicked.
          *
          * Launches V-Gears.
          */
-        void on_btnLaunch_clicked();
+        void on_btn_vgears_run_clicked();
 
         /**
          * Triggered when the input data directory button is clicked.
          *
          * Opens a file manager for directory selection.
          */
-        void on_btnInput_clicked();
+        void on_btn_data_src_clicked();
 
         /**
          * Triggered when the output data directory has done being edited.
          *
          * Sets the selected directory.
          */
-        void on_lineDataDir_editingFinished();
+        void on_line_data_dst_editingFinished();
 
         /**
          * Triggered when the output data directory button is clicked.
          *
          * Opens a file manager for directory selection.
          */
-        void on_btnDataDir_clicked();
+        void on_btn_data_dst_clicked();
 
         /**
          * Triggered when the install button is clicked.
          *
          * Launches the installation.
          */
-        void on_btnGO_clicked();
+        void on_btn_data_run_clicked();
 
     //private slots:
 
@@ -145,7 +142,10 @@ class MainWindow : public QMainWindow{
          */
         void InitSettings(void);
 
-    private:
+        // The Q_OBJECT macro must appear in the private section of a class definition
+        //that declares its own signals and slots or that uses other services provided
+        // by Qt's meta-object system.
+        Q_OBJECT
 
         /**
          * The installer window.
@@ -165,5 +165,5 @@ class MainWindow : public QMainWindow{
         /**
          * The installer.
          */
-        std::unique_ptr<class FF7DataInstaller> installer_;
+        std::unique_ptr<class DataInstaller> installer_;
 };

+ 60 - 0
V-Gears-Installer/include/ModelsAndAnimationsDb.h

@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 The V-Gears Team
+ *
+ * This file is part of V-Gears
+ *
+ * V-Gears is free software: you can redistribute it and/or modify it under
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, version 3.0 (GPLv3) of the License.
+ *
+ * V-Gears is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#pragma once
+
+#include "common/VGearsStringUtil.h"
+
+typedef std::map<std::string, std::set<std::string>> ModelAnimationMap;
+
+/**
+ * Database of model animations.
+ */
+class ModelsAndAnimationsDb{
+
+    public:
+
+        /**
+         * Normalizes an animation name.
+         *
+         * Generates a normalized file name, without path, lowercase, and an
+         * '.a' extension.
+         *
+         * @param name[in] Current name.
+         * @return The normalized name.
+         */
+        std::string NormalizeAnimationName(const std::string& name);
+
+        /**
+         * @todo Understand and document.
+         *
+         * @param model[in] @todo Understand and document.
+         * @return @todo Understand and document.
+         */
+        std::set<std::string>& ModelAnimations(const std::string model);
+
+        /**
+         * Retrieves the metadata file name associated to a model.
+         *
+         * @param model_name[in] The model name.
+         * @return Name of the metadata file.
+         */
+        std::string ModelMetaDataName(const std::string& model_name);
+
+        /**
+         * Map of models and animations.
+         */
+        ModelAnimationMap map;
+};

+ 67 - 0
V-Gears-Installer/include/ScopedLgp.h

@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2022 The V-Gears Team
+ *
+ * This file is part of V-Gears
+ *
+ * V-Gears is free software: you can redistribute it and/or modify it under
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, version 3.0 (GPLv3) of the License.
+ *
+ * V-Gears is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#pragma once
+
+#include <Ogre.h>
+
+/**
+ * Handles a scoped LGP archive.
+ */
+class ScopedLgp{
+
+    public:
+
+        /**
+         * Constructor.
+         *
+         * Don't use directly.
+         */
+        ScopedLgp(const ScopedLgp&) = delete;
+
+        /**
+         * Copy constructor.
+         *
+         * Don't use directly.
+         */
+        ScopedLgp& operator = (const ScopedLgp&) = delete;
+
+        /**
+         * Constructor.
+         */
+        ScopedLgp(Ogre::Root* root, std::string full_path, std::string type, std::string group);
+
+        /**
+         * Destructor.
+         */
+        ~ScopedLgp();
+
+    private:
+
+        /**
+         * The Ogre root system.
+         */
+        Ogre::Root* root_;
+
+        /**
+         * Full path to the LGP archive.
+         */
+        std::string full_path_;
+
+        /**
+         * Group for the resource.
+         */
+        std::string group_;
+};

+ 75 - 0
V-Gears-Installer/include/SpawnPointDb.h

@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 The V-Gears Team
+ *
+ * This file is part of V-Gears
+ *
+ * V-Gears is free software: you can redistribute it and/or modify it under
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, version 3.0 (GPLv3) of the License.
+ *
+ * V-Gears is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#pragma once
+
+/**
+ * A database of spawn points.
+ */
+struct SpawnPointDb{
+
+        /**
+         * Field IDs.
+         *
+         * ID of the field the gateways records from N other number of fields
+         * are linking to.
+         */
+        u16 target_field_id = 0;
+
+        /**
+         * A spawn point database record.
+         */
+        struct Record{
+
+                /**
+                 * Field that links to {@see SpawnPointDb::target_field_id}.
+                 */
+                u16 field_id = 0;
+
+                /**
+                 * Index of the gateway in {@see field_id}.
+                 */
+                u32 gateway_index_or_map_jump_address = 0;
+
+                /**
+                 * Gateway data.
+                 */
+                VGears::TriggersFile::Gateway gateway;
+
+                /**
+                 * Indicates if the gateway is a map jump from a script.
+                 */
+                bool from_script = false;
+
+                /**
+                 * @todo Understand and document.
+                 *
+                 * Only used from script calls.
+                 */
+                std::string entity_name;
+
+                /**
+                 * @todo Understand and document.
+                 *
+                 * Only used from script calls.
+                 */
+                std::string script_function_name;
+        };
+
+        /**
+         * List of gateways to this field.
+         */
+        std::vector<Record> gateways_to_this_field;
+};

+ 57 - 56
V-Gears-Installer/include/VGearsUtility.h

@@ -24,61 +24,62 @@ namespace VGears{
      * Provides utilities for the application.
      */
     class Utility : public Application{
-    public:
-
-        /**
-         * Constructor.
-         *
-         * @param argc[in] Number of arguments passed to the application.
-         * @param argv[in] List of arguments passed to the application.
-         */
-        Utility(int argc, char *argv[]);
-
-        /**
-         * Destructor.
-         */
-        virtual ~Utility();
-
-        virtual Ogre::Camera* GetCamera( void );
-
-    protected:
-
-        /**
-         * Initializes components used by the utilities.
-         */
-        virtual void InitComponents();
-
-        /**
-         * Initializes components used by the utilities.
-         */
-        virtual void DestroyComponents();
-
-    private:
-
-        /**
-         * Constructor.
-         */
-        Utility();
-
-        /**
-         * The frame listener.
-         */
-        DisplayFrameListener *frame_listener_;
-
-        /**
-         * The application scene manager.
-         */
-        Ogre::SceneManager *scene_manager_;
-
-        /**
-         * The engine camera.
-         */
-        Ogre::Camera *camera_;
-
-        /**
-         * The engine viewport.
-         */
-        Ogre::Viewport *viewport_;
-    };
+
+        public:
+
+            /**
+             * Constructor.
+             *
+             * @param argc[in] Number of arguments passed to the application.
+             * @param argv[in] List of arguments passed to the application.
+             */
+            Utility(int argc, char *argv[]);
+
+            /**
+             * Destructor.
+             */
+            virtual ~Utility();
+
+            virtual Ogre::Camera* GetCamera( void );
+
+        protected:
+
+            /**
+             * Initializes components used by the utilities.
+             */
+            virtual void InitComponents();
+
+            /**
+             * Initializes components used by the utilities.
+             */
+            virtual void DestroyComponents();
+
+        private:
+
+            /**
+             * Constructor.
+             */
+            Utility();
+
+            /**
+             * The frame listener.
+             */
+            DisplayFrameListener *frame_listener_;
+
+            /**
+             * The application scene manager.
+             */
+            Ogre::SceneManager *scene_manager_;
+
+            /**
+             * The engine camera.
+             */
+            Ogre::Camera *camera_;
+
+            /**
+             * The engine viewport.
+             */
+            Ogre::Viewport *viewport_;
+        };
 }
 

+ 23 - 23
V-Gears-Installer/src/ff7DataInstaller.cpp → V-Gears-Installer/src/DataInstaller.cpp

@@ -29,7 +29,6 @@
 #include <OgreHardwarePixelBuffer.h>
 #include <OgreResourceGroupManager.h>
 #include <OgreLog.h>
-#include "ff7DataInstaller.h"
 #include "VGearsGameState.h"
 #include "data/VGearsAFileManager.h"
 #include "data/VGearsBackgroundFileManager.h"
@@ -51,12 +50,13 @@
 #include <memory>
 #include <QtCore/QDir>
 
+#include "../include/DataInstaller.h"
 #include "decompiler/field/FieldScriptFormatter.h"
 #include "decompiler/field/FieldDecompiler.h"
 
-float FF7DataInstaller::LINE_SCALE_FACTOR = 0.0078124970964f;
+float DataInstaller::LINE_SCALE_FACTOR = 0.0078124970964f;
 
-FF7DataInstaller::FF7DataInstaller(
+DataInstaller::DataInstaller(
   std::string input_dir, std::string output_dir,
   std::function<void(std::string)> write_output_line
 )
@@ -76,9 +76,9 @@ FF7DataInstaller::FF7DataInstaller(
 
 }
 
-FF7DataInstaller::~FF7DataInstaller(){}
+DataInstaller::~DataInstaller(){}
 
-int FF7DataInstaller::CalcProgress(){
+int DataInstaller::CalcProgress(){
     // TODO: Make more accurate with iterator_counter_ and
     // progress_step_num_elements_.
     float curr_step = installation_state_ / static_cast<float>(STATE_COUNT);
@@ -86,7 +86,7 @@ int FF7DataInstaller::CalcProgress(){
     return static_cast<int>(curr_step);
 }
 
-int FF7DataInstaller::Progress(){
+int DataInstaller::Progress(){
     switch (installation_state_){
         case IDLE:
             write_output_line("Loading flevel.lgp");
@@ -290,7 +290,7 @@ static void ExportMesh(std::string outdir, const Ogre::MeshPtr &mesh){
  */
 static std::string FieldName(const std::string& name){return "ffvii_" + name;}
 
-void FF7DataInstaller::CreateDir(const std::string& path){
+void DataInstaller::CreateDir(const std::string& path){
     QString target = QString::fromStdString(output_dir_ + path);
     QDir dir(target);
     if (!dir.mkpath(".")) throw std::runtime_error("Failed to mkpath");
@@ -600,7 +600,7 @@ static float FieldScaleFactor(
  * @param write_output_line[in] Functon to print output to console.
  */
 static void FF7PcFieldToVGearsField(
-  FF7FieldTextWriter& field_text_writter,
+  FieldTextWriter& field_text_writter,
   VGears::FLevelFilePtr& field,
   const std::string& out_dir,
   const std::vector<std::string>& field_id_to_name_lookup,
@@ -777,15 +777,15 @@ static void FF7PcFieldToVGearsField(
             xml_entity_trigger->SetAttribute("name", line.name);
             xml_entity_trigger->SetAttribute(
               "point1",
-              std::to_string(line.point_a[0] * FF7DataInstaller::LINE_SCALE_FACTOR)
-                + " " + std::to_string(line.point_a[1] * FF7DataInstaller::LINE_SCALE_FACTOR)
-                + " " + std::to_string(line.point_a[2] * FF7DataInstaller::LINE_SCALE_FACTOR)
+              std::to_string(line.point_a[0] * DataInstaller::LINE_SCALE_FACTOR)
+                + " " + std::to_string(line.point_a[1] * DataInstaller::LINE_SCALE_FACTOR)
+                + " " + std::to_string(line.point_a[2] * DataInstaller::LINE_SCALE_FACTOR)
             );
             xml_entity_trigger->SetAttribute(
               "point2",
-              std::to_string(line.point_b[0] * FF7DataInstaller::LINE_SCALE_FACTOR)
-                + " " + std::to_string(line.point_b[1] * FF7DataInstaller::LINE_SCALE_FACTOR)
-                + " " + std::to_string(line.point_b[2] * FF7DataInstaller::LINE_SCALE_FACTOR)
+              std::to_string(line.point_b[0] * DataInstaller::LINE_SCALE_FACTOR)
+                + " " + std::to_string(line.point_b[1] * DataInstaller::LINE_SCALE_FACTOR)
+                + " " + std::to_string(line.point_b[2] * DataInstaller::LINE_SCALE_FACTOR)
             );
             xml_entity_trigger->SetAttribute("enabled", "true");
             element->LinkEndChild(xml_entity_trigger.release());
@@ -1236,7 +1236,7 @@ static void CollectFieldScaleFactors(
       = FieldDecompiler::ScaleFactor(field->GetRawScript());
 }
 
-void FF7DataInstaller::InitCollectSpawnAndScaleFactors(){
+void DataInstaller::InitCollectSpawnAndScaleFactors(){
     progress_step_num_elements_ = 1;
     CreateDir(FieldMapDir());
     CreateDir(FieldModelDir());
@@ -1253,7 +1253,7 @@ void FF7DataInstaller::InitCollectSpawnAndScaleFactors(){
     installation_state_ = SPAWN_POINTS_AND_SCALE_FACTORS;
 }
 
-void FF7DataInstaller::CollectionFieldSpawnAndScaleFactors(){
+void DataInstaller::CollectionFieldSpawnAndScaleFactors(){
     // On the first pass collate required field information.
     progress_step_num_elements_ = flevel_file_list_->size();
     if (iterator_counter_ < flevel_file_list_->size()){
@@ -1293,7 +1293,7 @@ void FF7DataInstaller::CollectionFieldSpawnAndScaleFactors(){
     }
 }
 
-void FF7DataInstaller::ConvertFieldsIteration(){
+void DataInstaller::ConvertFieldsIteration(){
     // Do the full conversion with the collated data.
     progress_step_num_elements_ = flevel_file_list_->size();
     if (iterator_counter_ < flevel_file_list_->size()){
@@ -1332,7 +1332,7 @@ void FF7DataInstaller::ConvertFieldsIteration(){
     }
 }
 
-void FF7DataInstaller::WriteMapsXmlBegin(){
+void DataInstaller::WriteMapsXmlBegin(){
     // Write out maps.xml.
     progress_step_num_elements_ = 1;
     doc_ = std::make_unique<TiXmlDocument>();
@@ -1343,7 +1343,7 @@ void FF7DataInstaller::WriteMapsXmlBegin(){
     converted_map_list_iterator_ = converted_map_list_.begin();
 }
 
-void FF7DataInstaller::WriteMapsXmlIteration(){
+void DataInstaller::WriteMapsXmlIteration(){
     // TODO: Probably need to inject "empty" and "test" fields.
     progress_step_num_elements_ = converted_map_list_.size();
     if (converted_map_list_iterator_ != converted_map_list_.end()){
@@ -1359,14 +1359,14 @@ void FF7DataInstaller::WriteMapsXmlIteration(){
     else installation_state_ = WRITE_MAPS_CLEAN;
 }
 
-void FF7DataInstaller::EndWriteMapsXml(){
+void DataInstaller::EndWriteMapsXml(){
     progress_step_num_elements_ = 1;
     doc_->LinkEndChild(element_.release());
     doc_->SaveFile(output_dir_ + "/maps.xml");
     installation_state_ = CONVERT_FIELD_MODELS_INIT;
 }
 
-void FF7DataInstaller::ConvertFieldModelsBegin(){
+void DataInstaller::ConvertFieldModelsBegin(){
     // TODO: Convert models and animations in model_animation_db.
     progress_step_num_elements_ = 1;
     field_models_lgp_ = std::make_unique<ScopedLgp>(
@@ -1380,12 +1380,12 @@ void FF7DataInstaller::ConvertFieldModelsBegin(){
     model_animation_map_iterator_ = used_models_and_anims_.map.begin();
 }
 
-void FF7DataInstaller::ConvertFieldModelsIteration(){
+void DataInstaller::ConvertFieldModelsIteration(){
     progress_step_num_elements_ = used_models_and_anims_.map.size();
     if (model_animation_map_iterator_ != used_models_and_anims_.map.end()){
         if (conversion_step_ == 0){
             write_output_line("Converting model " + model_animation_map_iterator_->first);
-            conversion_step_++;
+            conversion_step_ ++;
         }
         else{
             try{

+ 18 - 38
V-Gears-Installer/src/ff7FieldTextWriter.cpp → V-Gears-Installer/src/FieldTextWriter.cpp

@@ -14,10 +14,10 @@
  */
 
 #include <iostream>
-#include "../include/ff7FieldTextWriter.h"
+
+#include "FieldTextWriter.h"
 #include "common/VGearsStringUtil.h"
 
-// TODO: Refactor: this is based on/copied from DatFile::DumpText.
 
 /**
  * Table of English characters.
@@ -180,10 +180,9 @@ static const unsigned short JAPANESE_CHARS_FE[256] = {
     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xF0 - 0xFF
 };
 
-void FF7FieldTextWriter::Begin(std::string file_name){
+void FieldTextWriter::Begin(std::string file_name){
     data_.clear();
     logger_.reset(new Logger(file_name));
-
     // Write BOM
     /* FIX ME - It needs to write data as UTF8.
     std::vector< unsigned char > bomBytes;
@@ -195,19 +194,18 @@ void FF7FieldTextWriter::Begin(std::string file_name){
     logger_->Log("<texts>\n");
 }
 
-u16 FF7FieldTextWriter::GetU16LE(u32 offset){
+u16 FieldTextWriter::GetU16LE(u32 offset){
     if (offset+1 >= data_.size()) throw std::out_of_range("");
     return *reinterpret_cast<u16*>(&data_[offset]);
 }
 
-u8 FF7FieldTextWriter::GetU8(u32 offset){
+u8 FieldTextWriter::GetU8(u32 offset){
     if (offset >= data_.size()) throw std::out_of_range("");
     return data_[offset];
 }
 
-void FF7FieldTextWriter::Write(
-  const std::vector<u8>& script_section_buffer, std::string field_name,
-  bool english
+void FieldTextWriter::Write(
+  const std::vector<u8>& script_section_buffer, std::string field_name, bool english
 ){
     data_ = script_section_buffer;
     // Get sector 1 offset (scripts and dialog).
@@ -230,8 +228,7 @@ void FF7FieldTextWriter::Write(
     const u16 dialogCount = GetU16LE(offset_to_sector + offset_to_dialogs);
     for (u16 i = 0; i <dialogCount; ++ i){
         // gGt offset of string data.
-        u32 offset
-          = offset_to_sector + offset_to_dialogs + GetU16LE(
+        u32 offset = offset_to_sector + offset_to_dialogs + GetU16LE(
             offset_to_sector + offset_to_dialogs
             + 0x02 +  // +2 to skip dialog count
             i * 0x02 // *2 because each char is 2 bytes
@@ -335,8 +332,7 @@ void FF7FieldTextWriter::Write(
                 logger_->Log("<image sprite=\"ButtonCross\" />");
             }
             else if (
-              (temp == 0xFA || temp == 0xFB || temp == 0xFC || temp == 0xFD)
-              && english == false
+              (temp == 0xFA || temp == 0xFB || temp == 0xFC || temp == 0xFD) && english == false
             ){
                 ++ offset;
                 unsigned char temp2 = GetU8(offset);
@@ -347,9 +343,7 @@ void FF7FieldTextWriter::Write(
                     }
                     else{
                         AddText(dialog);
-                        logger_->Log(
-                          "[MISSING 0xFA " + HexToString(temp2, 2, '0') + "]"
-                        );
+                        logger_->Log("[MISSING 0xFA " + HexToString(temp2, 2, '0') + "]");
                     }
                 }
                 else if (temp == 0xFB){
@@ -359,9 +353,7 @@ void FF7FieldTextWriter::Write(
                     }
                     else{
                         AddText(dialog);
-                        logger_->Log(
-                          "[MISSING 0xFB " + HexToString(temp2, 2, '0') + "]"
-                        );
+                        logger_->Log("[MISSING 0xFB " + HexToString(temp2, 2, '0') + "]");
                     }
                 }
                 else if (temp == 0xFC){
@@ -371,9 +363,7 @@ void FF7FieldTextWriter::Write(
                     }
                     else{
                         AddText(dialog);
-                        logger_->Log(
-                          "[MISSING 0xFC " + HexToString(temp2, 2, '0') + "]"
-                        );
+                        logger_->Log("[MISSING 0xFC " + HexToString(temp2, 2, '0') + "]");
                     }
                 }
                 else if (temp == 0xFD){
@@ -383,9 +373,7 @@ void FF7FieldTextWriter::Write(
                     }
                     else{
                         AddText(dialog);
-                        logger_->Log(
-                          "[MISSING 0xFD " + HexToString(temp2, 2, '0') + "]"
-                        );
+                        logger_->Log("[MISSING 0xFD " + HexToString(temp2, 2, '0') + "]");
                     }
                 }
             }
@@ -429,9 +417,7 @@ void FF7FieldTextWriter::Write(
                     ++ offset;
                     ++ offset;
                     AddText(dialog);
-                    logger_->Log(
-                      "<pause time=\"" + IntToString(wait) + "\" />"
-                    );
+                    logger_->Log("<pause time=\"" + IntToString(wait) + "\" />");
                 }
                 else{
                     if (JAPANESE_CHARS_FE[temp2] != 0x0000 && english == false){
@@ -440,9 +426,7 @@ void FF7FieldTextWriter::Write(
                     }
                     else{
                         AddText(dialog);
-                        logger_->Log(
-                          "[MISSING 0xFE " + HexToString(temp2, 2, '0') + "]"
-                        );
+                        logger_->Log("[MISSING 0xFE " + HexToString(temp2, 2, '0') + "]");
                     }
                 }
             }
@@ -456,11 +440,7 @@ void FF7FieldTextWriter::Write(
                 else{
                     AddText(dialog);
                     if (temp == 0xa9) logger_->Log("..."); // TODO Verify.
-                    else{
-                        logger_->Log(
-                          "[MISSING CHAR " + HexToString(temp, 2, '0') + "]"
-                        );
-                    }
+                    else logger_->Log("[MISSING CHAR " + HexToString(temp, 2, '0') + "]");
                 }
             }
         }
@@ -471,12 +451,12 @@ void FF7FieldTextWriter::Write(
 
 }
 
-void FF7FieldTextWriter::End(){
+void FieldTextWriter::End(){
     if (logger_) logger_->Log("</texts>\n");
     logger_.reset();
 }
 
-void FF7FieldTextWriter::AddText(std::vector< unsigned char >& text){
+void FieldTextWriter::AddText(std::vector< unsigned char >& text){
     if (text.empty()) return;
     std::string str(reinterpret_cast<char*>(text.data()), text.size());
     str = Ogre::StringUtil::replaceAll(str, "&", "&amp;");

+ 243 - 0
V-Gears-Installer/src/MainWindow.cpp

@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2022 The V-Gears Team
+ *
+ * This file is part of V-Gears
+ *
+ * V-Gears is free software: you can redistribute it and/or modify it under
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, version 3.0 (GPLv3) of the License.
+ *
+ * V-Gears is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+#include <iostream>
+#include <QtCore/QProcess>
+#include <QtWidgets/QFileDialog>
+#include <QtCore/QDir>
+#include <QtCore/QSettings>
+#include <QtWidgets/QMessageBox>
+#include <QtCore/QTimer>
+#include "DataInstaller.h"
+#include "MainWindow.h"
+#include "ui_MainWindow.h"
+
+/**
+ * Indicates if an installer has already been created.
+ */
+static bool installer_created = false;
+
+MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), main_window_(new Ui::MainWindow){
+    main_window_->setupUi(this);
+    // Goto the data tab by default.
+    main_window_->tabWidget->setCurrentIndex(0);
+    // Turn off the launcher tab for now since it dosen't actually work
+    //main_window_->tabWidget->setTabEnabled(0, false);
+    InitSettings();
+    main_window_->btn_vgears_config->setText(settings_->value("ConfigDir").toString());
+    main_window_->line_data_dst->setText(settings_->value("DataDir").toString());
+    main_window_->line_vgears_exe->setText(settings_->value("VGearsEXE").toString());
+#ifdef _DEBUG
+    // Hard coded prebaked paths for debugging to save time
+    //main_window_->line_data_src->setText("C:\\Games\\FF7\\data");
+    //main_window_->line_data_dst->setText(
+    //  "C:\\Users\\paul\\Desktop\\v-gears\\output\\data"
+    //);
+#endif
+    timer_ = new QTimer(this);
+    connect(timer_, SIGNAL(timeout()), this, SLOT(DoProgress()));
+}
+
+MainWindow::~MainWindow(){delete main_window_;}
+
+void MainWindow::InitSettings(void){
+    bool win = false;
+#ifdef Q_OS_WIN
+    settings_ = new QSettings(
+      QCoreApplication::applicationDirPath() + "/" + "launcherSettings.ini",
+      QSettings::IniFormat
+    );
+    win = true;
+#else
+    settings_ = new QSettings(
+      QSettings::NativeFormat,QSettings::UserScope, "v-gears", "launcher", 0
+    );
+#endif
+    //Check settings.
+    if (settings_->value("ConfigDir").isNull()){
+        if (win) settings_->setValue("ConfigDir", QString("%1/v-gears").arg(QDir::homePath()));
+        else settings_->setValue("ConfigDir", QString("%1/.v-gears").arg(QDir::homePath()));
+    }
+
+    if (settings_->value("DataDir").isNull()){
+        if (win) settings_->setValue("DataDir",QString("%1/v-gears/data").arg(QDir::homePath()));
+        else settings_->setValue("DataDir",QString("%1/.v-gears/data").arg(QDir::homePath()));
+    }
+
+    if (settings_->value("VGearsEXE").isNull()){
+        if (win){
+            settings_->setValue(
+              "VGearsEXE",QString("%1/v-gears.exe").arg(QCoreApplication::applicationDirPath())
+            );
+        }
+        else settings_->setValue("VGearsEXE", QString("/usr/games/v-gears"));
+    }
+}
+
+void MainWindow::on_line_vgears_config_editingFinished(){
+    settings_->setValue("ConfigDir",main_window_->btn_vgears_config->text());
+}
+
+void MainWindow::on_btn_vgears_config_clicked(){
+    QString temp = QFileDialog::getExistingDirectory(
+      this, tr("Select Location of VGears Configuration Data,"),
+      settings_->value("ConfigDir").toString()
+    );
+    if (!temp.isNull()){
+        settings_->setValue("ConfigDir", temp);
+        main_window_->btn_vgears_config->setText(temp);
+    }
+}
+
+void MainWindow::on_line_vgears_exe_editingFinished(){
+    settings_->setValue("VGearsEXE",main_window_->line_vgears_exe->text());
+}
+
+void MainWindow::on_btn_vgears_exe_clicked(){
+    QString temp = QFileDialog::getOpenFileName(
+      this, tr("Location of VGears Executable,"), QDir::rootPath()
+    );
+    if (!temp.isNull()){
+        settings_->setValue("VGearsEXE", temp);
+        main_window_->line_vgears_exe->setText(temp);
+    }
+}
+
+void MainWindow::on_btn_vgears_run_clicked(){
+    QString configDir(main_window_->btn_vgears_config->text());
+    QString exe(main_window_->line_vgears_exe->text());
+    QStringList args;
+    args.append(
+      QString("--resources-file=%1/resources.cfg").arg(main_window_->btn_vgears_config->text())
+    );
+    args.append(
+      QString("--config-file=%1/v-gears.cfg").arg(main_window_->btn_vgears_config->text())
+    );
+    args.append(
+      QString("--plugins-file=/%1/plugins.cfg").arg(main_window_->btn_vgears_config->text())
+    );
+    // Check that the config dir is set up correctly.
+    QProcess vGears;
+    vGears.startDetached(exe,args,configDir);
+}
+
+void MainWindow::on_btn_data_src_clicked(){
+    QString temp = QFileDialog::getExistingDirectory(
+      this, tr("Location of Game Data),"),QDir::homePath()
+    );
+    main_window_->line_data_src->setText(temp);
+}
+
+void MainWindow::on_line_data_dst_editingFinished(){
+    settings_->setValue("DataDir",main_window_->line_data_dst->text());
+}
+
+void MainWindow::on_btn_data_dst_clicked(){
+    QString temp = QFileDialog::getExistingDirectory(
+      this, tr("Location of VGears Data),"), settings_->value("DataDir").toString()
+    );
+    if (!temp.isNull()){
+        settings_->setValue("DataDir",temp);
+        main_window_->line_data_dst->setText(temp);
+    }
+}
+
+void MainWindow::on_btn_data_run_clicked(){
+    if (main_window_->line_data_src->text().isEmpty()){
+        // TODO IVV: Default path, remove
+        main_window_->line_data_src->setText("/home/ivalentin/data/");
+    }
+    //{
+    //    QMessageBox::critical(
+    //      this, tr("Input error"),
+    //      tr("No input to installed FF7 PC data provided")
+    //    );
+    //}
+    else if (main_window_->line_data_dst->text().isEmpty())
+        QMessageBox::critical(this, tr("Output error"), tr("No output path provided"));
+    else{
+        // Normalize the paths so its in / format separators.
+        QString input = QDir::fromNativeSeparators(main_window_->line_data_src->text());
+        if (!input.endsWith("/")) input += "/";
+        QString output = QDir::fromNativeSeparators(main_window_->line_data_dst->text());
+        if (!output.endsWith("/")) output += "/";
+        // TODO: Enumerate files or find some better way to do this.
+        const std::vector<std::string> required_files = {"field/char.lgp", "field/flevel.lgp"};
+        // Ensure required files are in the input dir
+        for (auto& file : required_files){
+            QString full_path = input + QString::fromStdString(file);
+            if (!QFile::exists(full_path)){
+                QMessageBox::critical(
+                  this, tr("Missing input file"), tr("File not found: ") + full_path);
+                return;
+            }
+        }
+        if (installer_created){
+            QMessageBox::critical(
+              this,
+              tr("Error"),
+              tr(
+                "Due to use of singletons install function can only be used "
+                "once, please restart the application."
+              )
+            );
+            return;
+        }
+        // Start data conversion
+        try{
+            installer_created = true;
+            std::cout << "[INSTALLER] Started";
+            std::cout << "[INSTALLER] Input path: "
+              << QDir::toNativeSeparators(input).toStdString() << std::endl;
+            std::cout << "[INSTALLER] Output path: "
+              << QDir::toNativeSeparators(output).toStdString() << std::endl;
+            installer_ = std::make_unique<DataInstaller>(
+              QDir::toNativeSeparators(input).toStdString(),
+              QDir::toNativeSeparators(output).toStdString(),
+              [this](std::string outputLine){main_window_->data_log->append(outputLine.c_str());}
+            );
+            OnInstallStarted();
+        }
+        catch (const std::exception& ex){OnInstallStopped();}
+    }
+}
+
+void MainWindow::EnableUi(bool enable){
+    main_window_->btn_data_run->setEnabled(enable);
+    main_window_->line_data_src->setEnabled(enable);
+    main_window_->btn_data_src->setEnabled(enable);
+    main_window_->line_data_dst->setEnabled(enable);
+    main_window_->btn_data_dst->setEnabled(enable);
+    main_window_->data_progress_bar->setValue(0);
+    if (!enable) timer_->start(0);
+    else timer_->stop();
+}
+
+void MainWindow::OnInstallStarted(){EnableUi(false);}
+
+void MainWindow::OnInstallStopped(){EnableUi(true);}
+
+void MainWindow::DoProgress(){
+    try{
+        const int progress = installer_->Progress();
+        main_window_->data_progress_bar->setValue(progress);
+        if (progress >= 100) OnInstallStopped();
+    }
+    catch (const std::exception& ex){
+        OnInstallStopped();
+        QMessageBox::critical(this, tr("Data conversion exception"), ex.what());
+    }
+}

+ 75 - 72
V-Gears-Installer/src/mainwindow.ui → V-Gears-Installer/src/MainWindow.ui

@@ -11,40 +11,37 @@
    </rect>
   </property>
   <property name="windowTitle">
-   <string>VGears Launcher</string>
+   <string>VGears Installer</string>
   </property>
   <widget class="QWidget" name="centralWidget">
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
      <widget class="QTabWidget" name="tabWidget">
+      <property name="tabPosition">
+       <enum>QTabWidget::North</enum>
+      </property>
       <property name="currentIndex">
-       <number>1</number>
+       <number>0</number>
       </property>
-      <widget class="QWidget" name="tab">
+      <widget class="QWidget" name="tab_installer">
        <attribute name="title">
-        <string>V-Gears Config</string>
+        <string>Data Installer</string>
        </attribute>
-       <layout class="QVBoxLayout" name="verticalLayout_2">
+       <layout class="QVBoxLayout" name="verticalLayout_3">
         <item>
-         <layout class="QHBoxLayout" name="horizontalLayout">
+         <layout class="QHBoxLayout" name="horizontalLayout_4">
           <item>
-           <widget class="QLabel" name="label_2">
+           <widget class="QLabel" name="label_4">
             <property name="text">
-             <string>VGears Path</string>
+             <string>Import Data Source:</string>
             </property>
            </widget>
           </item>
           <item>
-           <widget class="QLineEdit" name="lineVGearsExe"/>
+           <widget class="QLineEdit" name="line_data_src"/>
           </item>
           <item>
-           <widget class="QPushButton" name="btnVGearsExe">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
+           <widget class="QPushButton" name="btn_data_src">
             <property name="maximumSize">
              <size>
               <width>24</width>
@@ -59,25 +56,19 @@
          </layout>
         </item>
         <item>
-         <layout class="QHBoxLayout" name="horizontalLayout_2">
+         <layout class="QHBoxLayout" name="horizontalLayout_3">
           <item>
-           <widget class="QLabel" name="label">
+           <widget class="QLabel" name="label_3">
             <property name="text">
-             <string>Config Directory</string>
+             <string>VGears Data Path:</string>
             </property>
            </widget>
           </item>
           <item>
-           <widget class="QLineEdit" name="lineConfigDir"/>
+           <widget class="QLineEdit" name="line_data_dst"/>
           </item>
           <item>
-           <widget class="QPushButton" name="btnConfigDir">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
+           <widget class="QPushButton" name="btn_data_dst">
             <property name="maximumSize">
              <size>
               <width>24</width>
@@ -92,33 +83,66 @@
          </layout>
         </item>
         <item>
-         <widget class="QPushButton" name="btnLaunch">
+         <widget class="QProgressBar" name="data_progress_bar">
+          <property name="value">
+           <number>0</number>
+          </property>
+          <property name="alignment">
+           <set>Qt::AlignCenter</set>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLabel" name="label_5">
           <property name="text">
-           <string>Run V-Gears</string>
+           <string>Output</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QTextEdit" name="data_log">
+          <property name="undoRedoEnabled">
+           <bool>false</bool>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QPushButton" name="btn_data_run">
+          <property name="text">
+           <string>Install data</string>
           </property>
          </widget>
         </item>
        </layout>
       </widget>
-      <widget class="QWidget" name="tab_2">
+      <widget class="QWidget" name="tab_vgears">
        <attribute name="title">
-        <string>Data Installer</string>
+        <string>V-Gears Config</string>
        </attribute>
-       <layout class="QVBoxLayout" name="verticalLayout_3">
+       <layout class="QVBoxLayout" name="verticalLayout_2">
         <item>
-         <layout class="QHBoxLayout" name="horizontalLayout_4">
+         <layout class="QHBoxLayout" name="horizontalLayout">
           <item>
-           <widget class="QLabel" name="label_4">
+           <widget class="QLabel" name="label_2">
             <property name="text">
-             <string>Import Data Source:</string>
+             <string>VGears Path</string>
             </property>
            </widget>
           </item>
           <item>
-           <widget class="QLineEdit" name="lineInput"/>
+           <widget class="QLineEdit" name="line_vgears_exe"/>
           </item>
           <item>
-           <widget class="QPushButton" name="btnInput">
+           <widget class="QPushButton" name="btn_vgears_exe">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
             <property name="maximumSize">
              <size>
               <width>24</width>
@@ -133,19 +157,25 @@
          </layout>
         </item>
         <item>
-         <layout class="QHBoxLayout" name="horizontalLayout_3">
+         <layout class="QHBoxLayout" name="horizontalLayout_2">
           <item>
-           <widget class="QLabel" name="label_3">
+           <widget class="QLabel" name="label">
             <property name="text">
-             <string>VGears Data Path:</string>
+             <string>Config Directory</string>
             </property>
            </widget>
           </item>
           <item>
-           <widget class="QLineEdit" name="lineDataDir"/>
+           <widget class="QLineEdit" name="line_vgears_config"/>
           </item>
           <item>
-           <widget class="QPushButton" name="btnDataDir">
+           <widget class="QPushButton" name="btn_vgears_config">
+            <property name="sizePolicy">
+             <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
             <property name="maximumSize">
              <size>
               <width>24</width>
@@ -160,36 +190,9 @@
          </layout>
         </item>
         <item>
-         <widget class="QProgressBar" name="progressBar">
-          <property name="value">
-           <number>0</number>
-          </property>
-          <property name="alignment">
-           <set>Qt::AlignCenter</set>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QLabel" name="label_5">
+         <widget class="QPushButton" name="btn_vgears_launch">
           <property name="text">
-           <string>Output</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QTextEdit" name="txtOutput">
-          <property name="undoRedoEnabled">
-           <bool>false</bool>
-          </property>
-          <property name="readOnly">
-           <bool>true</bool>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QPushButton" name="btnGO">
-          <property name="text">
-           <string>Install data</string>
+           <string>Run V-Gears</string>
           </property>
          </widget>
         </item>
@@ -205,7 +208,7 @@
      <x>0</x>
      <y>0</y>
      <width>720</width>
-     <height>21</height>
+     <height>26</height>
     </rect>
    </property>
    <widget class="QMenu" name="menuFile">

+ 44 - 0
V-Gears-Installer/src/ModelsAndAnimationsDb.cpp

@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The V-Gears Team
+ *
+ * This file is part of V-Gears
+ *
+ * V-Gears is free software: you can redistribute it and/or modify it under
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, version 3.0 (GPLv3) of the License.
+ *
+ * V-Gears is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "ModelsAndAnimationsDb.h"
+
+#include <set>
+#include <string>
+#include <Ogre.h>
+#include "common/FinalFantasy7/FF7NameLookup.h"
+
+std::string ModelsAndAnimationsDb::NormalizeAnimationName(const std::string& name){
+    Ogre::String base_name;
+    VGears::StringUtil::splitBase(name, base_name);
+    std::transform(base_name.begin(), base_name.end(), base_name.begin(), ::tolower);
+    return base_name + ".a";
+}
+
+
+std::set<std::string>& ModelsAndAnimationsDb::ModelAnimations(const std::string model){
+    // HACK FIX LGP READING.
+    std::string model_lower = model;
+    std::transform(model_lower.begin(), model_lower.end(), model_lower.begin(), ::tolower);
+    return map[model_lower];
+}
+
+std::string ModelsAndAnimationsDb::ModelMetaDataName(const std::string& model_name){
+    // If not in meta data then just replace .hrc with .mesh.
+    Ogre::String base_name;
+    VGears::StringUtil::splitBase(model_name, base_name);
+    return VGears::FF7::NameLookup::model(base_name) + ".mesh";
+}
+

+ 30 - 0
V-Gears-Installer/src/ScopedLgp.cpp

@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2022 The V-Gears Team
+ *
+ * This file is part of V-Gears
+ *
+ * V-Gears is free software: you can redistribute it and/or modify it under
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, version 3.0 (GPLv3) of the License.
+ *
+ * V-Gears is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "ScopedLgp.h"
+
+ScopedLgp::ScopedLgp(Ogre::Root* root, std::string full_path, std::string type, std::string group):
+  root_(root), full_path_(full_path), group_(group)
+{
+    if (root_){
+        //std::cout << "[RESOURCE] " << full_path_ << ", " << type << ", " << group_ << std::endl;
+        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(full_path_, type, group_);
+    }
+}
+
+ScopedLgp::~ScopedLgp(){
+     if (root_)
+         Ogre::ResourceGroupManager::getSingleton().removeResourceLocation(full_path_, group_);
+ }

+ 7 - 14
V-Gears-Installer/src/VGearsUtility.cpp

@@ -15,14 +15,11 @@
 
 #include "VGearsUtility.h"
 
-namespace VGears
-{
+namespace VGears{
+
     Utility::Utility(int argc, char *argv[]) :
-      Application(argc, argv),
-      frame_listener_(NULL),
-      scene_manager_(NULL),
-      camera_(NULL),
-      viewport_(NULL)
+      Application(argc, argv), frame_listener_(NULL), scene_manager_(NULL),
+      camera_(NULL), viewport_(NULL)
     {}
 
     Utility::~Utility(){}
@@ -31,15 +28,12 @@ namespace VGears
 
     void Utility::InitComponents(){
         Application::initComponents();
-        Ogre::ResourceGroupManager::getSingleton()
-          .initialiseAllResourceGroups();
+        Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
         Ogre::Root *root(getRoot());
         scene_manager_ = root->createSceneManager(Ogre::ST_GENERIC, "Scene");
         scene_manager_->clearScene();
         scene_manager_->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
-        Ogre::Light* directional_light = scene_manager_->createLight(
-          "directional_light"
-        );
+        Ogre::Light* directional_light = scene_manager_->createLight("directional_light");
         directional_light->setType(Ogre::Light::LT_DIRECTIONAL);
         directional_light->setDiffuseColour(Ogre::ColourValue(0.5, 0.5, 0.5));
         directional_light->setSpecularColour(Ogre::ColourValue(0.5, 0.5, 0.5));
@@ -52,8 +46,7 @@ namespace VGears
         viewport_ = window->addViewport(camera_);
         viewport_->setBackgroundColour(Ogre::ColourValue(0.0f, 0.4f, 0.0f));
         camera_->setAspectRatio(
-          Ogre::Real(viewport_->getActualWidth())
-          / Ogre::Real(viewport_->getActualHeight())
+          Ogre::Real(viewport_->getActualWidth()) / Ogre::Real(viewport_->getActualHeight())
         );
         frame_listener_ = new DisplayFrameListener(window);
         frame_listener_->setCamera(camera_);

+ 0 - 130
V-Gears-Installer/src/flevel.cpp

@@ -1,130 +0,0 @@
-/*
------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2013-07-31 Tobias Peters <tobias.peters@kreativeffekt.at>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-#include <cstdio>
-#include <iostream>
-
-#include <boost/filesystem.hpp>
-#include <boost/program_options.hpp>
-
-#include "common/FileSystem.h"
-#include "common/Logger.h"
-//#include "common/VGearsFLevelFile.h"
-
-using std::cout;
-using std::endl;
-
-namespace bfs = boost::filesystem;
-namespace bpo = boost::program_options;
-
-void extractSections( const bfs::path &file_in, const bfs::path &path_out )
-{
-    /*
-    File f( file_in.string() );
-    // TODO alternative implementation adapted to FLevel Resource
-    VGears::FLevelFile flevel( &f );
-    File** sections( flevel.getSections() );
-
-    bfs::path file_out;
-    file_out = path_out / ( file_in.stem().string() + ".script" );
-    sections[0]->WriteFile( file_out.string() );
-    file_out = path_out / ( file_in.stem().string() + ".cam_matrix" );
-    sections[1]->WriteFile( file_out.string() );
-    file_out = path_out / ( file_in.stem().string() + ".model_loader" );
-    sections[2]->WriteFile( file_out.string() );
-    file_out = path_out / ( file_in.stem().string() + ".palette" );
-    sections[3]->WriteFile( file_out.string() );
-    file_out = path_out / ( file_in.stem().string() + ".walkmesh" );
-    sections[4]->WriteFile( file_out.string() );
-    file_out = path_out / ( file_in.stem().string() + ".tilemap" );
-    sections[5]->WriteFile( file_out.string() );
-    file_out = path_out / ( file_in.stem().string() + ".encounter" );
-    sections[6]->WriteFile( file_out.string() );
-    file_out = path_out / ( file_in.stem().string() + ".trigger" );
-    sections[7]->WriteFile( file_out.string() );
-    file_out = path_out / ( file_in.stem().string() + ".background.ppm" );
-    sections[8]->WriteFile( file_out.string() );
-    file_out = path_out / ( file_in.stem().string() + ".background" );
-    sections[9]->WriteFile( file_out.string() );
-    */
-}
-
-int
-main(int ac, char *av[])
-{
-    const char* PO_HELP( "help" );
-    const char* PO_INPUT_FILE( "input-file" );
-    const char* PO_OUTPUT_PATH( "output-path" );
-
-    try {
-        bpo::options_description generic("Generic options");
-        generic.add_options()
-            ( PO_HELP, "produce help message" )
-            ;
-
-        // Hidden options, will be allowed both on command line and
-        // in config file, but will not be shown to the user.
-        bpo::options_description hidden("Hidden options");
-        hidden.add_options()
-            ( PO_INPUT_FILE , bpo::value< bfs::path >()->required(), "lzs compressed file" )
-            ( PO_OUTPUT_PATH
-              , bpo::value< bfs::path >()->default_value( "." )
-              , "path to output section files"
-            )
-            ;
-
-        bpo::positional_options_description p;
-        p.add( PO_INPUT_FILE , 1 )
-         .add( PO_OUTPUT_PATH, 1 );
-
-        bpo::options_description cmdline_options;
-        cmdline_options.add( generic ).add( hidden );
-        bpo::variables_map vm;
-        bpo::store( bpo::command_line_parser( ac, av ).options( cmdline_options ).positional( p ).run(), vm );
-
-        bfs::path self( av[0] );
-        if ( vm.count( PO_HELP ) )
-        {
-            cout << "Usage: " << self.stem().string()
-                 << " [options]"
-                 << " " << PO_INPUT_FILE
-                 << " " << PO_OUTPUT_PATH
-                 << endl
-                 << generic << "\n";
-            return 0;
-        }
-
-        bpo::notify( vm );
-        // TODO implement compression?
-        LOGGER = new Logger( self.stem().string() + ".log" );
-        extractSections( vm[ PO_INPUT_FILE ].as< bfs::path >(), vm[ PO_OUTPUT_PATH ].as< bfs::path >() );
-    }
-    catch( std::exception& e )
-    {
-        cout << e.what() << endl;
-        return 1;
-    }
-    return 0;
-}

+ 0 - 101
V-Gears-Installer/src/lzs.cpp

@@ -1,101 +0,0 @@
-/*
------------------------------------------------------------------------------
-The MIT License (MIT)
-
-Copyright (c) 2013-07-31 Tobias Peters <tobias.peters@kreativeffekt.at>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
------------------------------------------------------------------------------
-*/
-#include <cstdio>
-#include <iostream>
-
-#include <boost/filesystem.hpp>
-#include <boost/program_options.hpp>
-
-#include "common/FileSystem.h"
-#include "common/Logger.h"
-#include "common/LzsFile.h"
-
-using std::cout;
-using std::endl;
-
-namespace bfs = boost::filesystem;
-namespace bpo = boost::program_options;
-
-void decompress( const bfs::path &file_in, const bfs::path &file_out )
-{
-    LzsFile lzs( file_in.string() );
-    lzs.WriteFile( file_out.string() );
-}
-
-int
-main(int ac, char *av[])
-{
-    const char* PO_HELP( "help" );
-    const char* PO_INPUT_FILE( "input-file" );
-    const char* PO_OUTPUT_FILE( "output-file" );
-
-    try {
-        bpo::options_description generic("Generic options");
-        generic.add_options()
-            ( PO_HELP, "produce help message" )
-            ;
-
-        // Hidden options, will be allowed both on command line and
-        // in config file, but will not be shown to the user.
-        bpo::options_description hidden("Hidden options");
-        hidden.add_options()
-            ( PO_INPUT_FILE , bpo::value< bfs::path >()->required(), "lzs compressed file" )
-            ( PO_OUTPUT_FILE, bpo::value< bfs::path >()->required(), "output file" )
-            ;
-
-        bpo::positional_options_description p;
-        p.add( PO_INPUT_FILE , 1 )
-         .add( PO_OUTPUT_FILE, 1 );
-
-        bpo::options_description cmdline_options;
-        cmdline_options.add( generic ).add( hidden );
-        bpo::variables_map vm;
-        bpo::store( bpo::command_line_parser( ac, av ).options( cmdline_options ).positional( p ).run(), vm );
-
-        bfs::path self( av[0] );
-        if ( vm.count( PO_HELP ) )
-        {
-            cout << "Usage: " << self.stem().string()
-                 << " [options]"
-                 << " " << PO_INPUT_FILE
-                 << " " << PO_OUTPUT_FILE
-                 << endl
-                 << generic << "\n";
-            return 0;
-        }
-
-        bpo::notify( vm );
-        // TODO implement compression?
-        LOGGER = new Logger( self.stem().string() + ".log" );
-        decompress( vm[ PO_INPUT_FILE ].as< bfs::path >(), vm[ PO_OUTPUT_FILE ].as< bfs::path >() );
-    }
-    catch( std::exception& e )
-    {
-        cout << e.what() << endl;
-        return 1;
-    }
-    return 0;
-}

+ 2 - 1
V-Gears-Installer/src/main.cpp

@@ -14,7 +14,8 @@
  */
 
 #include <QtWidgets/QApplication>
-#include "../include/mainwindow.h"
+
+#include "MainWindow.h"
 
 /**
  * Installer main function.

+ 0 - 289
V-Gears-Installer/src/mainwindow.cpp

@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2022 The V-Gears Team
- *
- * This file is part of V-Gears
- *
- * V-Gears is free software: you can redistribute it and/or modify it under
- * terms of the GNU General Public License as published by the Free Software
- * Foundation, version 3.0 (GPLv3) of the License.
- *
- * V-Gears is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include "../include/mainwindow.h"
-#include "ui_mainwindow.h"
-#include "../include/ff7DataInstaller.h"
-#include <iostream>
-#include <QtCore/QProcess>
-#include <QtWidgets/QFileDialog>
-#include <QtCore/QDir>
-#include <QtCore/QSettings>
-#include <QtWidgets/QMessageBox>
-#include <QtCore/QTimer>
-/**
- * Indicates if an installer has already been created.
- */
-static bool installer_created = false;
-
-MainWindow::MainWindow(QWidget *parent) :
-  QMainWindow(parent), main_window_(new Ui::MainWindow)
-{
-    main_window_->setupUi(this);
-    // Goto the data tab by default.
-    main_window_->tabWidget->setCurrentIndex(1);
-    // Turn off the launcher tab for now since it dosen't actually work
-    //main_window_->tabWidget->setTabEnabled(0, false);
-    InitSettings();
-    main_window_->lineConfigDir->setText(
-      settings_->value("ConfigDir").toString()
-    );
-    main_window_->lineDataDir->setText(settings_->value("DataDir").toString());
-    main_window_->lineVGearsExe->setText(
-      settings_->value("VGearsEXE").toString()
-    );
-#ifdef _DEBUG
-    // Hard coded prebaked paths for debugging to save time
-    //main_window_->lineInput->setText("C:\\Games\\FF7\\data");
-    //main_window_->lineDataDir->setText(
-    //  "C:\\Users\\paul\\Desktop\\v-gears\\output\\data"
-    //);
-#endif
-    timer_ = new QTimer(this);
-    connect(timer_, SIGNAL(timeout()), this, SLOT(DoProgress()));
-}
-
-MainWindow::~MainWindow(){delete main_window_;
-}
-void MainWindow::InitSettings(void){
-    bool win = false;
-    #ifdef Q_OS_WIN
-        settings_ = new QSettings(
-          QCoreApplication::applicationDirPath() + "/" + "launcherSettings.ini",
-          QSettings::IniFormat
-        );
-        win = true;
-    #else
-        settings_ = new QSettings(
-          QSettings::NativeFormat,QSettings::UserScope, "v-gears", "launcher", 0
-        );
-    #endif
-    //Check settings
-    if(settings_->value("ConfigDir").isNull()){
-        if (win){
-            settings_->setValue(
-              "ConfigDir", QString("%1/v-gears").arg(QDir::homePath())
-            );
-        }
-        else{
-          settings_->setValue(
-            "ConfigDir", QString("%1/.v-gears").arg(QDir::homePath())
-          );
-        }
-    }
-
-    if(settings_->value("DataDir").isNull()){
-        if (win){
-            settings_->setValue(
-              "DataDir",QString("%1/v-gears/data").arg(QDir::homePath())
-            );
-        }
-        else{
-            settings_->setValue(
-              "DataDir",QString("%1/.v-gears/data").arg(QDir::homePath())
-            );
-        }
-    }
-
-    if (settings_->value("VGearsEXE").isNull()){
-        if (win){
-            settings_->setValue(
-              "VGearsEXE",QString("%1/v-gears.exe").arg(
-                 QCoreApplication::applicationDirPath()
-               )
-            );
-        }
-        else settings_->setValue("VGearsEXE", QString("/usr/games/v-gears"));
-    }
-}
-
-void MainWindow::on_lineConfigDir_editingFinished(){
-    settings_->setValue("ConfigDir",main_window_->lineConfigDir->text());
-}
-
-void MainWindow::on_btnConfigDir_clicked(){
-    QString temp = QFileDialog::getExistingDirectory(
-      this, tr("Select Location of VGears Configuration Data,"),
-      settings_->value("ConfigDir").toString());
-    if (!temp.isNull()){
-        settings_->setValue("ConfigDir", temp);
-        main_window_->lineConfigDir->setText(temp);
-    }
-}
-
-void MainWindow::on_lineVGearsExe_editingFinished(){
-    settings_->setValue("VGearsEXE",main_window_->lineVGearsExe->text());
-}
-
-void MainWindow::on_btnVGearsExe_clicked(){
-    QString temp = QFileDialog::getOpenFileName(
-      this, tr("Location of VGears Executable,"), QDir::rootPath());
-    if (!temp.isNull()){
-        settings_->setValue("VGearsEXE", temp);
-        main_window_->lineVGearsExe->setText(temp);
-    }
-}
-
-void MainWindow::on_btnLaunch_clicked(){
-    QString configDir(main_window_->lineConfigDir->text());
-    QString exe(main_window_->lineVGearsExe->text());
-    QStringList args;
-    args.append(
-      QString("--resources-file=%1/resources.cfg").arg(
-        main_window_->lineConfigDir->text())
-    );
-    args.append(
-      QString("--config-file=%1/v-gears.cfg").arg(
-        main_window_->lineConfigDir->text()
-      )
-    );
-    args.append(
-      QString("--plugins-file=/%1/plugins.cfg").arg(
-        main_window_->lineConfigDir->text()
-      )
-    );
-    // Check that the config dir is set up correctly.
-    QProcess vGears;
-    vGears.startDetached(exe,args,configDir);
-}
-
-
-void MainWindow::on_btnInput_clicked(){
-    QString temp = QFileDialog::getExistingDirectory(
-      this, tr("Location of Game Data),"),QDir::homePath()
-    );
-    main_window_->lineInput->setText(temp);
-}
-
-void MainWindow::on_lineDataDir_editingFinished(){
-    settings_->setValue("DataDir",main_window_->lineDataDir->text());
-}
-
-void MainWindow::on_btnDataDir_clicked(){
-    QString temp = QFileDialog::getExistingDirectory(
-      this, tr("Location of VGears Data),"),
-      settings_->value("DataDir").toString()
-    );
-    if(!temp.isNull()){
-        settings_->setValue("DataDir",temp);
-        main_window_->lineDataDir->setText(temp);
-    }
-}
-
-void MainWindow::on_btnGO_clicked(){
-    if (main_window_->lineInput->text().isEmpty()){
-        // TODO IVV: Default path, remove
-        main_window_->lineInput->setText("/home/ivalentin/data/");
-    }
-    //{
-    //    QMessageBox::critical(
-    //      this, tr("Input error"),
-    //      tr("No input to installed FF7 PC data provided")
-    //    );
-    //}
-    else if (main_window_->lineDataDir->text().isEmpty()){
-        QMessageBox::critical(
-          this, tr("Output error"), tr("No output path provided")
-        );
-    }
-    else{
-        // Normalize the paths so its in / format separators.
-        QString input = QDir::fromNativeSeparators(
-          main_window_->lineInput->text()
-        );
-        if (!input.endsWith("/")) input += "/";
-        QString output = QDir::fromNativeSeparators(
-          main_window_->lineDataDir->text()
-        );
-        if (!output.endsWith("/")) output += "/";
-        // TODO: Enumerate files or find some better way to do this.
-        const std::vector<std::string> required_files = {
-            "field/char.lgp",
-            "field/flevel.lgp"
-        };
-        // Ensure required files are in the input dir
-        for (auto& file : required_files){
-            QString fullPath = input + QString::fromStdString(file);
-            if (!QFile::exists(fullPath)){
-                QMessageBox::critical(
-                  this, tr("Missing input file"),
-                  tr("File not found: ") + fullPath);
-                return;
-            }
-        }
-        if (installer_created){
-            QMessageBox::critical(
-              this,
-              tr("Error"),
-              tr(
-                "Due to use of singletons install function can only be used "
-                "once, please restart the application."
-              )
-            );
-            return;
-        }
-        // Start data conversion
-        try{
-            installer_created = true;
-            std::cout << "[INSTALLER] Started";
-            std::cout << "[INSTALLER] Input path: "
-              << QDir::toNativeSeparators(input).toStdString() << std::endl;
-            std::cout << "[INSTALLER] Output path: "
-              << QDir::toNativeSeparators(output).toStdString() << std::endl;
-            installer_ = std::make_unique<FF7DataInstaller>(
-              QDir::toNativeSeparators(input).toStdString(),
-              QDir::toNativeSeparators(output).toStdString(),
-              [this](std::string outputLine){
-                main_window_->txtOutput->append(outputLine.c_str());
-              }
-            );
-            std::cout << "[INSTALLER] Calling OnInstallStartred. " << std::endl;
-            OnInstallStarted();
-            std::cout << "[INSTALLER] Called OnInstallStartred. " << std::endl;
-        }
-        catch (const std::exception& ex){
-            std::cout << "[INSTALLER] on_btnGo_clicked exception:. "
-              << ex.what() << std::endl;
-            OnInstallStopped();
-        }
-    }
-}
-
-void MainWindow::EnableUi(bool enable){
-    main_window_->btnGO->setEnabled(enable);
-    main_window_->lineInput->setEnabled(enable);
-    main_window_->btnInput->setEnabled(enable);
-    main_window_->lineDataDir->setEnabled(enable);
-    main_window_->btnDataDir->setEnabled(enable);
-    main_window_->progressBar->setValue(0);
-    if (!enable) timer_->start(0);
-    else timer_->stop();
-}
-
-void MainWindow::OnInstallStarted(){EnableUi(false);}
-
-void MainWindow::OnInstallStopped(){EnableUi(true);}
-
-void MainWindow::DoProgress(){
-    try{
-        const int progress = installer_->Progress();
-        main_window_->progressBar->setValue(progress);
-        if (progress >= 100) OnInstallStopped();
-    }
-    catch (const std::exception& ex){
-        OnInstallStopped();
-        QMessageBox::critical(this, tr("Data conversion exception"), ex.what());
-    }
-}