From 5c1af5be243d31616f7350eb3947b62cccc000cb Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Fri, 1 Sep 2023 14:55:31 +0800 Subject: [PATCH] fix fatal CKStateChunk error --- LibCmo/CK2/CKContext.cpp | 4 +++- LibCmo/CK2/CKContext.hpp | 7 ++++++ LibCmo/CK2/CKGlobals.cpp | 11 +++++---- LibCmo/CK2/CKStateChunk.cpp | 1 + LibCmo/CK2/ObjImpls/CK3dEntity.cpp | 20 ++++++++++++++++ LibCmo/CK2/ObjImpls/CK3dEntity.hpp | 32 ++++++++++++++++++++++++++ LibCmo/CK2/ObjImpls/CK3dObject.hpp | 28 ++++++++++++++++++++++ LibCmo/CK2/ObjImpls/CKRenderObject.cpp | 8 +++++++ LibCmo/CK2/ObjImpls/CKRenderObject.hpp | 28 ++++++++++++++++++++++ LibCmo/LibCmo.vcxproj | 5 ++++ LibCmo/LibCmo.vcxproj.filters | 15 ++++++++++++ 11 files changed, 153 insertions(+), 6 deletions(-) create mode 100644 LibCmo/CK2/ObjImpls/CK3dEntity.cpp create mode 100644 LibCmo/CK2/ObjImpls/CK3dEntity.hpp create mode 100644 LibCmo/CK2/ObjImpls/CK3dObject.hpp create mode 100644 LibCmo/CK2/ObjImpls/CKRenderObject.cpp create mode 100644 LibCmo/CK2/ObjImpls/CKRenderObject.hpp diff --git a/LibCmo/CK2/CKContext.cpp b/LibCmo/CK2/CKContext.cpp index 0a28495..4088707 100644 --- a/LibCmo/CK2/CKContext.cpp +++ b/LibCmo/CK2/CKContext.cpp @@ -57,7 +57,7 @@ namespace LibCmo::CK2 { } // create one - ObjImpls::CKObject* obj = desc->CreationFct(this, decided_id, name); + ObjImpls::CKObject* obj = desc->CreationFct(this, decided_id + c_ObjectIdOffset, name); // put into slot m_ObjectsList[decided_id] = obj; @@ -67,6 +67,7 @@ namespace LibCmo::CK2 { } ObjImpls::CKObject* CKContext::GetObject(CK_ID id) { + id -= c_ObjectIdOffset; if (id >= m_ObjectsList.size()) return nullptr; return m_ObjectsList[id]; } @@ -89,6 +90,7 @@ namespace LibCmo::CK2 { desc->ReleaseFct(ctx, obj); } void CKContext::DestroyObject(CK_ID id) { + id -= c_ObjectIdOffset; if (id >= m_ObjectsList.size()) return; // get object and free it diff --git a/LibCmo/CK2/CKContext.hpp b/LibCmo/CK2/CKContext.hpp index 4fa3c6e..f754d88 100644 --- a/LibCmo/CK2/CKContext.hpp +++ b/LibCmo/CK2/CKContext.hpp @@ -97,6 +97,13 @@ namespace LibCmo::CK2 { protected: // ========== Objects Management ========== + /** + * The global offset of created CK_ID. + * The value close to zero may cause some issue. + * So we add a static offset to every created CK_ID. + */ + const CK_ID c_ObjectIdOffset = 61u; + XContainer::XArray m_ObjectsList; std::deque m_ReturnedObjectIds; diff --git a/LibCmo/CK2/CKGlobals.cpp b/LibCmo/CK2/CKGlobals.cpp index 70aff57..82755bc 100644 --- a/LibCmo/CK2/CKGlobals.cpp +++ b/LibCmo/CK2/CKGlobals.cpp @@ -14,6 +14,9 @@ #include "ObjImpls/CKSceneObject.hpp" #include "ObjImpls/CKBeObject.hpp" #include "ObjImpls/CKGroup.hpp" +#include "ObjImpls/CKRenderObject.hpp" +#include "ObjImpls/CK3dEntity.hpp" +#include "ObjImpls/CK3dObject.hpp" namespace LibCmo::CK2 { @@ -222,11 +225,9 @@ CKClassRegister(cid, parentCid, \ EasyClassReg(ObjImpls::CKSceneObject, CK_CLASSID::CKCID_SCENEOBJECT, CK_CLASSID::CKCID_OBJECT, "Scene Object"); EasyClassReg(ObjImpls::CKBeObject, CK_CLASSID::CKCID_BEOBJECT, CK_CLASSID::CKCID_SCENEOBJECT, "Behavioral Object"); EasyClassReg(ObjImpls::CKGroup, CK_CLASSID::CKCID_GROUP, CK_CLASSID::CKCID_BEOBJECT, "Group"); - - //CKClassRegister(CK_CLASSID::CKCID_OBJECT, CK_CLASSID::CKCID_OBJECT, - // [](CKContext* ctx, CK_ID id, CKSTRING name) -> ObjImpls::CKObject* { return new ObjImpls::CKObject(ctx, id, name); }, - // [](CKContext* ctx, ObjImpls::CKObject* obj) -> void { delete obj; }, - // []() -> CKSTRING { return "Basic Object"; }); + EasyClassReg(ObjImpls::CKRenderObject, CK_CLASSID::CKCID_RENDEROBJECT, CK_CLASSID::CKCID_BEOBJECT, "Render Object"); + EasyClassReg(ObjImpls::CK3dEntity, CK_CLASSID::CKCID_3DENTITY, CK_CLASSID::CKCID_RENDEROBJECT, "3D Entity"); + EasyClassReg(ObjImpls::CK3dObject, CK_CLASSID::CKCID_3DOBJECT, CK_CLASSID::CKCID_3DENTITY, "3D Object"); #undef EasyClassReg diff --git a/LibCmo/CK2/CKStateChunk.cpp b/LibCmo/CK2/CKStateChunk.cpp index 55c992f..a645a61 100644 --- a/LibCmo/CK2/CKStateChunk.cpp +++ b/LibCmo/CK2/CKStateChunk.cpp @@ -565,6 +565,7 @@ namespace LibCmo::CK2 { CKDWORD size_in_dword = this->GetCeilDwordSize(size_in_byte); if (this->EnsureReadSpace(size_in_dword)) { std::memcpy(data_ptr, this->m_pData + this->m_Parser.m_CurrentPos, size_in_byte); + this->m_Parser.m_CurrentPos += size_in_dword; return true; } else { // failed, report to context diff --git a/LibCmo/CK2/ObjImpls/CK3dEntity.cpp b/LibCmo/CK2/ObjImpls/CK3dEntity.cpp new file mode 100644 index 0000000..5dfa551 --- /dev/null +++ b/LibCmo/CK2/ObjImpls/CK3dEntity.cpp @@ -0,0 +1,20 @@ +#include "CK3dEntity.hpp" +#include "../CKStateChunk.hpp" + +namespace LibCmo::CK2::ObjImpls { + + bool CK3dEntity::Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) { + bool suc = CKRenderObject::Save(chunk, file, flags); + if (!suc) return false; + + return true; + } + + bool CK3dEntity::Load(CKStateChunk* chunk, CKFileVisitor* file) { + bool suc = CKRenderObject::Load(chunk, file); + if (!suc) return false; + + return true; + } + +} diff --git a/LibCmo/CK2/ObjImpls/CK3dEntity.hpp b/LibCmo/CK2/ObjImpls/CK3dEntity.hpp new file mode 100644 index 0000000..f9ac37d --- /dev/null +++ b/LibCmo/CK2/ObjImpls/CK3dEntity.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "../../VTAll.hpp" +#include "CKRenderObject.hpp" + +namespace LibCmo::CK2::ObjImpls { + + class CK3dEntity : public CKRenderObject { + public: + CK3dEntity(CKContext* ctx, CK_ID ckid, CKSTRING name) : + CKRenderObject(ctx, ckid, name), + m_Meshes(), m_CurrentMesh(nullptr), m_WorldMatrix() + {} + virtual ~CK3dEntity() {} + LIBCMO_DISABLE_COPY_MOVE(CK3dEntity); + + virtual CK_CLASSID GetClassID(void) override { + return CK_CLASSID::CKCID_3DENTITY; + } + //virtual void PreSave(CKFileVisitor* file, CKDWORD flags) override; + virtual bool Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) override; + virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override; + //virtual void PostLoad() override; + + protected: + XContainer::XObjectPointerArray m_Meshes; + CKMesh* m_CurrentMesh; + VxMath::VxMatrix m_WorldMatrix; + + }; + +} diff --git a/LibCmo/CK2/ObjImpls/CK3dObject.hpp b/LibCmo/CK2/ObjImpls/CK3dObject.hpp new file mode 100644 index 0000000..ba95f2a --- /dev/null +++ b/LibCmo/CK2/ObjImpls/CK3dObject.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "../../VTAll.hpp" +#include "CK3dEntity.hpp" + +namespace LibCmo::CK2::ObjImpls { + + class CK3dObject : public CK3dEntity { + public: + CK3dObject(CKContext* ctx, CK_ID ckid, CKSTRING name) : + CK3dEntity(ctx, ckid, name) + {} + virtual ~CK3dObject() {} + LIBCMO_DISABLE_COPY_MOVE(CK3dObject); + + virtual CK_CLASSID GetClassID(void) override { + return CK_CLASSID::CKCID_3DOBJECT; + } + // CK3dObject do not implement any load/save functions + //virtual void PreSave(CKFileVisitor* file, CKDWORD flags) override; + //virtual bool Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) override; + //virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override; + //virtual void PostLoad() override; + protected: + + }; + +} diff --git a/LibCmo/CK2/ObjImpls/CKRenderObject.cpp b/LibCmo/CK2/ObjImpls/CKRenderObject.cpp new file mode 100644 index 0000000..b2d02a9 --- /dev/null +++ b/LibCmo/CK2/ObjImpls/CKRenderObject.cpp @@ -0,0 +1,8 @@ +#include "CKRenderObject.hpp" +#include "../CKStateChunk.hpp" + +namespace LibCmo::CK2::ObjImpls { + + // nothing to compile now + +} diff --git a/LibCmo/CK2/ObjImpls/CKRenderObject.hpp b/LibCmo/CK2/ObjImpls/CKRenderObject.hpp new file mode 100644 index 0000000..8e63757 --- /dev/null +++ b/LibCmo/CK2/ObjImpls/CKRenderObject.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "../../VTAll.hpp" +#include "CKBeObject.hpp" + +namespace LibCmo::CK2::ObjImpls { + + class CKRenderObject : public CKBeObject { + public: + CKRenderObject(CKContext* ctx, CK_ID ckid, CKSTRING name) : + CKBeObject(ctx, ckid, name) + {} + virtual ~CKRenderObject() {} + LIBCMO_DISABLE_COPY_MOVE(CKRenderObject); + + virtual CK_CLASSID GetClassID(void) override { + return CK_CLASSID::CKCID_RENDEROBJECT; + } + // CKRenderObject do not implement any load/save functions + //virtual void PreSave(CKFileVisitor* file, CKDWORD flags) override; + //virtual bool Save(CKStateChunk* chunk, CKFileVisitor* file, CKDWORD flags) override; + //virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override; + //virtual void PostLoad() override; + protected: + + }; + +} diff --git a/LibCmo/LibCmo.vcxproj b/LibCmo/LibCmo.vcxproj index 55c3b31..4668ae9 100644 --- a/LibCmo/LibCmo.vcxproj +++ b/LibCmo/LibCmo.vcxproj @@ -180,9 +180,11 @@ + + @@ -201,8 +203,11 @@ + + + diff --git a/LibCmo/LibCmo.vcxproj.filters b/LibCmo/LibCmo.vcxproj.filters index d3245bc..9cbc81c 100644 --- a/LibCmo/LibCmo.vcxproj.filters +++ b/LibCmo/LibCmo.vcxproj.filters @@ -90,6 +90,12 @@ Sources\XContainer + + Sources\CK2\ObjImpls + + + Sources\CK2\ObjImpls + @@ -152,5 +158,14 @@ Headers\XContainer + + Headers\CK2\ObjImpls + + + Headers\CK2\ObjImpls + + + Headers\CK2\ObjImpls + \ No newline at end of file