From ae5f617be2ca71620bbfbe96f0ee50f3fbc6d3f1 Mon Sep 17 00:00:00 2001 From: Mordred Date: Thu, 12 Oct 2017 00:07:41 +0200 Subject: [PATCH] first potentially working dat reader generation --- src/tools/exd_struct_gen/ExdData.cpp.tmpl | 42 ++++++++ src/tools/exd_struct_gen/ExdData.h.tmpl | 48 +++++++++ src/tools/exd_struct_gen/main.cpp | 125 +++++++++++++++++++--- 3 files changed, 200 insertions(+), 15 deletions(-) create mode 100644 src/tools/exd_struct_gen/ExdData.cpp.tmpl create mode 100644 src/tools/exd_struct_gen/ExdData.h.tmpl diff --git a/src/tools/exd_struct_gen/ExdData.cpp.tmpl b/src/tools/exd_struct_gen/ExdData.cpp.tmpl new file mode 100644 index 00000000..cafd2feb --- /dev/null +++ b/src/tools/exd_struct_gen/ExdData.cpp.tmpl @@ -0,0 +1,42 @@ +#include "ExdData.h" +#include + +#include + +Core::Data::ExdData::ExdData() +{ +} + +Core::Data::ExdData::~ExdData() +{ +} + +xiv::exd::Exd Core::Data::ExdData::setupDatAccess( const std::string& name, xiv::exd::Language lang ) +{ + auto& cat = m_exd_data->get_category( name ); + return static_cast< xiv::exd::Exd >( cat.get_data_ln( lang ) ); +}; + +bool Core::Data::ExdData::init( const std::string& path ) +{ + try + { + m_data = boost::make_shared< xiv::dat::GameData >( path ); + m_exd_data = boost::make_shared< xiv::exd::ExdData >( *m_data ); + +SETUPDATACCESS + } + catch( std::runtime_error ) + { + return false; + } + + return true; +} + +/////////////////////////////////////////////////////////////// +// DIRECT GETTERS +DIRECTGETTERS + + + diff --git a/src/tools/exd_struct_gen/ExdData.h.tmpl b/src/tools/exd_struct_gen/ExdData.h.tmpl new file mode 100644 index 00000000..7cb55ff8 --- /dev/null +++ b/src/tools/exd_struct_gen/ExdData.h.tmpl @@ -0,0 +1,48 @@ +#ifndef _EXDDATA_H +#define _EXDDATA_H + +/* This file has been automatically generated. + Changes will be lost upon regeneration. + To change the content edit tools/exd_struct_gen */ + +#include +#include +#include +#include +#include + +namespace Core { +namespace Data { + +STRUCTS + + class ExdData + { + public: + ExdData(); + ~ExdData(); + + bool init( const std::string& path ); + + xiv::exd::Exd setupDatAccess( const std::string& name, xiv::exd::Language lang ); + + template< class T > + T getField( std::vector< xiv::exd::Field >& fields, uint32_t index ) + { + return *boost::get< T >( &fields.at( index ) ); + } + + boost::shared_ptr< xiv::dat::GameData > m_data; + boost::shared_ptr< xiv::exd::ExdData > m_exd_data; + +DATACCESS + +DIRECTGETTERS + + }; + +} +} + +#endif + diff --git a/src/tools/exd_struct_gen/main.cpp b/src/tools/exd_struct_gen/main.cpp index 0db41b84..02bfe6de 100644 --- a/src/tools/exd_struct_gen/main.cpp +++ b/src/tools/exd_struct_gen/main.cpp @@ -17,27 +17,78 @@ #include #include +#include +#include Core::Logger g_log; Core::Data::ExdData g_exdData; -const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" ); -//const std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv" ); +//const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" ); +const std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv" ); std::map< uint8_t, std::string > g_typeMap; -std::string generateEnum( const std::string& exd ) +std::string generateDatAccessDecl( const std::string &exd ) { + return " xiv::exd::Exd m_" + exd + "Dat;\n"; +} +std::string generateDirectGetters( const std::string& exd ) +{ + return " boost::shared_ptr< " + exd + " > get" + exd + "( uint32_t " + exd + "Id );"; +} + +std::string generateSetDatAccessCall( const std::string &exd ) +{ + auto& cat = g_exdData.m_exd_data->get_category( exd ); + auto exh = cat.get_header(); + + std::string lang = "xiv::exd::Language::none"; + auto langs = exh.get_languages(); + if( langs.size() > 1 ) + lang = "xiv::exd::Language::en"; + + return " m_" + exd + "Dat = setupDatAccess( \"" + exd + "\", " + lang + " );"; +} + +std::string generateDirectGetterDef( const std::string& exd ) +{ + std::string result = ""; + result = + "boost::shared_ptr< Core::Data::" + exd + " >\n" + " Core::Data::ExdData::get" + exd + "( uint32_t " + exd + "Id )\n" + "{\n" + " try\n" + " {\n" + " auto row = m_" + exd + "Dat.get_row( " + exd + "Id );\n" + " auto info = boost::make_shared< " + exd + " >( " + exd + "Id, this );\n" + + " return info;\n" + " }\n" + " catch( ... )\n" + " {\n" + " return nullptr;\n" + " }\n" + + " return nullptr;\n" + + "}\n"; + return result; +} + +std::string generateStruct( const std::string &exd ) +{ auto& cat = g_exdData.m_exd_data->get_category( exd ); auto exh = cat.get_header(); auto exhMem = exh.get_exh_members(); - + + std::map< uint32_t, std::string > indexToNameMap; + std::map< uint32_t, std::string > indexToTypeMap; int count = 0; - std::string result = "struct " + exd +"\n{\n"; + std::string result = " struct " + exd +"\n {\n"; for( auto member : exhMem ) { @@ -48,21 +99,37 @@ std::string generateEnum( const std::string& exd ) if( it != g_typeMap.end() ) type = it->second; else - type = "bool(" + std::to_string( static_cast< uint8_t >( member.type ) ) + ")"; + type = "bool"; + + std::string fieldName = " field" + std::to_string( count ); + + indexToNameMap[count] = fieldName; + indexToTypeMap[count] = type; - result += " " + type + " field" + std::to_string( count ) + ";\n"; + result += " " + type + " " + fieldName + ";\n"; count++; } - - result += "};\n"; + + result += "\n " + exd + "( uint32_t id, Core::Data::ExdData* exdData )\n"; + result += " {\n"; + count = 0; + std::string indent = " "; + result += indent + " auto row = exdData->m_AetheryteDat.get_row( id );\n"; + for( auto member : exhMem ) + { + result += indent + indexToNameMap[count] + " = exdData->getField< " + indexToTypeMap[count] + " >( &row.at( " + std::to_string( count) + " ) );\n"; + count++; + } + result += " }\n"; + result += " };\n"; return result; } int main() { - g_typeMap[0] = "char"; + g_typeMap[0] = "std::string"; g_typeMap[1] = "bool"; g_typeMap[2] = "int8_t"; g_typeMap[3] = "uint8_t"; @@ -73,20 +140,48 @@ int main() g_typeMap[9] = "float"; g_typeMap[11] = "uint64_t"; + std::ifstream t( "ExdData.h.tmpl" ); + std::string exdH( ( std::istreambuf_iterator( t ) ), + std::istreambuf_iterator() ); + + std::ifstream s( "ExdData.cpp.tmpl" ); + std::string exdC( ( std::istreambuf_iterator( s ) ), + std::istreambuf_iterator() ); + g_log.init(); - g_log.info( "Setting up EXD data" ); - if( !g_exdData.init( datLocation ) ) + if( !g_exdData.init( datLocation ) ) { g_log.fatal( "Error setting up EXD data " ); return 0; } - std::string result = - "/* This file has been automatically generated.\n Changes will be lost upon regeneration.\n To change the content edit tools/exd_struct_gen */\n"; + std::string structDefs; + std::string dataDecl; + std::string getterDecl; + std::string datAccCall; + std::string getterDef; + + // for all sheets in the json i guess.... + structDefs += generateStruct( "TerritoryType" ); + dataDecl += generateDatAccessDecl( "TerritoryType" ); + getterDecl += generateDirectGetters( "TerritoryType" ); + datAccCall += generateSetDatAccessCall( "TerritoryType" ); + getterDef += generateDirectGetterDef( "TerritoryType" ); + + + std::string result; + result = std::regex_replace( exdH, std::regex( "\\STRUCTS" ), structDefs ); + result = std::regex_replace( result, std::regex( "\\DATACCESS" ), dataDecl ); + result = std::regex_replace( result, std::regex( "\\DIRECTGETTERS" ), getterDecl ); - result += generateEnum( "TerritoryType" ); g_log.info( result ); + + result = std::regex_replace( exdC, std::regex( "\\SETUPDATACCESS" ), datAccCall ); + result = std::regex_replace( result, std::regex( "\\DIRECTGETTERS" ), getterDef ); + + g_log.info( result ); + return 0; }