From 902a2bc27d2b62a21c0175ca49ce29a3b5ff8175 Mon Sep 17 00:00:00 2001 From: Diavolo Date: Sat, 9 Dec 2023 16:07:53 +0100 Subject: [PATCH] feat: dump scriptfiles to gsc bin (gsc-tool) format --- .../IW5/AssetDumpers/AssetDumperRawFile.cpp | 21 +------------ .../IW5/AssetDumpers/AssetDumperRawFile.h | 2 -- .../AssetDumpers/AssetDumperScriptFile.cpp | 30 +++++++++++++++++++ .../IW5/AssetDumpers/AssetDumperScriptFile.h | 14 +++++++++ src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp | 3 +- 5 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperScriptFile.cpp create mode 100644 src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperScriptFile.h diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.cpp index 2a5fca66..922057e8 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.cpp +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.cpp @@ -10,25 +10,6 @@ bool AssetDumperRawFile::ShouldDump(XAssetInfo* asset) return true; } -std::string AssetDumperRawFile::GetAssetFileName(XAssetInfo* asset) -{ - std::string cleanAssetName = asset->m_name; - for (auto& c : cleanAssetName) - { - switch (c) - { - case '*': - c = '_'; - break; - - default: - break; - } - } - - return cleanAssetName; -} - void AssetDumperRawFile::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) { const auto* rawFile = asset->Asset(); @@ -68,7 +49,7 @@ void AssetDumperRawFile::DumpAsset(AssetDumpingContext& context, XAssetInfoname); + std::cerr << "Inflate failed when attempting to dump rawfile " << rawFile->name << std::endl; inflateEnd(&zs); return; } diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.h index 495bc29e..57e35274 100644 --- a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.h +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperRawFile.h @@ -7,8 +7,6 @@ namespace IW5 { class AssetDumperRawFile final : public AbstractAssetDumper { - static std::string GetAssetFileName(XAssetInfo* asset); - protected: bool ShouldDump(XAssetInfo* asset) override; void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperScriptFile.cpp b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperScriptFile.cpp new file mode 100644 index 00000000..c432a700 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperScriptFile.cpp @@ -0,0 +1,30 @@ +#include "AssetDumperScriptFile.h" + +using namespace IW5; + +bool AssetDumperScriptFile::ShouldDump(XAssetInfo* asset) +{ + return true; +} + +// See https://github.com/xensik/gsc-tool#file-format for an in-depth explanation about the .gscbin format +void AssetDumperScriptFile::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) +{ + auto* scriptFile = asset->Asset(); + const auto assetFile = context.OpenAssetFile(asset->m_name + ".gscbin"); + + if (!assetFile) + return; + + auto& stream = *assetFile; + + // Dump the name and the numeric fields + stream.write(asset->m_name.c_str(), asset->m_name.size() + 1); + stream.write(reinterpret_cast(&scriptFile->compressedLen), sizeof(scriptFile->compressedLen)); + stream.write(reinterpret_cast(&scriptFile->len), sizeof(scriptFile->len)); + stream.write(reinterpret_cast(&scriptFile->bytecodeLen), sizeof(scriptFile->bytecodeLen)); + + // Dump the buffers + stream.write(scriptFile->buffer, scriptFile->compressedLen); + stream.write(reinterpret_cast(scriptFile->bytecode), scriptFile->bytecodeLen); +} diff --git a/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperScriptFile.h b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperScriptFile.h new file mode 100644 index 00000000..2397f387 --- /dev/null +++ b/src/ObjWriting/Game/IW5/AssetDumpers/AssetDumperScriptFile.h @@ -0,0 +1,14 @@ +#pragma once + +#include "Dumping/AbstractAssetDumper.h" +#include "Game/IW5/IW5.h" + +namespace IW5 +{ + class AssetDumperScriptFile final : public AbstractAssetDumper + { + protected: + bool ShouldDump(XAssetInfo* asset) override; + void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; + }; +} // namespace IW5 diff --git a/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp b/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp index c67408c9..809cdf91 100644 --- a/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp +++ b/src/ObjWriting/Game/IW5/ZoneDumperIW5.cpp @@ -7,6 +7,7 @@ #include "AssetDumpers/AssetDumperMenuDef.h" #include "AssetDumpers/AssetDumperMenuList.h" #include "AssetDumpers/AssetDumperRawFile.h" +#include "AssetDumpers/AssetDumperScriptFile.h" #include "AssetDumpers/AssetDumperStringTable.h" #include "AssetDumpers/AssetDumperXModel.h" #include "Game/IW5/GameAssetPoolIW5.h" @@ -63,7 +64,7 @@ bool ZoneDumper::DumpZone(AssetDumpingContext& context) const // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX) // DUMP_ASSET_POOL(AssetDumperSurfaceFxTable, m_surface_fx_table, ASSET_TYPE_SURFACE_FX) DUMP_ASSET_POOL(AssetDumperRawFile, m_raw_file, ASSET_TYPE_RAWFILE) - // DUMP_ASSET_POOL(AssetDumperScriptFile, m_script_file, ASSET_TYPE_SCRIPTFILE) + DUMP_ASSET_POOL(AssetDumperScriptFile, m_script_file, ASSET_TYPE_SCRIPTFILE) DUMP_ASSET_POOL(AssetDumperStringTable, m_string_table, ASSET_TYPE_STRINGTABLE) // DUMP_ASSET_POOL(AssetDumperLeaderboardDef, m_leaderboard, ASSET_TYPE_LEADERBOARD) // DUMP_ASSET_POOL(AssetDumperStructuredDataDefSet, m_structed_data_def_set, ASSET_TYPE_STRUCTURED_DATA_DEF)