write some CKStateChunk code

This commit is contained in:
yyc12345 2023-02-26 13:57:32 +08:00
parent bf7c669ce6
commit e450fa532d
12 changed files with 369 additions and 165 deletions

View File

@ -6,6 +6,8 @@ lost 24 byte, 6 fields or 2 lists
Important CK Class size Important CK Class size
CKObject no change. 0x14(20) CKObject no change. 0x14(20)
CKSceneObject no change 0x1C(28), share Load/Save with CKObject CKSceneObject no change 0x1C(28), share Load/Save with CKObject
CKBehavior no change 0x6C(108)
CKBeObject 0x50(80) count 20 CKBeObject 0x50(80) count 20
CKGroup 0x68(104) count 26 CKGroup 0x68(104) count 26
@ -39,6 +41,14 @@ CKFileManagerData no change (12)
CKStateChunk is 0x28u black box CKStateChunk is 0x28u black box
CKBufferParser also is 0x10u black box CKBufferParser also is 0x10u black box
typedef char* CKSTRING;
typedef char CKCHAR;
typedef int CKBOOL;
typedef unsigned char CKBYTE;
typedef unsigned int CKDWORD;
typedef unsigned short CKWORD;
typedef int CKERROR;
struct CKGUID { struct CKGUID {
DWORD d1,d2; DWORD d1,d2;
}; };
@ -98,6 +108,38 @@ struct XFileObjectsTable {
}; };
struct CKObject {
DWORD* vtable;
CK_ID m_ID;
CKSTRING m_Name;
CKDWORD m_ObjectFlags;
CKContext *m_Context;
};
struct CKSceneObject : CKObject {
XBitArray m_Scenes;
};
struct BehaviorBlockData{};
struct BehaviorGraphData{};
struct CKBehavior : CKSceneObject {
CK_ID m_Owner;
CK_ID m_BehParent;
XSObjectPointerArray m_InputArray;
XSObjectPointerArray m_OutputArray;
XSObjectPointerArray m_InParameter;
XSObjectPointerArray m_OutParameter;
XSObjectPointerArray m_LocalParameter;
CK_CLASSID m_CompatibleClassID;
int m_Priority;
CKDWORD m_Flags;
CKStateChunk * m_InterfaceChunk;
BehaviorGraphData* m_GraphData;
BehaviorBlockData* m_BlockData;
float m_LastExecutionTime;
CK_ID m_InputTargetParam;
};
struct CKFileInfo struct CKFileInfo
{ {
DWORD ProductVersion; // Virtools Version (Dev/Creation). (CK_VIRTOOLS_VERSION) DWORD ProductVersion; // Virtools Version (Dev/Creation). (CK_VIRTOOLS_VERSION)
@ -180,6 +222,28 @@ struct CKStateChunk {
CKFile* m_BindFile; CKFile* m_BindFile;
DWORD m_unknow; DWORD m_unknow;
}; };
struct CKStateChunkRemap { // 0x40 count 16
DWORD m_ChunkVersion;
DWORD* m_pData;
DWORD m_DataDwordSize;
DWORD unknow_3;
DWORD* m_ObjList_pData;
DWORD m_ObjList_Count;
DWORD* m_ChkList_pData;
DWORD m_ChkList_Count;
DWORD unknow_8;
DWORD unknow_9;
DWORD unknow_10;
DWORD unknow_11;
DWORD unknow_12;
DWORD unknow_13;
CKDependenciesContext* m_DepCtx;
CKContext* m_Ctx;
};
struct CKBufferParser { struct CKBufferParser {
char* m_MemBegin; char* m_MemBegin;

View File

@ -23,7 +23,6 @@ namespace LibCmo {
using XClassArray = std::vector<T>; using XClassArray = std::vector<T>;
//using CKObjectArray = std::vector<CKObject*>; //using CKObjectArray = std::vector<CKObject*>;
struct CKGUID { struct CKGUID {
union { union {
struct { struct {

View File

@ -347,6 +347,11 @@ namespace LibCmo {
return CKERROR::CKERR_OK; return CKERROR::CKERR_OK;
} }
CKERROR CKFile::DeepLoad(CKSTRING u8_filename, CKFileData::DeepDocument** out_doc) {
return CKERROR::CKERR_OK;
}
//CKERROR CKFile::Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags) { //CKERROR CKFile::Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags) {
// CKERROR result = this->OpenFile(u8_filename, flags); // CKERROR result = this->OpenFile(u8_filename, flags);
// if (result == CKERROR::CKERR_OK || result == CKERROR::CKERR_PLUGINSMISSING) { // if (result == CKERROR::CKERR_OK || result == CKERROR::CKERR_PLUGINSMISSING) {

View File

@ -3,13 +3,11 @@
#include "CKDefines.hpp" #include "CKDefines.hpp"
#include "CKEnums.hpp" #include "CKEnums.hpp"
#include "VTEncoding.hpp" #include "VTEncoding.hpp"
#include "VTObjects.hpp"
#include <filesystem> #include <filesystem>
namespace LibCmo { namespace LibCmo {
// forward decl to rm recursive reference
namespace ObjsImpl { class CKObject; }
class CKMinContext { class CKMinContext {
public: public:
CKMinContext(); CKMinContext();
@ -19,7 +17,7 @@ namespace LibCmo {
void Printf(CKSTRING fmt, ...); void Printf(CKSTRING fmt, ...);
ObjsImpl::CKObject* CreateObject(CK_ID id, CKSTRING name); ObjsImpl::CKObject* CreateObject(CK_ID id, CK_CLASSID cls, CKSTRING name);
void DestroyObject(ObjsImpl::CKObject* obj); void DestroyObject(ObjsImpl::CKObject* obj);
void GetUtf8ObjectName(std::string& native_name, std::string& u8_name); void GetUtf8ObjectName(std::string& native_name, std::string& u8_name);

View File

@ -9,27 +9,96 @@
namespace LibCmo { namespace LibCmo {
#pragma region Ctor Dtor
CKStateChunk::CKStateChunk() : CKStateChunk::CKStateChunk() :
m_ClassId(CK_CLASSID::CKCID_OBJECT), m_DataDwSize(0u), m_pData(nullptr), m_ClassId(CK_CLASSID::CKCID_OBJECT), m_DataDwSize(0u), m_pData(nullptr),
m_DataVersion(CK_STATECHUNK_DATAVERSION::CHUNKDATA_CURRENTVERSION), m_ChunkVersion(CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4), m_DataVersion(CK_STATECHUNK_DATAVERSION::CHUNKDATA_CURRENTVERSION), m_ChunkVersion(CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4),
m_Parser{ 0u, 0u, 0u }, m_Parser{ CKStateChunkStatus::IDLE, 0u, 0u, 0u },
m_ObjectList(), m_ChunkList(), m_ManagerList() m_ObjectList(), m_ChunkList(), m_ManagerList()
{ {
; ;
} }
LibCmo::CKStateChunk::CKStateChunk(CK_CLASSID clsid) : CKStateChunk::CKStateChunk(const CKStateChunk& rhs) :
m_ClassId(clsid), m_DataDwSize(0u), m_pData(nullptr), m_ClassId(rhs.m_ClassId), m_DataVersion(rhs.m_DataVersion), m_ChunkVersion(rhs.m_ChunkVersion),
m_DataVersion(CK_STATECHUNK_DATAVERSION::CHUNKDATA_CURRENTVERSION), m_ChunkVersion(CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4), m_Parser(rhs.m_Parser),
m_Parser{ 0u, 0u, 0u }, m_ObjectList(rhs.m_ObjectList), m_ManagerList(rhs.m_ManagerList), m_ChunkList(rhs.m_ChunkList),
m_ObjectList(), m_ChunkList(), m_ManagerList() m_pData(nullptr), m_DataDwSize(rhs.m_DataDwSize)
{ {
; // copy buffer
if (rhs.m_pData != nullptr) {
this->m_pData = new(std::nothrow) CKDWORD[rhs.m_DataDwSize];
if (this->m_pData != nullptr) {
memcpy(this->m_pData, rhs.m_pData, sizeof(CKDWORD) * rhs.m_DataDwSize);
}
}
}
CKStateChunk& CKStateChunk::operator=(const CKStateChunk& rhs) {
this->Clear();
this->m_DataVersion = rhs.m_DataVersion;
this->m_ChunkVersion = rhs.m_ChunkVersion;
this->m_ClassId = rhs.m_ClassId;
this->m_Parser = rhs.m_Parser;
this->m_ObjectList = rhs.m_ObjectList;
this->m_ManagerList = rhs.m_ManagerList;
this->m_ChunkList = rhs.m_ChunkList;
// copy buffer
if (rhs.m_pData != nullptr) {
this->m_pData = new(std::nothrow) CKDWORD[rhs.m_DataDwSize];
if (this->m_pData != nullptr) {
memcpy(this->m_pData, rhs.m_pData, sizeof(CKDWORD) * rhs.m_DataDwSize);
}
}
this->m_DataDwSize = rhs.m_DataDwSize;
return *this;
} }
CKStateChunk::~CKStateChunk() { CKStateChunk::~CKStateChunk() {
if (this->m_pData != nullptr) if (this->m_pData != nullptr)
delete[] this->m_pData; delete[] this->m_pData;
} }
#pragma endregion
#pragma region Misc Funcs
void CKStateChunk::Clear(void) {
this->m_ClassId = CK_CLASSID::CKCID_OBJECT;
//this->m_DataVersion = CK_STATECHUNK_DATAVERSION::CHUNK_DEV_2_1;
//this->m_ChunkVersion = CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4;
this->m_Parser.m_CurrentPos = 0;
this->m_Parser.m_DataSize = 0;
this->m_Parser.m_PrevIdentifierPos = 0;
this->m_DataDwSize = 0;
if (this->m_pData != nullptr) {
delete[] this->m_pData;
this->m_pData = nullptr;
}
this->m_ObjectList.clear();
this->m_ManagerList.clear();
this->m_ChunkList.clear();
}
CKDWORD CKStateChunk::GetDataSize(void) {
return sizeof(CKDWORD) * this->m_DataDwSize;
}
void LibCmo::CKStateChunk::_EnsureWriteSpace(CKDWORD size) {
;
}
#pragma endregion
#pragma region Buffer Related
bool CKStateChunk::ConvertFromBuffer(const void* buf) { bool CKStateChunk::ConvertFromBuffer(const void* buf) {
if (buf == nullptr) return false; if (buf == nullptr) return false;
@ -163,6 +232,9 @@ namespace LibCmo {
return 0u; return 0u;
} }
#pragma endregion
//bool CKStateChunk::UnPack(CKDWORD DestSize) { //bool CKStateChunk::UnPack(CKDWORD DestSize) {
// // NOTE: in UnPack. pData store the compressed buffer, and // // NOTE: in UnPack. pData store the compressed buffer, and
// // dwSize store the length of compressed buffer as CHAR size, not DWORD size! // // dwSize store the length of compressed buffer as CHAR size, not DWORD size!
@ -192,20 +264,21 @@ namespace LibCmo {
// return true; // return true;
//} //}
CKDWORD CKStateChunk::GetDataSize(void) {
return sizeof(CKDWORD) * this->m_DataDwSize;
}
bool CKStateChunk::SeekIdentifier(CKDWORD identifier) { bool CKStateChunk::SeekIdentifier(CKDWORD identifier) {
return false; return false;
} }
void CKStateChunk::StartRead(void) {
if (this->m_Parser.m_Status != CKStateChunkStatus::IDLE) return;
this->m_Parser.m_CurrentPos = 0u;
this->m_Parser.m_DataSize = this->m_DataDwSize;
this->m_Parser.m_PrevIdentifierPos = 0u;
this->m_Parser.m_Status = CKStateChunkStatus::READ;
}
void CKStateChunk::ReadString(std::string& strl) { void CKStateChunk::ReadString(std::string& strl) {
; ;
} }
void LibCmo::CKStateChunk::_EnsureEnoughSpace(CKDWORD size) {
;
}
} }

View File

@ -8,23 +8,30 @@ namespace LibCmo {
class CKStateChunk { class CKStateChunk {
public: public:
CKStateChunk(); CKStateChunk();
CKStateChunk(CK_CLASSID clsid); CKStateChunk(const CKStateChunk&);
CKStateChunk(const CKStateChunk&) = delete; CKStateChunk& operator=(const CKStateChunk&);
CKStateChunk& operator=(const CKStateChunk&) = delete;
~CKStateChunk(); ~CKStateChunk();
bool ConvertFromOldBuffer(const void* buf, CKDWORD buf_size, CKDWORD blk_size, CK_FILE_WRITEMODE mode); void Clear(void);
bool ConvertFromBuffer(const void* buf); bool ConvertFromBuffer(const void* buf);
CKDWORD ConvertToBuffer(void* buf); CKDWORD ConvertToBuffer(void* buf);
bool UnPack(CKDWORD DestSize); //bool UnPack(CKDWORD DestSize);
CKDWORD GetDataSize(void); CKDWORD GetDataSize(void);
bool SeekIdentifier(CKDWORD identifier); bool SeekIdentifier(CKDWORD identifier);
void StartRead(void);
void ReadString(std::string& strl); void ReadString(std::string& strl);
private: private:
enum class CKStateChunkStatus : int32_t {
IDLE,
READ,
WRITE
};
CK_CLASSID m_ClassId; CK_CLASSID m_ClassId;
CKDWORD m_DataDwSize; CKDWORD m_DataDwSize;
CKDWORD* m_pData; CKDWORD* m_pData;
@ -33,6 +40,7 @@ namespace LibCmo {
CK_STATECHUNK_CHUNKVERSION m_ChunkVersion; CK_STATECHUNK_CHUNKVERSION m_ChunkVersion;
struct { struct {
CKStateChunkStatus m_Status;
CKDWORD m_CurrentPos; CKDWORD m_CurrentPos;
CKDWORD m_DataSize; CKDWORD m_DataSize;
CKDWORD m_PrevIdentifierPos; CKDWORD m_PrevIdentifierPos;
@ -43,8 +51,10 @@ namespace LibCmo {
std::vector<CKDWORD> m_ManagerList; std::vector<CKDWORD> m_ManagerList;
private: private:
void _EnsureEnoughSpace(CKDWORD size); void _EnsureWriteSpace(CKDWORD size);
inline bool _EnsureReadSpace(CKDWORD required) {
return (this->m_Parser.m_CurrentPos <= this->m_Parser.m_DataSize) && (required <= (this->m_Parser.m_DataSize - this->m_Parser.m_CurrentPos));
}
}; };
} }

View File

@ -190,6 +190,7 @@
<ClInclude Include="CKMinContext.hpp" /> <ClInclude Include="CKMinContext.hpp" />
<ClInclude Include="CKStateChunk.hpp" /> <ClInclude Include="CKStateChunk.hpp" />
<ClInclude Include="VTEncoding.hpp" /> <ClInclude Include="VTEncoding.hpp" />
<ClInclude Include="VTManagers.hpp" />
<ClInclude Include="VTObjects.hpp" /> <ClInclude Include="VTObjects.hpp" />
<ClInclude Include="VTUtils.hpp" /> <ClInclude Include="VTUtils.hpp" />
<ClInclude Include="VxMemoryMappedFile.hpp" /> <ClInclude Include="VxMemoryMappedFile.hpp" />

View File

@ -80,5 +80,8 @@
<ClInclude Include="CKMinContext.hpp"> <ClInclude Include="CKMinContext.hpp">
<Filter>Headers</Filter> <Filter>Headers</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="VTManagers.hpp">
<Filter>Headers</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

26
LibCmo/VTManagers.hpp Normal file
View File

@ -0,0 +1,26 @@
#pragma once
#include "CKDefines.hpp"
#include "CKEnums.hpp"
namespace LibCmo {
// forward decl to rm recursive reference
class CKMinContext;
class CKStateChunk;
namespace MgrsImpl {
class CKBaseManager {
public:
CKBaseManager();
CKBaseManager(const CKBaseManager&) = delete;
CKBaseManager& operator=(const CKBaseManager&) = delete;
virtual ~CKBaseManager();
private:
};
}
}

View File

@ -2,9 +2,13 @@
#include "CKDefines.hpp" #include "CKDefines.hpp"
#include "CKEnums.hpp" #include "CKEnums.hpp"
#include "CKStateChunk.hpp"
namespace LibCmo { namespace LibCmo {
// forward decl to rm recursive reference
class CKMinContext;
class CKStateChunk;
namespace ObjsImpl { namespace ObjsImpl {
class CKObject { class CKObject {

View File

@ -15,7 +15,7 @@ int main(int argc, char* argv[]) {
LibCmo::CKFile vtfile(&vtctx); LibCmo::CKFile vtfile(&vtctx);
LibCmo::CKFileData::ShallowDocument* doc; LibCmo::CKFileData::ShallowDocument* doc;
LibCmo::CKERROR err = vtfile.ShallowLoad("combining behaviors.cmo", &doc); LibCmo::CKERROR err = vtfile.ShallowLoad("Language.old.nmo", &doc);
if (doc) if (doc)
Unvirt::StructFormatter::PrintCKFileInfo(doc->m_FileInfo); Unvirt::StructFormatter::PrintCKFileInfo(doc->m_FileInfo);

View File

@ -10,10 +10,10 @@
#define BUFFER_SIZE 1024 #define BUFFER_SIZE 1024
void Assert(bool cond, const char* desc) { void Assert(bool cond, const char* desc) {
if (!cond) { if (!cond) {
std::cout << desc << std::endl; std::cout << desc << std::endl;
ExitProcess(0); ExitProcess(0);
} }
} }
struct MyModuleInfo { struct MyModuleInfo {
@ -59,6 +59,31 @@ std::map<intptr_t, MyModuleInfo> ConstructModuleList() {
return result; return result;
} }
void PrintVTable(std::map<intptr_t, MyModuleInfo>& modules, CKDWORD* pCls, size_t vtable_len, char indent) {
if (pCls == nullptr) {
fputc('\n', stdout);
return;
}
CKDWORD* vtable = *(reinterpret_cast<CKDWORD**>(pCls));
for (size_t i = 0; i < vtable_len; ++i) {
intptr_t addr = vtable[i];
const auto& it = modules.lower_bound(addr);
if (it != modules.end() && it != modules.begin()) {
const auto& itt = std::prev(it);
fprintf(stdout, "%s::", itt->second.ModuleName.c_str());
addr = addr - itt->second.BaseOfDll;
if (itt->second.ModuleName == "CK2_3D.dll")
addr += 0x10000000u;
else if (itt->second.ModuleName == "CK2.dll")
addr += 0x24000000u;
}
fprintf(stdout, "%08X%c", addr, indent);
}
fputc('\n', stdout);
}
int main() { int main() {
Assert(LoadLibrary("CK2.dll"), "Error loading CK2.dll"); Assert(LoadLibrary("CK2.dll"), "Error loading CK2.dll");
@ -88,141 +113,137 @@ int main() {
std::cout << "Press any key to run..." << std::endl; std::cout << "Press any key to run..." << std::endl;
system("pause"); system("pause");
static std::vector<CK_CLASSID> cls{ // print CKObject vtable
CKCID_OBJECT, //static std::vector<CK_CLASSID> cls{
CKCID_PARAMETERIN, // CKCID_OBJECT,
CKCID_PARAMETEROPERATION, // CKCID_PARAMETERIN,
CKCID_STATE, // CKCID_PARAMETEROPERATION,
CKCID_BEHAVIORLINK, // CKCID_STATE,
CKCID_BEHAVIOR, // CKCID_BEHAVIORLINK,
CKCID_BEHAVIORIO, // CKCID_BEHAVIOR,
CKCID_RENDERCONTEXT, // CKCID_BEHAVIORIO,
CKCID_KINEMATICCHAIN, // CKCID_RENDERCONTEXT,
CKCID_SCENEOBJECT, // CKCID_KINEMATICCHAIN,
CKCID_OBJECTANIMATION, // CKCID_SCENEOBJECT,
CKCID_ANIMATION, // CKCID_OBJECTANIMATION,
CKCID_KEYEDANIMATION, // CKCID_ANIMATION,
CKCID_BEOBJECT, // CKCID_KEYEDANIMATION,
CKCID_DATAARRAY, // CKCID_BEOBJECT,
CKCID_SCENE, // CKCID_DATAARRAY,
CKCID_LEVEL, // CKCID_SCENE,
CKCID_PLACE, // CKCID_LEVEL,
CKCID_GROUP, // CKCID_PLACE,
CKCID_SOUND, // CKCID_GROUP,
CKCID_WAVESOUND, // CKCID_SOUND,
CKCID_MIDISOUND, // CKCID_WAVESOUND,
CKCID_MATERIAL, // CKCID_MIDISOUND,
CKCID_TEXTURE, // CKCID_MATERIAL,
CKCID_MESH, // CKCID_TEXTURE,
CKCID_PATCHMESH, // CKCID_MESH,
CKCID_RENDEROBJECT, // CKCID_PATCHMESH,
CKCID_2DENTITY, // CKCID_RENDEROBJECT,
CKCID_SPRITE, // CKCID_2DENTITY,
CKCID_SPRITETEXT, // CKCID_SPRITE,
CKCID_3DENTITY, // CKCID_SPRITETEXT,
CKCID_GRID, // CKCID_3DENTITY,
CKCID_CURVEPOINT, // CKCID_GRID,
CKCID_SPRITE3D, // CKCID_CURVEPOINT,
CKCID_CURVE, // CKCID_SPRITE3D,
CKCID_CAMERA, // CKCID_CURVE,
CKCID_TARGETCAMERA, // CKCID_CAMERA,
CKCID_LIGHT, // CKCID_TARGETCAMERA,
CKCID_TARGETLIGHT, // CKCID_LIGHT,
CKCID_CHARACTER, // CKCID_TARGETLIGHT,
CKCID_3DOBJECT, // CKCID_CHARACTER,
CKCID_BODYPART, // CKCID_3DOBJECT,
CKCID_PARAMETER, // CKCID_BODYPART,
CKCID_PARAMETERLOCAL, // CKCID_PARAMETER,
CKCID_PARAMETERVARIABLE, // CKCID_PARAMETERLOCAL,
CKCID_PARAMETEROUT, // CKCID_PARAMETERVARIABLE,
CKCID_INTERFACEOBJECTMANAGER, // CKCID_PARAMETEROUT,
CKCID_CRITICALSECTION, // CKCID_INTERFACEOBJECTMANAGER,
CKCID_LAYER, // CKCID_CRITICALSECTION,
CKCID_PROGRESSIVEMESH, // CKCID_LAYER,
CKCID_SYNCHRO // CKCID_PROGRESSIVEMESH,
}; // CKCID_SYNCHRO
static std::vector<const char*> clsname{ //};
"CKCID_OBJECT", //static std::vector<const char*> clsname{
"CKCID_PARAMETERIN", // "CKCID_OBJECT",
"CKCID_PARAMETEROPERATION", // "CKCID_PARAMETERIN",
"CKCID_STATE", // "CKCID_PARAMETEROPERATION",
"CKCID_BEHAVIORLINK", // "CKCID_STATE",
"CKCID_BEHAVIOR", // "CKCID_BEHAVIORLINK",
"CKCID_BEHAVIORIO", // "CKCID_BEHAVIOR",
"CKCID_RENDERCONTEXT", // "CKCID_BEHAVIORIO",
"CKCID_KINEMATICCHAIN", // "CKCID_RENDERCONTEXT",
"CKCID_SCENEOBJECT", // "CKCID_KINEMATICCHAIN",
"CKCID_OBJECTANIMATION", // "CKCID_SCENEOBJECT",
"CKCID_ANIMATION", // "CKCID_OBJECTANIMATION",
"CKCID_KEYEDANIMATION", // "CKCID_ANIMATION",
"CKCID_BEOBJECT", // "CKCID_KEYEDANIMATION",
"CKCID_DATAARRAY", // "CKCID_BEOBJECT",
"CKCID_SCENE", // "CKCID_DATAARRAY",
"CKCID_LEVEL", // "CKCID_SCENE",
"CKCID_PLACE", // "CKCID_LEVEL",
"CKCID_GROUP", // "CKCID_PLACE",
"CKCID_SOUND", // "CKCID_GROUP",
"CKCID_WAVESOUND", // "CKCID_SOUND",
"CKCID_MIDISOUND", // "CKCID_WAVESOUND",
"CKCID_MATERIAL", // "CKCID_MIDISOUND",
"CKCID_TEXTURE", // "CKCID_MATERIAL",
"CKCID_MESH", // "CKCID_TEXTURE",
"CKCID_PATCHMESH", // "CKCID_MESH",
"CKCID_RENDEROBJECT", // "CKCID_PATCHMESH",
"CKCID_2DENTITY", // "CKCID_RENDEROBJECT",
"CKCID_SPRITE", // "CKCID_2DENTITY",
"CKCID_SPRITETEXT", // "CKCID_SPRITE",
"CKCID_3DENTITY", // "CKCID_SPRITETEXT",
"CKCID_GRID", // "CKCID_3DENTITY",
"CKCID_CURVEPOINT", // "CKCID_GRID",
"CKCID_SPRITE3D", // "CKCID_CURVEPOINT",
"CKCID_CURVE", // "CKCID_SPRITE3D",
"CKCID_CAMERA", // "CKCID_CURVE",
"CKCID_TARGETCAMERA", // "CKCID_CAMERA",
"CKCID_LIGHT", // "CKCID_TARGETCAMERA",
"CKCID_TARGETLIGHT", // "CKCID_LIGHT",
"CKCID_CHARACTER", // "CKCID_TARGETLIGHT",
"CKCID_3DOBJECT", // "CKCID_CHARACTER",
"CKCID_BODYPART", // "CKCID_3DOBJECT",
"CKCID_PARAMETER", // "CKCID_BODYPART",
"CKCID_PARAMETERLOCAL", // "CKCID_PARAMETER",
"CKCID_PARAMETERVARIABLE", // "CKCID_PARAMETERLOCAL",
"CKCID_PARAMETEROUT", // "CKCID_PARAMETERVARIABLE",
"CKCID_INTERFACEOBJECTMANAGER", // "CKCID_PARAMETEROUT",
"CKCID_CRITICALSECTION", // "CKCID_INTERFACEOBJECTMANAGER",
"CKCID_LAYER", // "CKCID_CRITICALSECTION",
"CKCID_PROGRESSIVEMESH", // "CKCID_LAYER",
"CKCID_SYNCHRO" // "CKCID_PROGRESSIVEMESH",
}; // "CKCID_SYNCHRO"
//};
//
//auto moduleInfos = ConstructModuleList();
//fputs("Class Name,Class Id,Show(),IsHiddenByParent(),CanBeHide(),IsVisible(),~dtor(),GetClassID(),PreSave(),Save(),Load(),PostLoad(),PreDelete(),CheckPreDeletion(),CheckPostDeletion(),GetMemoryOccupation(),IsObjectUsed(),PrepareDependencies(),RemapDependencies(),Copy(),\n", stdout);
//for (size_t j = 0; j < cls.size(); ++j) {
// CK_CLASSID item = cls[j];
// const char* itemname = clsname[j];
// CKObject* obj = ctx->CreateObject(item, NULL, CK_OBJECTCREATION_NONAMECHECK, NULL);
// fprintf(stdout, "%s,%d,", itemname, item);
// PrintVTable(moduleInfos, reinterpret_cast<CKDWORD*>(obj), 18);
//}
// print manager vtables
auto moduleInfos = ConstructModuleList(); auto moduleInfos = ConstructModuleList();
int count = ctx->GetManagerCount();
for (int i = 0; i < count; ++i) {
CKBaseManager* mgr = ctx->GetManager(i);
fputs("Class Name,Class Id,Show(),IsHiddenByParent(),CanBeHide(),IsVisible(),~dtor(),GetClassID(),PreSave(),Save(),Load(),PostLoad(),PreDelete(),CheckPreDeletion(),CheckPostDeletion(),GetMemoryOccupation(),IsObjectUsed(),PrepareDependencies(),RemapDependencies(),Copy(),\n", stdout); CKSTRING name = mgr->GetName();
for (size_t j = 0; j < cls.size(); ++j) { CKGUID guid = mgr->GetGuid();
CK_CLASSID item = cls[j]; fprintf(stdout, "%s\t0x%08x, 0x%08x\t", name, guid.d1, guid.d2);
const char* itemname = clsname[j]; PrintVTable(moduleInfos, reinterpret_cast<CKDWORD*>(mgr), 30, '\t');
CKObject* obj = ctx->CreateObject(item, NULL, CK_OBJECTCREATION_NONAMECHECK, NULL);
if (obj == nullptr) continue;
CKDWORD* vtable = *(reinterpret_cast<CKDWORD**>(obj));
fprintf(stdout, "%s,%d,", itemname, item);
for (size_t i = 0; i < 18; ++i) {
intptr_t addr = vtable[i];
const auto& it = moduleInfos.lower_bound(addr);
if (it != moduleInfos.end() && it != moduleInfos.begin()) {
const auto& itt = std::prev(it);
fprintf(stdout, "%s::", itt->second.ModuleName.c_str());
addr = addr - itt->second.BaseOfDll;
if (itt->second.ModuleName == "CK2_3D.dll")
addr += 0x10000000u;
else if (itt->second.ModuleName == "CK2.dll")
addr += 0x24000000u;
}
fprintf(stdout, "%08X,", addr);
}
fputc('\n', stdout);
} }
// call reader // call reader