Skip to content

Commit

Permalink
Merge pull request Laupetin#48 from diamante0018/main
Browse files Browse the repository at this point in the history
feature: Load GSC BIN files from gsc-tool  from raw
  • Loading branch information
Laupetin authored Dec 9, 2023
2 parents f7eb518 + 0ad1964 commit 20af6c4
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 1 deletion.
78 changes: 78 additions & 0 deletions src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderScriptFile.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#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);

if (scriptFile->compressedLen <= 0 || scriptFile->bytecodeLen <= 0)
{
std::cerr << "Error: Invalid length of the buffers in " << assetName << " specified" << std::endl;
return false;
}

if (offset + (scriptFile->compressedLen + scriptFile->bytecodeLen) > file.m_length)
{
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);

manager->AddAsset(ASSET_TYPE_SCRIPTFILE, assetName, scriptFile);

return true;
}
17 changes: 17 additions & 0 deletions src/ObjLoading/Game/IW5/AssetLoaders/AssetLoaderScriptFile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#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>
{
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
3 changes: 2 additions & 1 deletion src/ObjLoading/Game/IW5/ObjLoaderIW5.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "AssetLoaders/AssetLoaderMenuDef.h"
#include "AssetLoaders/AssetLoaderMenuList.h"
#include "AssetLoaders/AssetLoaderRawFile.h"
#include "AssetLoaders/AssetLoaderScriptFile.h"
#include "AssetLoaders/AssetLoaderStringTable.h"
#include "AssetLoading/AssetLoadingManager.h"
#include "Game/IW5/GameAssetPoolIW5.h"
Expand Down Expand Up @@ -60,7 +61,7 @@ ObjLoader::ObjLoader()
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_IMPACT_FX, FxImpactTable))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SURFACE_FX, SurfaceFxTable))
REGISTER_ASSET_LOADER(AssetLoaderRawFile)
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_SCRIPTFILE, ScriptFile))
REGISTER_ASSET_LOADER(AssetLoaderScriptFile)
REGISTER_ASSET_LOADER(AssetLoaderStringTable)
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_LEADERBOARD, LeaderboardDef))
REGISTER_ASSET_LOADER(BASIC_LOADER(ASSET_TYPE_STRUCTURED_DATA_DEF, StructuredDataDefSet))
Expand Down

0 comments on commit 20af6c4

Please sign in to comment.