feature: Load GSC bin files from gsc-tool from raw

This commit is contained in:
6arelyFuture 2023-12-09 14:33:56 +01:00
parent fe1d764615
commit 9306210227
Signed by: Future
GPG Key ID: FA77F074E98D98A5
3 changed files with 97 additions and 1 deletions

View File

@ -0,0 +1,76 @@
#include "AssetLoaderScriptFile.h"
#include "Game/IW5/IW5.h"
#include "Pool/GlobalAssetPool.h"
#include <cstring>
#include <filesystem>
#include <iostream>
using namespace IW5;
void* AssetLoaderScriptFile::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory)
{
auto* scriptFile = memory->Create<ScriptFile>();
memset(scriptFile, 0, sizeof(ScriptFile));
scriptFile->name = memory->Dup(assetName.c_str());
return scriptFile;
}
bool AssetLoaderScriptFile::CanLoadFromRaw() const
{
return true;
}
// See https://github.com/xensik/gsc-tool#file-format for an in-depth explanation about the .gscbin format
bool AssetLoaderScriptFile::LoadFromRaw(
const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const
{
const auto file = searchPath->Open(assetName + ".gscbin");
if (!file.IsOpen())
return false;
const auto fileBuffer = std::make_unique<char[]>(static_cast<size_t>(file.m_length));
file.m_stream->read(fileBuffer.get(), file.m_length);
if (file.m_stream->gcount() != file.m_length)
return false;
auto* scriptFile = memory->Create<ScriptFile>();
scriptFile->name = memory->Dup(assetName.c_str());
// Retrieve data from the buffer
size_t offset = 0;
// Read past the name pointer, we will use the one from assetName
offset += strlen(fileBuffer.get()) + 1;
memcpy(&scriptFile->compressedLen, fileBuffer.get() + offset, sizeof(scriptFile->compressedLen));
offset += sizeof(scriptFile->compressedLen);
memcpy(&scriptFile->len, fileBuffer.get() + offset, sizeof(scriptFile->len));
offset += sizeof(scriptFile->len);
memcpy(&scriptFile->bytecodeLen, fileBuffer.get() + offset, sizeof(scriptFile->bytecodeLen));
offset += sizeof(scriptFile->bytecodeLen);
// Get the file size
auto fileSize = file.m_length;
if (offset + scriptFile->compressedLen > fileSize || offset + scriptFile->bytecodeLen > fileSize)
{
std::cerr << "Error: Specified length in " << assetName << " GSC BIN structure exceeds the actual file size" << std::endl;
return false;
}
scriptFile->buffer = static_cast<char*>(memory->Alloc(scriptFile->compressedLen));
memcpy(const_cast<char*>(scriptFile->buffer), fileBuffer.get() + offset, scriptFile->compressedLen);
offset += scriptFile->compressedLen;
scriptFile->bytecode = static_cast<unsigned char*>(memory->Alloc(scriptFile->bytecodeLen));
memcpy(scriptFile->bytecode, fileBuffer.get() + offset, scriptFile->bytecodeLen);
offset += scriptFile->bytecodeLen;
manager->AddAsset(ASSET_TYPE_SCRIPTFILE, assetName, scriptFile);
return true;
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "AssetLoading/BasicAssetLoader.h"
#include "AssetLoading/IAssetLoadingManager.h"
#include "Game/IW5/IW5.h"
#include "SearchPath/ISearchPath.h"
namespace IW5
{
class AssetLoaderScriptFile final : public BasicAssetLoader<ASSET_TYPE_SCRIPTFILE, ScriptFile>
{
static constexpr size_t COMPRESSED_BUFFER_SIZE_PADDING = 64;
public:
_NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override;
_NODISCARD bool CanLoadFromRaw() const override;
bool
LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override;
};
} // namespace IW5

View File

@ -5,6 +5,7 @@
#include "AssetLoaders/AssetLoaderMenuDef.h" #include "AssetLoaders/AssetLoaderMenuDef.h"
#include "AssetLoaders/AssetLoaderMenuList.h" #include "AssetLoaders/AssetLoaderMenuList.h"
#include "AssetLoaders/AssetLoaderRawFile.h" #include "AssetLoaders/AssetLoaderRawFile.h"
#include "AssetLoaders/AssetLoaderScriptFile.h"
#include "AssetLoaders/AssetLoaderStringTable.h" #include "AssetLoaders/AssetLoaderStringTable.h"
#include "AssetLoading/AssetLoadingManager.h" #include "AssetLoading/AssetLoadingManager.h"
#include "Game/IW5/GameAssetPoolIW5.h" #include "Game/IW5/GameAssetPoolIW5.h"
@ -60,7 +61,7 @@ ObjLoader::ObjLoader()
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMPACT_FX, FxImpactTable)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMPACT_FX, FxImpactTable))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SURFACE_FX, SurfaceFxTable)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SURFACE_FX, SurfaceFxTable))
REGISTER_ASSET_LOADER(AssetLoaderRawFile) REGISTER_ASSET_LOADER(AssetLoaderRawFile)
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SCRIPTFILE, ScriptFile)) REGISTER_ASSET_LOADER(AssetLoaderScriptFile)
REGISTER_ASSET_LOADER(AssetLoaderStringTable) REGISTER_ASSET_LOADER(AssetLoaderStringTable)
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LEADERBOARD, LeaderboardDef)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LEADERBOARD, LeaderboardDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet)) REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet))