1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-25 14:07:46 +00:00
sapphire/deps/datReader/DatCategories/bg/sgb.h

294 lines
6.1 KiB
C
Raw Normal View History

2018-02-26 23:50:50 +01:00
#ifndef _SGB_H
#define _SGB_H
#include <cstring>
#include <memory>
#include <cstdint>
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include "vec3.h"
//
// ported from https://github.com/ufx/SaintCoinach/blob/master/SaintCoinach/Graphics/Sgb/SgbDataType.cs
struct SGB_FILE;
struct SGB_HEADER;
struct SGB_MODEL_ENTRY;
struct SGB_MODEL_HEADER;
struct SGB_GROUP;
struct SGB_GROUP_HEADER;
enum SgbDataType : uint32_t
2018-02-26 23:50:50 +01:00
{
Unknown0008 = 0x0008,
Group = 0x0100,
2018-02-26 23:50:50 +01:00
};
enum SgbGroupEntryType : uint32_t
2018-02-26 23:50:50 +01:00
{
Model = 0x01,
2019-04-11 19:06:27 +10:00
Gimmick = 0x06,
2018-02-26 23:50:50 +01:00
};
struct SGB_GROUP_HEADER
{
SgbDataType type;
int32_t nameOffset;
uint32_t unknown08;
uint32_t unknown0C;
uint32_t unknown10;
uint32_t unknown14;
uint32_t unknown18;
uint32_t unknown1C;
int32_t entryCount;
uint32_t unknown24;
uint32_t unknown28;
uint32_t unknown2C;
uint32_t unknown30;
uint32_t unknown34;
uint32_t unknown38;
uint32_t unknown3C;
uint32_t unknown40;
uint32_t unknown44;
2018-02-26 23:50:50 +01:00
};
2019-04-11 19:06:27 +10:00
struct SGB_GROUP1C_HEADER
{
SgbDataType type;
int32_t nameOffset;
uint32_t unknown08;
int32_t entryCount;
uint32_t unknown14;
int32_t modelFileOffset;
vec3 unknownFloat3;
vec3 unknownFloat3_2;
int32_t stateOffset;
int32_t modelFileOffset2;
uint32_t unknown3;
float unknown4;
int32_t nameOffset2;
vec3 unknownFloat3_3;
};
struct SGB_GROUP1C_ENTRY
{
uint32_t unk;
uint32_t unk2;
int32_t nameOffset;
uint32_t index;
uint32_t unk3;
int32_t modelFileOffset;
};
2018-02-26 23:50:50 +01:00
struct SGB_GROUP_ENTRY
{
public:
char* m_buf;
uint32_t m_offset;
SGB_GROUP_ENTRY()
{
m_buf = nullptr;
m_offset = 0;
};
SGB_GROUP_ENTRY( char* buf, uint32_t offset )
{
m_buf = buf;
m_offset = offset;
};
virtual ~SGB_GROUP_ENTRY()
{
};
2018-02-26 23:50:50 +01:00
};
struct SGB_ENTRY_HEADER
{
SgbGroupEntryType type;
uint32_t unknown2;
int32_t nameOffset;
vec3 translation;
vec3 rotation;
vec3 scale;
2018-02-26 23:50:50 +01:00
};
struct SGB_MODEL_HEADER : public SGB_ENTRY_HEADER
2018-02-26 23:50:50 +01:00
{
int32_t modelFileOffset;
int32_t collisionFileOffset;
2018-02-26 23:50:50 +01:00
};
struct SGB_MODEL_ENTRY : public SGB_GROUP_ENTRY
2018-02-26 23:50:50 +01:00
{
SGB_MODEL_HEADER header;
SgbGroupEntryType type;
std::string name;
std::string modelFileName;
std::string collisionFileName;
SGB_MODEL_ENTRY( char* buf, size_t offset, SgbGroupEntryType type )
{
2019-04-11 19:06:27 +10:00
this->type = type;
header = *reinterpret_cast< SGB_MODEL_HEADER* >( buf + offset );
name = std::string( buf + offset + header.nameOffset );
modelFileName = std::string( buf + offset + header.modelFileOffset );
collisionFileName = std::string( buf + offset + header.collisionFileOffset );
}
2018-02-26 23:50:50 +01:00
};
struct SGB_GROUP
{
SGB_GROUP_HEADER header;
std::string name;
SGB_FILE* parent;
std::vector< std::shared_ptr< SGB_GROUP_ENTRY > > entries;
SGB_GROUP( char* buf, SGB_FILE* file, uint32_t fileSize, uint32_t offset )
{
parent = file;
header = *reinterpret_cast< SGB_GROUP_HEADER* >( buf + offset );
name = std::string( buf + offset + header.nameOffset );
auto entriesOffset = offset + sizeof( header );
for( auto i = 0; i < header.entryCount; ++i )
{
auto entryOffset = entriesOffset + *reinterpret_cast< uint32_t* >( buf + ( entriesOffset + ( i * 4 ) ) );
if( entryOffset > fileSize )
throw std::runtime_error( "SGB_GROUP entry offset was larger than SGB file size!" );
auto type = *reinterpret_cast< uint32_t* >( buf + entryOffset );
2019-04-11 19:06:27 +10:00
if( type == SgbGroupEntryType::Model || type == SgbGroupEntryType::Gimmick )
2018-02-26 23:50:50 +01:00
{
2019-04-11 19:06:27 +10:00
entries.push_back( std::make_shared< SGB_MODEL_ENTRY >( buf, entryOffset, ( SgbGroupEntryType )type ) );
2018-02-26 23:50:50 +01:00
}
else
{
// std::cout << "\t\tUnknown SGB entry! Group: " << name << " type: " << type << " index: " << i << " entryOffset: " << entryOffset << "\n";
}
}
}
2018-02-26 23:50:50 +01:00
};
struct SGB_HEADER
{
char magic[4]; // SGB1
uint32_t fileSize;
uint32_t unknown1;
char magic2[4]; // SCN1
uint32_t unknown10;
int32_t sharedOffset;
uint32_t unknown18;
int32_t offset1C;
uint32_t unknown20;
uint32_t statesOffset;
uint32_t unknown28;
uint32_t unknown2C;
uint32_t unknown30;
uint32_t unknown34;
uint32_t unknown38;
uint32_t unknown3C;
uint32_t unknown40;
uint32_t unknown44;
uint32_t unknown48;
uint32_t unknown4C;
uint32_t unknown50;
uint32_t unknown54;
2018-02-26 23:50:50 +01:00
};
2022-02-16 22:18:55 +01:00
enum eCollisionState
{
NoChange = 0x0,
On = 0x1,
Off = 0x2,
};
struct SGB_STATE_HEADER
{
uint32_t id;
uint32_t nameOffset;
2022-02-16 22:18:55 +01:00
int Binders;
int BinderCount;
int BinaryAssetPath;
int Binary;
int BinaryCount;
uint32_t TimelineID;
int8_t AutoPlay;
int8_t LoopPlayback;
uint8_t Padding00[2];
eCollisionState CollisionState;
uint32_t Reserved[1];
};
struct SGB_STATE_ENTRY
{
SGB_STATE_HEADER header;
std::string name;
SGB_STATE_ENTRY( char* buf )
{
header = *reinterpret_cast< SGB_STATE_HEADER* >( buf );
name = std::string( buf + header.nameOffset );
}
};
2018-02-26 23:50:50 +01:00
struct SGB_FILE
{
SGB_HEADER header;
std::vector< SGB_GROUP > entries;
std::vector< SGB_STATE_ENTRY > stateEntries;
SGB_FILE()
{
memset( &header, 0, sizeof( header ) );
}
SGB_FILE( char* buf )
{
constexpr int baseOffset = 0x14;
header = *reinterpret_cast< SGB_HEADER* >( buf );
if( strncmp( &header.magic[ 0 ], "SGB1", 4 ) != 0 || strncmp( &header.magic2[ 0 ], "SCN1", 4 ) != 0 )
throw std::runtime_error( "Unable to load SGB File!" );
try
{
auto group = SGB_GROUP( buf, this, header.fileSize, baseOffset + header.sharedOffset );
entries.push_back( group );
auto group2 = SGB_GROUP( buf, this, header.fileSize, baseOffset + header.offset1C );
entries.push_back( group2 );
uint32_t stateCount = *reinterpret_cast< uint32_t* >( buf + baseOffset + header.statesOffset + 4 );
if( stateCount > 0 )
2018-02-26 23:50:50 +01:00
{
stateCount = stateCount;
for( size_t i = 0; i < stateCount; ++i )
{
auto state = SGB_STATE_ENTRY( buf + baseOffset + header.statesOffset + 8 + i * sizeof( SGB_STATE_HEADER ) );
stateEntries.push_back( state );
std::cout << state.name << "\n";
}
2018-02-26 23:50:50 +01:00
}
}
catch( std::exception& e )
{
std::cout << e.what() << "\n";
}
};
2018-02-26 23:50:50 +01:00
};
2019-04-11 19:06:27 +10:00
#endif // !_SGB_H