Просмотр исходного кода

Merge pull request #142 from paulsapps/installer

Install texts
Paul 11 лет назад
Родитель
Сommit
602e2a895d

+ 10 - 4
QGearsMain/include/core/DialogsManager.h

@@ -60,6 +60,10 @@ struct MessageData
     UiWidget* cursor;
 
     MessageState state;
+    int x = 0;
+    int y = 0;
+    int w = 0;
+    int h = 0;
 
     std::vector< ScriptId > sync;
 
@@ -89,11 +93,13 @@ public:
     void Update();
     void Clear();
 
-    void ShowDialog( const char* d_name, const char* name, const int x, const int y );
-    void ShowText( const char* d_name, const char* text, const int x, const int y, const int width, const int height );
-    int Sync( const char* d_name );
+    void OpenDialog(const char* d_name, int x, int y, int w, int h); // aka dialog_open
+    void SetText( const char* d_name, const char* text ); // aka dialog_set_text
+    int Sync( const char* d_name ); // aka dialog_wait_for_close
+    void Hide(const char* d_name); // aka dialog_close
+
     void SetVariable( const char* d_name, const char* name, const char* value );
-    void Hide( const char* d_name );
+
     void SetClickable( const char* d_name, const bool clickable );
     void SetCursor( const char* d_name, const int first_row, const int last_row );
     int GetCursor( const char* d_name ) const;

+ 6 - 6
QGearsMain/include/core/ScriptManagerBinds.h

@@ -168,11 +168,11 @@ ScriptManager::InitBinds()
     luabind::module( m_LuaState )
     [
         luabind::class_< DialogsManager >( "Dialog" )
-            .def( "show_dialog", ( void( DialogsManager::* )( const char*, const char*, const int, const int ) ) &DialogsManager::ShowDialog )
-            .def( "show_text", ( void( DialogsManager::* )( const char*, const char*, const int, const int, const int, const int ) ) &DialogsManager::ShowText )
-            .def( "sync", ( int( DialogsManager::* )( const char* ) ) &DialogsManager::Sync, luabind::yield )
-            .def( "set_variable", ( void( DialogsManager::* )( const char*, const char*, const char* ) ) &DialogsManager::SetVariable )
-            .def( "hide", ( void( DialogsManager::* )( const char* ) ) &DialogsManager::Hide )
+            .def( "dialog_open", ( void( DialogsManager::* )( const char*, int, int, int, int ) ) &DialogsManager::OpenDialog )
+            .def( "dialog_set_text", ( void( DialogsManager::* )( const char*, const char* ) ) &DialogsManager::SetText )
+            .def( "dialog_wait_for_close", ( int( DialogsManager::* )( const char* ) ) &DialogsManager::Sync, luabind::yield )
+            .def( "dialog_close", (void(DialogsManager::*)(const char*)) &DialogsManager::Hide)
+            .def( "set_variable", ( void( DialogsManager::* )( const char*, const char*, const char* ) ) &DialogsManager::SetVariable )           
             .def( "set_clickable", ( void( DialogsManager::* )( const char*, const bool ) ) &DialogsManager::SetClickable )
             .def( "set_cursor", ( void( DialogsManager::* )( const char*, const int, const int ) ) &DialogsManager::SetCursor )
             .def( "get_cursor", ( int( DialogsManager::* )( const char* ) ) &DialogsManager::GetCursor )
@@ -246,7 +246,7 @@ ScriptManager::InitBinds()
     luabind::globals( m_LuaState )[ "entity_manager" ] = boost::ref( *( EntityManager::getSingletonPtr() ) );
     luabind::globals( m_LuaState )[ "background2d" ] = boost::ref( *( EntityManager::getSingletonPtr()->GetBackground2D() ) );
     luabind::globals( m_LuaState )[ "walkmesh" ] = boost::ref( *( EntityManager::getSingletonPtr()->GetWalkmesh() ) );
-    luabind::globals( m_LuaState )[ "message" ] = boost::ref( *( DialogsManager::getSingletonPtr() ) );
+    luabind::globals( m_LuaState )[ "dialog" ] = boost::ref( *( DialogsManager::getSingletonPtr() ) );
     luabind::globals( m_LuaState )[ "ui_manager" ] = boost::ref( *( UiManager::getSingletonPtr() ) );
     luabind::globals( m_LuaState )[ "world_map_module" ] = boost::ref( *( QGears::WorldMapModule::getSingletonPtr() ) );
     luabind::globals( m_LuaState )[ "timer" ] = boost::ref( *( Timer::getSingletonPtr() ) );

+ 47 - 40
QGearsMain/src/core/DialogsManager.cpp

@@ -268,54 +268,65 @@ DialogsManager::Clear()
 
 
 void
-DialogsManager::ShowDialog( const char* d_name, const char* name, const int x, const int y )
+DialogsManager::OpenDialog(const char* d_name, int x, int y, int w, int h)
 {
     int id = GetMessageId( d_name );
     if( id == -1 )
     {
-        LOG_TRIVIAL( "[SCRIPT] show_dialog: dialog \"" + Ogre::String( d_name ) + "\" doesn't exist." );
+        LOG_TRIVIAL( "[SCRIPT] dialog_open: dialog \"" + Ogre::String( d_name ) + "\" doesn't exist." );
         return;
     }
 
-    if( m_Messages[ id ]->state != MS_CLOSED )
+    MessageData* data = m_Messages[id];
+    if( data->state != MS_CLOSED )
     {
-        LOG_TRIVIAL( "[SCRIPT] show_dialog: dialog \"" + Ogre::String( d_name ) + " already shown. Close it first." );
+        LOG_TRIVIAL( "[SCRIPT] dialog_open: dialog \"" + Ogre::String( d_name ) + " already created. Close it first." );
         return;
     }
 
-    float width, height;
-    TiXmlNode* text = TextManager::getSingleton().GetDialog( name, width, height );
-    if( text != NULL )
-    {
-        m_Messages[ id ]->text_area->SetText( text );
-        ShowMessage( id, x, y, width, height );
-    }
-    else
-    {
-        LOG_TRIVIAL( "[SCRIPT] show_dialog: dialog text \"" + Ogre::String( name ) + "\" doesn't exist." );
-    }
+    data->x = x;
+    data->y = y;
+    data->w = w;
+    data->h = h;
+
+    LOG_TRIVIAL( "[SCRIPT] dialog_open: dialog(" +
+        std::to_string(x) + "," + std::to_string(y) + "," + 
+        std::to_string(w) + "," + std::to_string(h) + ")");
+    
 }
 
 
 
 void
-DialogsManager::ShowText( const char* d_name, const char* text, const int x, const int y, const int width, const int height )
+DialogsManager::SetText(const char* d_name, const char* text)
 {
-    int id = GetMessageId( d_name );
-    if( id == -1 )
+    int id = GetMessageId(d_name);
+    if (id == -1)
     {
-        LOG_TRIVIAL( "[SCRIPT] show_text: dialog \"" + Ogre::String( d_name ) + "\" doesn't exist." );
+        LOG_TRIVIAL("[SCRIPT] show_text: dialog \"" + Ogre::String(d_name) + "\" doesn't exist.");
         return;
     }
 
-    if( m_Messages[ id ]->state != MS_CLOSED )
+    MessageData* data = m_Messages[id];
+
+
+    // XML data can change dialog w/h VS whats in the lua script
+    float width = 0.0f;
+    float height = 0.0f;
+    TiXmlNode* xmlText = TextManager::getSingleton().GetDialog(text, width, height);
+    if (xmlText != NULL)
     {
-        LOG_TRIVIAL( "[SCRIPT] show_dialog: dialog \"" + Ogre::String( d_name ) + " already shown. Close it first." );
-        return;
+        m_Messages[id]->text_area->SetText(xmlText);
+        ShowMessage(id, data->x, data->y, 
+            width == 0.0f ? data->w : width, 
+            height == 0.0f ? data->h : height);
+    }
+    else
+    {
+        m_Messages[id]->text_area->SetText(std::string("[ERROR string not found:] ") + text);
+        ShowMessage(id, data->x, data->y, data->w, data->h);
     }
 
-    m_Messages[ id ]->text_area->SetText( text );
-    ShowMessage( id, x, y, width, height );
 }
 
 
@@ -336,22 +347,6 @@ DialogsManager::Sync( const char* d_name )
 }
 
 
-
-void
-DialogsManager::SetVariable( const char* d_name, const char* name, const char* value )
-{
-    int id = GetMessageId( d_name );
-    if( id == -1 )
-    {
-        LOG_TRIVIAL( "[SCRIPT] set_variable: dialog \"" + Ogre::String( d_name ) + "\" doesn't exist." );
-        return;
-    }
-
-    m_Messages[ id ]->text_area->SetVariable( name, value );
-}
-
-
-
 void
 DialogsManager::Hide( const char* d_name )
 {
@@ -372,6 +367,18 @@ DialogsManager::Hide( const char* d_name )
 }
 
 
+void
+DialogsManager::SetVariable(const char* d_name, const char* name, const char* value)
+{
+    int id = GetMessageId(d_name);
+    if (id == -1)
+    {
+        LOG_TRIVIAL("[SCRIPT] set_variable: dialog \"" + Ogre::String(d_name) + "\" doesn't exist.");
+        return;
+    }
+
+    m_Messages[id]->text_area->SetVariable(name, value);
+}
 
 void
 DialogsManager::SetClickable( const char* d_name, const bool clickable )

+ 1 - 1
QGearsMain/src/core/ScriptManager.cpp

@@ -197,7 +197,7 @@ ScriptManager::Update(const ScriptManager::Type type)
                             }
                             catch(luabind::error& /*e*/)
                             {
-                                LOG_ERROR(Ogre::String(lua_tostring(m_ScriptEntity[i].queue[0].state , -1)));
+                                LOG_ERROR("LUA error in " + m_ScriptEntity[i].name + " in function " + m_ScriptEntity[i].queue[0].function + " details: " + Ogre::String(lua_tostring(m_ScriptEntity[i].queue[0].state, -1)));
                             }
 
                             if(ret == 0)

+ 2 - 2
QGearsMain/src/core/XmlTextFile.cpp

@@ -37,8 +37,8 @@ XmlTextFile::LoadTexts()
         else if( node->Type() == TiXmlNode::TINYXML_ELEMENT && node->ValueStr() == "dialog" )
         {
             Ogre::String name = GetString( node, "name" );
-            float width = GetFloat( node, "width" );
-            float height = GetFloat( node, "height" );
+            float width = GetFloat( node, "width", 0.0f );
+            float height = GetFloat( node, "height", 0.0f );
             TextManager::getSingleton().AddDialog( name, node->Clone(), width, height );
         }
         node = node->NextSibling();

+ 1 - 1
dependencies/SUDM

@@ -1 +1 @@
-Subproject commit a02716798dfc67e0976041e2e7e544da3610c366
+Subproject commit da92262c8e9cef817f884fce0044aa1d5dc7a8f2

+ 1 - 1
utilities/ffvii_field_dat_dumper/src/DatFile.cpp

@@ -335,7 +335,7 @@ DatFile::DumpText( const Ogre::String& export_path, const Field& field, bool eng
 
         export_text->Log(dialog);
         dialog.clear();
-        export_text->LogW( "<dialog id=\"" + IntToString(m_Dialogs[i]) + "\">" );
+        export_text->LogW( "<dialog id=\"" + std::to_string(m_Dialogs[i]) + "\">" );
 
         for (unsigned char temp = 0x00; ; ++offset)
         {

+ 2 - 0
utilities/q-gears-launcher/CMakeLists.txt

@@ -7,12 +7,14 @@ include_directories (
 set ( q-gears-launcher_HDRS
 	src/mainwindow.h
 	src/ff7DataInstaller.h
+    src/ff7FieldTextWriter.h
 	)
 
 set ( q-gears-launcher_SRCS
 	src/main.cpp
 	src/mainwindow.cpp
 	src/ff7DataInstaller.cpp
+    src/ff7FieldTextWriter.cpp
 	)
 
 set ( q-gears-launcher_UIS

+ 13 - 1
utilities/q-gears-launcher/src/ff7DataInstaller.cpp

@@ -357,7 +357,9 @@ static float FieldScaleFactor(const FieldScaleFactorMap& scaleFactorMap, size_t
     return it->second;
 }
 
+
 static void FF7PcFieldToQGearsField(
+    FF7FieldTextWriter& fieldTextWriter,
     QGears::FLevelFilePtr& field,
     const std::string& outDir,
     const std::vector<std::string>& fieldIdToNameLookup,
@@ -396,6 +398,14 @@ static void FF7PcFieldToQGearsField(
         if (scriptFile.is_open())
         {
             scriptFile << decompiled.luaScript;
+            try
+            {
+                fieldTextWriter.Write(rawFieldData, field->getName());
+            }
+            catch (const std::out_of_range&)
+            {
+                fnWriteOutputLine("Failed to read texts");
+            }
         }
         else
         {
@@ -939,6 +949,7 @@ void FF7DataInstaller::CollectionFieldSpawnAndScaleFactors()
         mField.setNull();
         mIteratorCounter = 0;
         mState = eConvertFieldsIteration;
+        mFieldTextWriter.Begin(mOutputDir + "/texts/english/dialogs_mission1.xml");
     }
 }
 
@@ -963,7 +974,7 @@ void FF7DataInstaller::ConvertFieldsIteration()
                 CreateDir(FieldMapDir() + "/" + resourceName);
 
                 QGears::FLevelFilePtr field = QGears::LZSFLevelFileManager::getSingleton().load(resourceName, "FFVIIFields").staticCast<QGears::FLevelFile>();
-                FF7PcFieldToQGearsField(field, mOutputDir, mMapList, mCollectedSpawnPoints, mCollectedScaleFactors, mModelsAndAnimationsUsedByConvertedFields, mConvertedMapList, mfnWriteOutputLine);
+                FF7PcFieldToQGearsField(mFieldTextWriter, field, mOutputDir, mMapList, mCollectedSpawnPoints, mCollectedScaleFactors, mModelsAndAnimationsUsedByConvertedFields, mConvertedMapList, mfnWriteOutputLine);
             }
             else
             {
@@ -980,6 +991,7 @@ void FF7DataInstaller::ConvertFieldsIteration()
     {
         mIteratorCounter = 0;
         mState = eWriteMapListOfConvertedFieldsStart;
+        mFieldTextWriter.End();
     }
 }
 

+ 3 - 0
utilities/q-gears-launcher/src/ff7DataInstaller.h

@@ -8,6 +8,7 @@
 #include "data/QGearsTriggersFile.h"
 #include "common/QGearsStringUtil.h"
 #include "data/QGearsFLevelFile.h"
+#include "ff7FieldTextWriter.h"
 
 class ScopedLgp
 {
@@ -169,4 +170,6 @@ private:
     ModelAnimationMap::iterator mModelAnimationMapIterator;
 
     std::function<void(std::string)> mfnWriteOutputLine;
+
+    FF7FieldTextWriter mFieldTextWriter;
 };

+ 514 - 0
utilities/q-gears-launcher/src/ff7FieldTextWriter.cpp

@@ -0,0 +1,514 @@
+#include "ff7FieldTextWriter.h"
+
+// TODO: Refactor me - this is based on/copied from DatFile::DumpText
+
+
+
+//////////////////////////////////////////////
+static const unsigned short english_chars[256] = {
+    // 0    1       2       3       4       5       6       7       8       9       A       B       C       D       E       F
+    0x2000, 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2600, 0x2700, 0x2800, 0x2900, 0x2A00, 0x2B00, 0x2C00, 0x2D00, 0x2E00, 0x2F00, // 0x00 - 0x0F
+    0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700, 0x3800, 0x3900, 0x3A00, 0x3B00, 0x3C00, 0x3D00, 0x3E00, 0x3F00, // 0x10 - 0x1F
+    0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700, 0x4800, 0x4900, 0x4A00, 0x4B00, 0x4C00, 0x4D00, 0x4E00, 0x4F00, // 0x20 - 0x2F
+    0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700, 0x5800, 0x5900, 0x5A00, 0x5B00, 0x5C00, 0x5D00, 0x5E00, 0x5F00, // 0x30 - 0x3F
+    0x6000, 0x6100, 0x6200, 0x6300, 0x6400, 0x6500, 0x6600, 0x6700, 0x6800, 0x6900, 0x6A00, 0x6B00, 0x6C00, 0x6D00, 0x6E00, 0x6F00, // 0x40 - 0x4F
+    0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700, 0x7800, 0x7900, 0x7A00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x50 - 0x5F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x60 - 0x6F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x70 - 0x7F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x80 - 0x8F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x90 - 0x9F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2620, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xA0 - 0xAF
+    0x0000, 0x0000, 0x1C20, 0x1D20, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xB0 - 0xBF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xC0 - 0xCF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xD0 - 0xDF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0D00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xE0 - 0xEF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xF0 - 0xFF
+};
+
+static const unsigned short japanese_chars[256] = {
+    // 0    1       2       3       4       5       6       7       8       9       A       B       C       D       E       F
+    0xD030, 0x7030, 0xD330, 0x7330, 0xD630, 0x7630, 0xD930, 0x0000, 0xDC30, 0x7C30, 0xAC30, 0x4C30, 0xAE30, 0x4E30, 0xB030, 0x5030, // 0x00 - 0x0F
+    0xB230, 0x5230, 0xB430, 0x5430, 0xB630, 0x5630, 0xB830, 0x5830, 0xBA30, 0x5A30, 0xBC30, 0x5C30, 0xBE30, 0x5E30, 0xC030, 0x6030, // 0x10 - 0x1F
+    0x0000, 0x0000, 0xC530, 0x0000, 0xC730, 0x6730, 0xC930, 0x6930, 0x0000, 0xD130, 0x7130, 0xD430, 0x0000, 0xD730, 0x7730, 0xDA30, // 0x20 - 0x2F
+    0x0000, 0xDD30, 0x0000, 0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700, 0x3800, 0x3900, 0x0130, 0x0230, 0x2000, // 0x30 - 0x3F
+    0xCF30, 0x6F30, 0xD230, 0x7230, 0xD530, 0x7530, 0xD830, 0x7830, 0xDB30, 0x7B30, 0xAB30, 0x4B30, 0xAD30, 0x4D30, 0xAF30, 0x4F30, // 0x40 - 0x4F
+    0xB130, 0x5130, 0xB330, 0x5330, 0xB530, 0x5530, 0xB730, 0x5730, 0xB930, 0x5930, 0xBB30, 0x5B30, 0xBD30, 0x5D30, 0xBF30, 0x5F30, // 0x50 - 0x5F
+    0xC130, 0x6130, 0xC430, 0x6430, 0xC630, 0x6630, 0xC830, 0x6830, 0xA630, 0x4630, 0xA230, 0x4230, 0xA430, 0x4430, 0xA830, 0x4830, // 0x60 - 0x6F
+    0xAA30, 0x4A30, 0xCA30, 0x6A30, 0xCB30, 0x6B30, 0x0000, 0x6C30, 0xCD30, 0x6D30, 0xCE30, 0x6E30, 0xDE30, 0x7E30, 0xDF30, 0x7F30, // 0x70 - 0x7F
+    0xE030, 0x8030, 0xE130, 0x8130, 0xE230, 0x8230, 0xE930, 0x8930, 0xEA30, 0x8A30, 0xEB30, 0x8B30, 0xEC30, 0x8C30, 0xED30, 0x8D30, // 0x80 - 0x8F
+    0xE430, 0x8430, 0xE630, 0x0000, 0x0000, 0x8830, 0xEF30, 0x8F30, 0xF330, 0x9330, 0x0000, 0x9230, 0xC330, 0x6330, 0xE330, 0x8330, // 0x90 - 0x9F
+    0xE530, 0x8530, 0xE730, 0x8730, 0xA130, 0x4130, 0xA330, 0x0000, 0xA530, 0x0000, 0xA730, 0x4730, 0x0000, 0x4930, 0x01FF, 0x1FFF, // 0xA0 - 0xAF
+    0x0E30, 0x0F30, 0x0000, 0x0000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700, 0x4800, 0x4900, 0x4A00, 0x4B00, 0x4C00, // 0xB0 - 0xBF
+    0x4D00, 0x4E00, 0x4F00, 0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFB30, 0x0000, // 0xC0 - 0xCF
+    0xFC30, 0x7E00, 0x2620, 0x0000, 0x0000, 0x0000, 0x0000, 0x1030, 0x1130, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C30, 0x0D30, 0x08FF, // 0xD0 - 0xDF
+    0x09FF, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0D00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xE0 - 0xEF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xF0 - 0xFF
+};
+
+
+
+static const unsigned short japanese_chars_fa[256] = {
+    // 0    1       2       3       4       5       6       7       8       9       A       B       C       D       E       F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2759, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x00 - 0x0F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x10 - 0x1F
+    0x0672, 0x7F4F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3478, 0x4466, 0x8364, 0x0000, 0x0000, 0x0000, // 0x20 - 0x2F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x666B, 0x5E79, 0x0000, 0x0000, 0xA898, 0x0000, 0x176C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x30 - 0x3F
+    0x885B, 0x0000, 0x7D54, 0x0000, 0xD552, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6297, 0x0000, 0x0000, 0x0000, 0x0854, 0x0000, // 0x40 - 0x4F
+    0x0000, 0x0000, 0x0E66, 0x0000, 0x0000, 0x9C62, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x004E, 0x0000, 0x0580, // 0x50 - 0x5F
+    0x0000, 0x0000, 0x857F, 0x0000, 0x0000, 0x0000, 0x9950, 0x6856, 0x0000, 0x549B, 0xD56C, 0x0000, 0x0000, 0x0000, 0x0000, 0xFA51, // 0x60 - 0x6F
+    0x0163, 0xF876, 0x4B62, 0x0000, 0xBA78, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB965, 0x4C88, 0x0000, // 0x70 - 0x7F
+    0x9A5B, 0x0000, 0x0000, 0x4D52, 0x1F77, 0x0000, 0x9A89, 0x1752, 0x8C5F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xDE56, 0x0000, // 0x80 - 0x8F
+    0x9A7D, 0x7565, 0x0000, 0x0000, 0x0000, 0x0000, 0x3E5C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0882, 0x0000, 0x0000, // 0x90 - 0x9F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3E5F, 0x0000, 0x0000, 0x0000, 0x4266, 0x0000, 0x0000, 0x2662, 0x0000, // 0xA0 - 0xAF
+    0x0000, 0x0000, 0x0000, 0x0000, 0xB751, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xEA8C, 0x0000, 0x0000, 0x0000, // 0xB0 - 0xBF
+    0xCD53, 0x0000, 0xEE76, 0x0000, 0x0000, 0x9B52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7551, 0x0000, 0x0000, 0x0000, // 0xC0 - 0xCF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xD0 - 0xDF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xE0 - 0xEF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xF0 - 0xFF
+};
+
+
+
+static const unsigned short japanese_chars_fb[256] = {
+    // 0    1       2       3       4       5       6       7       8       9       A       B       C       D       E       F
+    0x0000, 0x0000, 0xB182, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0B4E, 0x0000, 0x6551, 0x4851, 0x0D4E, 0x505B, 0x9B4F, 0x4B5C, // 0x00 - 0x0F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8E96, 0x0000, 0x0000, 0xE890, 0x0000, 0x3458, 0x0000, 0xF24E, 0x9395, 0x0000, 0x0000, // 0x10 - 0x1F
+    0x5096, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x554F, 0x0000, 0x9965, 0x0000, 0x0A4E, 0x0000, 0x8B4E, 0x0000, 0x0000, // 0x20 - 0x2F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6559, 0x0000, 0x0000, 0x0000, 0x1D52, 0x5167, 0x0000, 0x0000, 0x0000, 0x0000, // 0x30 - 0x3F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x40 - 0x4F
+    0x0000, 0x0000, 0xCA8E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xBA87, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x50 - 0x5F
+    0x0000, 0x7751, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB672, 0x4B61, 0x0000, // 0x60 - 0x6F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B95, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x70 - 0x7F
+    0x0000, 0x0C54, 0x1F90, 0x4590, 0x0000, 0x0000, 0x0000, 0x0000, 0x7354, 0x0000, 0x0000, 0x0000, 0x0D50, 0x0000, 0x0000, 0x0000, // 0x80 - 0x8F
+    0x0000, 0xBA4E, 0xCA4E, 0x0000, 0x0000, 0x535F, 0x0000, 0x0000, 0xDB98, 0xE54E, 0x1659, 0x0000, 0x0000, 0x0000, 0xAB8E, 0x0000, // 0x90 - 0x9F
+    0xCB65, 0x0000, 0x0000, 0x0000, 0x5F6A, 0xB068, 0x0000, 0x8970, 0xB065, 0x214E, 0x2C67, 0x1B54, 0x0000, 0x8551, 0x5C4F, 0x668B, // 0xA0 - 0xAF
+    0x7972, 0x0000, 0x0000, 0x0000, 0x747A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB38D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xB0 - 0xBF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7795, 0x0000, 0x0000, 0x5458, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B89, // 0xC0 - 0xCF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4351, 0x0000, 0x0000, 0x0000, 0x427D, 0x0000, 0x0000, 0x0D54, 0x0000, 0x0000, // 0xD0 - 0xDF
+    0x0000, 0x1062, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xE0 - 0xEF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xF0 - 0xFF
+};
+
+
+
+static const unsigned short japanese_chars_fc[256] = {
+    // 0    1       2       3       4       5       6       7       8       9       A       B       C       D       E       F
+    0x0000, 0x0000, 0x188A, 0x0000, 0x7890, 0x6A75, 0x5788, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x00 - 0x0F
+    0x9358, 0xC35F, 0x0000, 0x0000, 0x0000, 0x0000, 0x5390, 0x0000, 0x0000, 0x0000, 0x0000, 0xFB5D, 0x0000, 0x0000, 0x0000, 0x0000, // 0x10 - 0x1F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x884E, 0x0000, 0x3D84, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x20 - 0x2F
+    0xE565, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE353, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x30 - 0x3F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x296E, 0x0000, 0x0000, 0x0000, 0x0000, 0x708D, 0x0000, 0x0000, 0x0000, 0x0000, // 0x40 - 0x4F
+    0x0000, 0x0000, 0x7153, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x008A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x50 - 0x5F
+    0x3159, 0x5765, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x60 - 0x6F
+    0x0000, 0x0000, 0xBC62, 0x0000, 0x0000, 0x0000, 0x5965, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x70 - 0x7F
+    0x0000, 0x0000, 0x0000, 0x0000, 0xC253, 0xE577, 0x5E80, 0x0000, 0xD54E, 0x2552, 0xC696, 0xE14F, 0x2875, 0x0000, 0x0000, 0x0000, // 0x80 - 0x8F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE965, 0x0000, 0x0000, 0x0000, 0x0000, 0x718A, 0x305E, 0x0000, 0x0000, 0x0000, // 0x90 - 0x9F
+    0x0000, 0xF258, 0x6E6D, 0x0000, 0xA052, 0x0000, 0x047D, 0x0000, 0x3C79, 0x5F67, 0x0000, 0x3775, 0x0000, 0x0000, 0x0000, 0xCB7A, // 0xA0 - 0xAF
+    0x0000, 0xFA4F, 0x0000, 0x0000, 0x0000, 0xC179, 0x0000, 0x0000, 0x1250, 0x114F, 0x0000, 0x0000, 0x0000, 0xA952, 0x0000, 0x0000, // 0xB0 - 0xBF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xAC8A, 0x0000, 0x0000, 0xF167, 0x0000, 0x0000, // 0xC0 - 0xCF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xD0 - 0xDF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xE0 - 0xEF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xF0 - 0xFF
+};
+
+
+
+static const unsigned short japanese_chars_fd[256] = {
+    // 0    1       2       3       4       5       6       7       8       9       A       B       C       D       E       F
+    0x0000, 0x1D4F, 0x0000, 0xA263, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x00 - 0x0F
+    0xE682, 0x0000, 0xF056, 0x0000, 0x0000, 0x0000, 0x0000, 0xA25B, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x10 - 0x1F
+    0x0000, 0x2B59, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB88C, 0x1F67, 0x0000, 0x0000, 0x0000, 0x0000, 0xDD4F, 0x2F5E, // 0x20 - 0x2F
+    0x0000, 0x0000, 0x0000, 0x1154, 0x0000, 0x0000, 0x7289, 0x0000, 0x216B, 0x0000, 0x207D, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x30 - 0x3F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB78C, 0x0000, 0x0000, 0x0000, 0x7C5E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x40 - 0x4F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x8179, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x50 - 0x5F
+    0x0000, 0x975E, 0x0000, 0x0000, 0x0000, 0xCA7D, 0x1478, 0x0000, 0x0000, 0x8766, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x60 - 0x6F
+    0xC599, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x70 - 0x7F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFD88, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x80 - 0x8F
+    0x0000, 0x0000, 0x3293, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5453, 0x0000, 0x0000, // 0x90 - 0x9F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x3181, 0x0000, 0x8D8E, 0x0000, 0x0000, 0x0000, 0x0000, 0x3052, 0x0000, 0x0000, 0x0000, 0x0000, // 0xA0 - 0xAF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xB0 - 0xBF
+    0x9F52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5291, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xC0 - 0xCF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xD0 - 0xDF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xE0 - 0xEF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xF0 - 0xFF
+};
+
+
+
+static const unsigned short japanese_chars_fe[256] = {
+    // 0    1       2       3       4       5       6       7       8       9       A       B       C       D       E       F
+    0x0000, 0x0000, 0x0000, 0x667D, 0x0000, 0x0000, 0x0000, 0xAD65, 0x0000, 0x0000, 0xB96C, 0x0000, 0xD550, 0x585B, 0x0000, 0x0000, // 0x00 - 0x0F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x10 - 0x1F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8B4F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x20 - 0x2F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x9758, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x30 - 0x3F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x40 - 0x4F
+    0x0000, 0x0000, 0x0000, 0xB48C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4256, 0xF158, 0x0000, 0x0000, 0x0000, 0x0000, // 0x50 - 0x5F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xB54F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x60 - 0x6F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1D8B, 0x0000, 0x0000, 0x0000, 0xA14F, 0x206B, 0xC45B, 0xD95F, // 0x70 - 0x7F
+    0x0000, 0x944E, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xA65E, 0x0000, 0x0000, 0x0000, 0x0000, 0x988A, // 0x80 - 0x8F
+    0x0000, 0x0000, 0x298F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x668A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0x90 - 0x9F
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7272, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xA0 - 0xAF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xC079, 0x0000, 0xFD8E, 0x0000, 0x0000, 0x0000, // 0xB0 - 0xBF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3B52, // 0xC0 - 0xCF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xD0 - 0xDF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xE0 - 0xEF
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, // 0xF0 - 0xFF
+};
+
+void FF7FieldTextWriter::Begin(std::string fileName)
+{
+    mData.clear();
+    mLogger.reset(new Logger(fileName));
+
+    // Write BOM
+    /* FIX ME - need to write data as UTF8
+    std::vector< unsigned char > bomBytes;
+    bomBytes.push_back(0xFF);
+    bomBytes.push_back(0xFE);
+    mLogger->Log(bomBytes);
+    */
+    mLogger->Log("<texts>\n");
+}
+
+u16 FF7FieldTextWriter::GetU16LE(u32 offset)
+{
+    return *reinterpret_cast<u16*>(&mData[offset]);
+}
+
+u8 FF7FieldTextWriter::GetU8(u32 offset)
+{
+    return mData[offset];
+}
+
+void FF7FieldTextWriter::Write(const std::vector<u8>& scriptSectionBuffer, std::string fieldName, bool english /*= true*/)
+{
+    mData = scriptSectionBuffer;
+
+
+    // get sector 1 offset (scripts and dialog)
+    u32 offset_to_sector = 0; // Our buffer IS the start of scripts and dialog
+    /*
+    u16 unknown1;			// Always 0x0502
+    char nEntities;			// Number of entities
+    char nModels;			// Number of models
+    u16 wStringOffset;			// Offset to strings code below extracts this offset
+    */
+    u16 offset_to_dialogs = GetU16LE(offset_to_sector + 0x04);
+
+    std::vector< unsigned char > dialog; // text line to write out
+
+
+    const u16 dialogCount = GetU16LE(offset_to_sector + offset_to_dialogs);
+    for (u16 i = 0; i <dialogCount; ++i)
+    {
+     
+        // get offset of string data
+        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
+
+        mLogger->Log(dialog);
+        dialog.clear();
+        mLogger->Log("<dialog name=\"" + fieldName + "_" + std::to_string(i) + "\">");
+
+        for (unsigned char temp = 0x00;; ++offset)
+        {
+            temp = GetU8(offset);
+            if (temp == 0xFF)
+            {
+                break;
+            }
+
+            if (temp == 0xE0 && english == true)
+            {
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+            }
+            else if (temp == 0xE1 && english == true)
+            {
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+            }
+            else if (temp == 0xE2 && english == true)
+            {
+                dialog.push_back(english_chars[0x0C] >> 8); //dialog.push_back(english_chars[0x0C] & 0xFF);
+                dialog.push_back(english_chars[0x00] >> 8); //dialog.push_back(english_chars[0x00] & 0xFF);
+            }
+            else if (temp == 0xE8)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<next_page />");
+            }
+            else if (temp == 0xEA)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<include name=\"char_cloud\" />");
+            }
+            else if (temp == 0xEB)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<include name=\"char_barret\" />");
+            }
+            else if (temp == 0xEC)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<character id=\"2\" />");
+            }
+            else if (temp == 0xED)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<character id=\"3\" />");
+            }
+            else if (temp == 0xEE)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<character id=\"4\" />");
+            }
+            else if (temp == 0xEF)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<character id=\"5\" />");
+            }
+            else if (temp == 0xF0)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<character id=\"6\" />");
+            }
+            else if (temp == 0xF1)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<character id=\"7\" />");
+            }
+            else if (temp == 0xF2)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<character id=\"8\" />");
+            }
+            else if (temp == 0xF3)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<character party_id=\"0\" />");
+            }
+            else if (temp == 0xF4)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<character party_id=\"1\" />");
+            }
+            else if (temp == 0xF5)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<character party_id=\"2\" />");
+            }
+            else if (temp == 0xF6)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<image sprite=\"ButtonCircle\" />");
+            }
+            else if (temp == 0xF7)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<image sprite=\"ButtonTriangle\" />");
+            }
+            else if (temp == 0xF8)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<image sprite=\"ButtonSquare\" />");
+            }
+            else if (temp == 0xF9)
+            {
+                mLogger->Log(dialog);
+                dialog.clear();
+                mLogger->Log("<image sprite=\"ButtonCross\" />");
+            }
+            else if ((temp == 0xFA || temp == 0xFB || temp == 0xFC || temp == 0xFD) && english == false)
+            {
+                ++offset;
+                unsigned char temp2 = GetU8(offset);
+
+                if (temp == 0xFA)
+                {
+                    if (japanese_chars_fa[temp2] != 0x0000)
+                    {
+                        dialog.push_back(japanese_chars_fa[temp2] >> 8); dialog.push_back(japanese_chars_fa[temp2] & 0xFF);
+                    }
+                    else
+                    {
+                        mLogger->Log(dialog);
+                        dialog.clear();
+                        mLogger->Log("[MISSING 0xFA " + HexToString(temp2, 2, '0') + "]");
+                    }
+                }
+                else if (temp == 0xFB)
+                {
+                    if (japanese_chars_fb[temp2] != 0x0000)
+                    {
+                        dialog.push_back(japanese_chars_fb[temp2] >> 8); dialog.push_back(japanese_chars_fb[temp2] & 0xFF);
+                    }
+                    else
+                    {
+                        mLogger->Log(dialog);
+                        dialog.clear();
+                        mLogger->Log("[MISSING 0xFB " + HexToString(temp2, 2, '0') + "]");
+                    }
+                }
+                else if (temp == 0xFC)
+                {
+                    if (japanese_chars_fc[temp2] != 0x0000)
+                    {
+                        dialog.push_back(japanese_chars_fc[temp2] >> 8); dialog.push_back(japanese_chars_fc[temp2] & 0xFF);
+                    }
+                    else
+                    {
+                        mLogger->Log(dialog);
+                        dialog.clear();
+                        mLogger->Log("[MISSING 0xFC " + HexToString(temp2, 2, '0') + "]");
+                    }
+                }
+                else if (temp == 0xFD)
+                {
+                    if (japanese_chars_fd[temp2] != 0x0000)
+                    {
+                        dialog.push_back(japanese_chars_fd[temp2] >> 8); dialog.push_back(japanese_chars_fd[temp2] & 0xFF);
+                    }
+                    else
+                    {
+                        mLogger->Log(dialog);
+                        dialog.clear();
+                        mLogger->Log("[MISSING 0xFD " + HexToString(temp2, 2, '0') + "]");
+                    }
+                }
+            }
+            else if (temp == 0xFE)
+            {
+                ++offset;
+
+                unsigned char temp2 = GetU8(offset);
+
+                // TODO: I think value must be RGB?
+                if (temp2 == 0xD4)
+                {
+                    mLogger->Log(dialog);
+                    dialog.clear();
+                    mLogger->Log("<colour value=\"red\">");
+                }
+                else if (temp2 == 0xD5)
+                {
+                    mLogger->Log(dialog);
+                    dialog.clear();
+                    mLogger->Log("<colour value=\"purple\" >");
+                }
+                else if (temp2 == 0xD6)
+                {
+                    mLogger->Log(dialog);
+                    dialog.clear();
+                    mLogger->Log("<colour value=\"green\" >");
+                }
+                else if (temp2 == 0xD7)
+                {
+                    mLogger->Log(dialog);
+                    dialog.clear();
+                    mLogger->Log("<colour value=\"cyan\" >");
+                }
+                else if (temp2 == 0xD8)
+                {
+                    mLogger->Log(dialog);
+                    dialog.clear();
+                    mLogger->Log("<colour value=\"yellow\">");
+                }
+                else if (temp2 == 0xD9)
+                {
+                    mLogger->Log(dialog);
+                    dialog.clear();
+                    mLogger->Log("</colour>");
+                }
+                else if (temp2 == 0xDC)
+                {
+                    mLogger->Log(dialog);
+                    dialog.clear();
+                    mLogger->Log("<pause_ok >");
+                }
+                else if (temp2 == 0xDD)
+                {
+                    u16 wait = GetU16LE(offset + 1);
+                    ++offset;
+                    ++offset;
+                    mLogger->Log(dialog);
+                    dialog.clear();
+                    mLogger->Log("<pause time=\"" + IntToString(wait) + "\" />");
+                }
+                else
+                {
+                    if (japanese_chars_fe[temp2] != 0x0000 && english == false)
+                    {
+                        dialog.push_back(japanese_chars_fe[temp2] >> 8); dialog.push_back(japanese_chars_fe[temp2] & 0xFF);
+                    }
+                    else
+                    {
+                        mLogger->Log(dialog);
+                        dialog.clear();
+                        mLogger->Log("[MISSING 0xFE " + HexToString(temp2, 2, '0') + "]");
+                    }
+                }
+            }
+            else
+            {
+                if (japanese_chars[temp] != 0x0000 && english == false)
+                {
+                    dialog.push_back(japanese_chars[temp] >> 8);// dialog.push_back(japanese_chars[temp] & 0xFF);
+                }
+                else if (english_chars[temp] != 0x0000 && english == true)
+                {
+                    dialog.push_back(english_chars[temp] >> 8); //dialog.push_back(english_chars[temp] & 0xFF);
+                }
+                else
+                {
+                    mLogger->Log(dialog);
+                    dialog.clear();
+                    mLogger->Log("[MISSING CHAR " + HexToString(temp, 2, '0') + "]");
+                }
+            }
+        }
+
+        mLogger->Log(dialog);
+        dialog.clear();
+        mLogger->Log("</dialog>\n\n");
+    }
+
+}
+
+void FF7FieldTextWriter::End()
+{
+    if (mLogger)
+    {
+        mLogger->Log("</texts>\n");
+    }
+    mLogger.reset();
+}

+ 20 - 0
utilities/q-gears-launcher/src/ff7FieldTextWriter.h

@@ -0,0 +1,20 @@
+#pragma once
+
+#include "common/TypeDefine.h"
+#include "common/Logger.h"
+#include <vector>
+#include <memory>
+
+class FF7FieldTextWriter
+{
+public:
+    void Begin(std::string fileName);
+    void Write(const std::vector<u8>& scriptSectionBuffer, std::string fieldName, bool english = true);
+    void End();
+private:
+    u16 GetU16LE(u32 offset);
+    u8 GetU8(u32 offset);
+
+    std::unique_ptr<Logger> mLogger;
+    std::vector<u8> mData;
+};