refactor project (1/?)

This commit is contained in:
2023-08-22 15:30:26 +08:00
parent f687297ebb
commit 1b8f2ff0d5
34 changed files with 1805 additions and 1396 deletions

View File

@ -0,0 +1,33 @@
#pragma once
#include "CKDefines.hpp"
#include "CKEnums.hpp"
namespace LibCmo::CK2::CKManagerImplements {
class CKBaseManager {
public:
CKBaseManager(CKContext* ctx, CK_ID ckid);
CKBaseManager(const CKBaseManager&) = delete;
CKBaseManager& operator=(const CKBaseManager&) = delete;
virtual ~CKBaseManager();
virtual CKERROR LoadData(CKStateChunk* statechunk, CKFileDocument* doc);
virtual CKStateChunk* SaveData(CKFileDocument* doc);
private:
};
class CKAttributeManager : public CKBaseManager {
public:
CKAttributeManager(CKContext* ctx, CK_ID ckid);
CKAttributeManager(const CKAttributeManager&) = delete;
CKAttributeManager& operator=(const CKAttributeManager&) = delete;
virtual ~CKAttributeManager();
private:
};
}

196
LibCmo/CK2/CKContext.cpp Normal file
View File

@ -0,0 +1,196 @@
#include "CKContext.hpp"
#include <cstdarg>
namespace LibCmo::CK2 {
#if defined(LIBCMO_OS_WIN32)
static wchar_t g_UniqueFolder[] = L"LibCmo";
#else
static char g_UniqueFolder[] = "LibCmo";
#endif
#pragma region Ctor Dtor
CKMinContext::CKMinContext() :
m_NameEncoding(), m_TempFolder(),
m_PrintCallback(nullptr),
m_CKObjectMaxID(0u),
// register CKObjects
m_ObjectsCreationMap{
{CK_CLASSID::CKCID_OBJECT, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKObject(ctx, id, name); })},
{CK_CLASSID::CKCID_SCENEOBJECT, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKSceneObject(ctx, id, name); })},
{CK_CLASSID::CKCID_BEOBJECT, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKBeObject(ctx, id, name); })},
{CK_CLASSID::CKCID_GROUP, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKGroup(ctx, id, name); })},
{CK_CLASSID::CKCID_MESH, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKMesh(ctx, id, name); })},
{CK_CLASSID::CKCID_TEXTURE, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKTexture(ctx, id, name); })},
{CK_CLASSID::CKCID_MATERIAL, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKMaterial(ctx, id, name); })},
{CK_CLASSID::CKCID_RENDEROBJECT, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKRenderObject(ctx, id, name); })},
{CK_CLASSID::CKCID_3DENTITY, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CK3dEntity(ctx, id, name); })},
{CK_CLASSID::CKCID_PARAMETERIN, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKParameterIn(ctx, id, name); })},
{CK_CLASSID::CKCID_PARAMETER, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKParameter(ctx, id, name); })},
{CK_CLASSID::CKCID_PARAMETEROUT, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKParameterOut(ctx, id, name); })},
{CK_CLASSID::CKCID_PARAMETERLOCAL, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKParameterLocal(ctx, id, name); })},
{CK_CLASSID::CKCID_PARAMETEROPERATION, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKParameterOperation(ctx, id, name); })},
{CK_CLASSID::CKCID_BEHAVIORLINK, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKBehaviorLink(ctx, id, name); })},
{CK_CLASSID::CKCID_BEHAVIORIO, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKBehaviorLink(ctx, id, name); })},
{CK_CLASSID::CKCID_BEHAVIOR, ([](CKMinContext* ctx, CK_ID id, CKSTRING name) ->CKObjectImplements::CKObject* { return new(std::nothrow) CKObjectImplements::CKBehavior(ctx, id, name); })}
},
// register CKBaseManagers
m_ManagersCreationMap{
{ATTRIBUTE_MANAGER_GUID, ([](CKMinContext* ctx, CK_ID id) ->CKManagerImplements::CKBaseManager* { return new(std::nothrow) CKManagerImplements::CKAttributeManager(ctx, id); })},
}
{
// preset for temp folder
m_TempFolder = std::filesystem::temp_directory_path();
m_TempFolder /= g_UniqueFolder;
std::filesystem::create_directory(m_TempFolder);
}
CKMinContext::~CKMinContext() {
// free all created objects
for (const auto& [key, value] : this->m_ObjectsList) {
delete value;
}
// todo: free all created managers
}
#pragma endregion
#pragma region Print
void CKMinContext::Printf(CKSTRING fmt, ...) {
if (m_PrintCallback == nullptr) return;
va_list argptr;
va_start(argptr, fmt);
std::string result;
int count = std::vsnprintf(nullptr, 0, fmt, argptr);
result.resize(count);
int write_result = std::vsnprintf(result.data(), count, fmt, argptr);
if (write_result < 0 || write_result > count) return;
va_end(argptr);
m_PrintCallback(result);
}
void CKMinContext::SetPrintCallback(PrintCallback cb) {
m_PrintCallback = cb;
}
#pragma endregion
#pragma region Objects
CKObjectImplements::CKObject* CKMinContext::CreateCKObject(CK_ID id, CK_CLASSID cls, CKSTRING name) {
// pick creation function
const auto& creation = m_ObjectsCreationMap.find(cls);
if (creation == m_ObjectsCreationMap.end()) return nullptr;
// check ckid
if (m_ObjectsList.contains(id)) return nullptr;
// create it
return creation->second(this, id, name);
}
CKObjectImplements::CKObject* CKMinContext::GetCKObject(CK_ID id) {
const auto& probe = m_ObjectsList.find(id);
if (probe == m_ObjectsList.end()) return nullptr;
else return probe->second;
}
void CKMinContext::DestroyCKObject(CK_ID id) {
const auto& probe = m_ObjectsList.find(id);
if (probe != m_ObjectsList.end()) {
delete (probe->second);
m_ObjectsList.erase(probe);
}
}
void CKMinContext::ClearCKObject(void) {
// free all created objects
for (const auto& [key, value] : this->m_ObjectsList) {
delete value;
}
// clear list
this->m_ObjectsList.clear();
}
CK_ID CKMinContext::GetObjectMaxID(void) {
return this->m_CKObjectMaxID;
}
void CKMinContext::SetObjectMaxID(CK_ID id) {
this->m_CKObjectMaxID = id;
}
#pragma endregion
#pragma region Managers
#pragma endregion
#pragma region Misc Funcs
void CKMinContext::GetUtf8String(const std::string& native_name, std::string& u8_name) {
bool success = false;
for (const auto& token : this->m_NameEncoding) {
success = LibCmo::EncodingHelper::GetUtf8VirtoolsName(native_name, u8_name, token);
if (success) break;
}
// fallback
if (!success) {
u8_name = native_name;
this->Printf("Error when converting to UTF8 string.");
}
}
void CKMinContext::GetNativeString(const std::string& u8_name, std::string& native_name) {
bool success = false;
for (const auto& token : this->m_NameEncoding) {
success = LibCmo::EncodingHelper::GetNativeVirtoolsName(u8_name, native_name, token);
if (success) break;
}
// fallback
if (!success) {
native_name = u8_name;
this->Printf("Error when converting to native string.");
}
}
void CKMinContext::SetEncoding(const std::vector<std::string> encoding_series) {
// free all current series
for (const auto& encoding : this->m_NameEncoding) {
LibCmo::EncodingHelper::DestroyEncodingToken(encoding);
}
this->m_NameEncoding.clear();
// add new encoding
for (const auto& encoding_str : encoding_series) {
this->m_NameEncoding.push_back(LibCmo::EncodingHelper::CreateEncodingToken(encoding_str));
}
}
void CKMinContext::SetTempPath(CKSTRING u8_temp) {
EncodingHelper::SetStdPathFromU8Path(this->m_TempFolder, u8_temp);
}
FILE* CKMinContext::OpenTempFile(CKSTRING u8_filename, bool is_read) {
std::filesystem::path stdfilename;
EncodingHelper::SetStdPathFromU8Path(stdfilename, u8_filename);
auto realfile = this->m_TempFolder / stdfilename;
return EncodingHelper::OpenStdPathFile(realfile, is_read);
}
#pragma endregion
}

72
LibCmo/CK2/CKContext.hpp Normal file
View File

@ -0,0 +1,72 @@
#pragma once
#include "../VTAll.hpp"
#include <filesystem>
#include <map>
#include <functional>
namespace LibCmo::CK2 {
/**
@brief Main Interface Object
@details
+ The CKContext object is the heart of all Virtools based applications, It is the first object that should be created in order to
use Virtools SDK. A CKContext can be simply created by calling its constructor.
+ The CKContext object act as the central interface to create/destroy objects,to access managers, to load/save files.
+ Several CKContext can be created inside a same process (in multiple threads for example) but objects created
by a specific CKContext must not be used in other contextes.
@see CKContext::CreateObject, CKContext::GetObject, CKContext::DestroyObject
*/
class CKContext {
public:
CKContext();
CKContext(const CKContext&) = delete;
CKContext& operator=(const CKContext&) = delete;
~CKContext();
using PrintCallback = std::function<void(const std::string&)>;
void Printf(CKSTRING fmt, ...);
void SetPrintCallback(PrintCallback cb);
/**
* @brief Creates a CKObject or derived class instance.
* @param[in] cls Class Identifier (CK_CLASSID) of the object to create.
* @param[in] name The name of this object.
* @return A pointer to the newly created object.
* @remark CKObjects must be destroy with the DestroyObject method.
* @see CKObject, DestroyObject
*/
CKObject* CreateCKObject(CK_CLASSID cls, CKSTRING name);
CKObject* GetCKObject(CK_ID id);
void DestroyCKObject(CK_ID id);
//CKManagerImplements::CKBaseManager* CreateCKManager(CKGUID guid);
//CKManagerImplements::CKBaseManager* GetCKManager(CK_ID guid);
//void DestroyCKManager(CKManagerImplements::CKBaseManager* mgr);
CK_ID GetObjectMaxID(void);
void SetObjectMaxID(CK_ID id);
void GetUtf8String(const std::string& native_name, std::string& u8_name);
void GetNativeString(const std::string& u8_name, std::string& native_name);
void SetEncoding(const std::vector<std::string> encoding_series);
void SetTempPath(CKSTRING u8_temp);
FILE* OpenTempFile(CKSTRING u8_filename, bool is_read);
public:
std::map<CK_ID, CKObject*> m_ObjectsList;
std::map<CK_ID, CKBaseManager*> m_ManagersList;
std::map<CK_CLASSID, std::function<CKObject* (CKContext*, CK_ID, CKSTRING)>> m_ObjectsCreationMap;
std::map<CKGUID, std::function<CKBaseManager* (CKContext*, CK_ID)>> m_ManagersCreationMap;
CK_ID m_CKObjectMaxID;
std::vector<EncodingHelper::ENCODING_TOKEN> m_NameEncoding;
std::filesystem::path m_TempFolder;
PrintCallback m_PrintCallback;
};
}

19
LibCmo/CK2/CKDefines.hpp Normal file
View File

@ -0,0 +1,19 @@
#pragma once
#include <string>
#include <vector>
#include <cstring>
#include <cinttypes>
#include "CKTypes.hpp"
namespace LibCmo::CK2 {
/**
* @brief Current Version of CK Engine (Day/Month/Year)
*/
constexpr const CKDWORD CKVERSION = 0x05082002u;
/**
* @brief Current Version of Dev
*/
constexpr const CKDWORD DEVVERSION = 0x02050000u;
constexpr const CKGUID VIRTOOLS_GUID = CKGUID(0x56495254u, 0x4f4f4c53u);
}

201
LibCmo/CK2/CKEnums.hpp Normal file
View File

@ -0,0 +1,201 @@
#pragma once
#include "../VTUtils.hpp"
#include "CKTypes.hpp"
#include <cinttypes>
#include <cstdint>
namespace LibCmo::CK2 {
#pragma region Preregistred Managers
// Virtools Managers GUID second data is 0
constexpr const CKDWORD OBJECT_MANAGER_GUID1 = 0x7cbb3b91;
constexpr const CKDWORD ATTRIBUTE_MANAGER_GUID1 = 0x3d242466;
constexpr const CKDWORD MESSAGE_MANAGER_GUID1 = 0x466a0fac;
constexpr const CKDWORD FLOOR_MANAGER_GUID1 = 0x420936f9;
constexpr const CKDWORD COLLISION_MANAGER_GUID1 = 0x38244712;
constexpr const CKDWORD GRID_MANAGER_GUID1 = 0x7f004791;
constexpr const CKDWORD TIME_MANAGER_GUID1 = 0x89ce7b32;
constexpr const CKDWORD BEHAVIOR_MANAGER_GUID1 = 0x58d621ae;
constexpr const CKDWORD INPUT_MANAGER_GUID1 = 0xf787c904;
constexpr const CKDWORD SOUND_MANAGER_GUID1 = 0xdce135f6;
constexpr const CKDWORD MIDI_MANAGER_GUID1 = 0x594154a6;
constexpr const CKDWORD INTERFACE_MANAGER_GUID1 = 0x9a4b8e3d;
constexpr const CKDWORD RENDER_MANAGER_GUID1 = 0xa213c8d5;
constexpr const CKDWORD PARAMETER_MANAGER_GUID1 = 0x9ce57ab6;
constexpr const CKDWORD PATH_MANAGER_GUID1 = 0x15fd54b9;
constexpr const CKDWORD VARIABLE_MANAGER_GUID1 = 0x98cc3cc9;
constexpr const CKGUID OBJECT_MANAGER_GUID{ OBJECT_MANAGER_GUID1 ,0 };
constexpr const CKGUID ATTRIBUTE_MANAGER_GUID{ ATTRIBUTE_MANAGER_GUID1, 0 };
constexpr const CKGUID MESSAGE_MANAGER_GUID{ MESSAGE_MANAGER_GUID1 ,0 };
constexpr const CKGUID TIME_MANAGER_GUID{ TIME_MANAGER_GUID1 ,0 };
constexpr const CKGUID SOUND_MANAGER_GUID{ SOUND_MANAGER_GUID1 ,0 };
constexpr const CKGUID MIDI_MANAGER_GUID{ MIDI_MANAGER_GUID1 ,0 };
constexpr const CKGUID INPUT_MANAGER_GUID{ INPUT_MANAGER_GUID1 ,0 };
constexpr const CKGUID BEHAVIOR_MANAGER_GUID{ BEHAVIOR_MANAGER_GUID1 ,0 };
constexpr const CKGUID FLOOR_MANAGER_GUID{ FLOOR_MANAGER_GUID1 ,0 };
constexpr const CKGUID COLLISION_MANAGER_GUID{ COLLISION_MANAGER_GUID1 ,0 };
constexpr const CKGUID GRID_MANAGER_GUID{ GRID_MANAGER_GUID1 ,0 };
constexpr const CKGUID INTERFACE_MANAGER_GUID{ INTERFACE_MANAGER_GUID1 ,0 };
constexpr const CKGUID RENDER_MANAGER_GUID{ RENDER_MANAGER_GUID1 ,0 };
constexpr const CKGUID PARAMETER_MANAGER_GUID{ PARAMETER_MANAGER_GUID1 ,0 };
constexpr const CKGUID PATH_MANAGER_GUID{ PATH_MANAGER_GUID1 ,0 };
constexpr const CKGUID VARIABLE_MANAGER_GUID{ VARIABLE_MANAGER_GUID1 ,0 };
#pragma endregion
/**
Specify the way files are saved to disk (compression)
@remark
+ File write mode controls the format of a Virtools file when saved. More specifically it
controls whether compression is enabled and also if the Virtools Dev Interface specific data
should be stored in the file (if CKFILE_FORVIEWER flag is set , no interface data is saved)
See also: CKContext::SetFileWriteMode, CKContext::GetFileWriteMode, CKContext::SetCompressionLevel,
CKContext::SetGlobalImagesSaveOptions, CKContext::SetGlobalSoundsSaveOptions
*/
enum class CK_FILE_WRITEMODE : uint32_t {
CKFILE_UNCOMPRESSED = 0, /**< Save data uncompressed */
CKFILE_CHUNKCOMPRESSED_OLD = 1, /**< Obsolete */
CKFILE_EXTERNALTEXTURES_OLD = 2, /**< Obsolete : use CKContext::SetGlobalImagesSaveOptions instead. */
CKFILE_FORVIEWER = 4, /**< Don't save Interface Data within the file, the level won't be editable anymore in the interface */
CKFILE_WHOLECOMPRESSED = 8, /**< Compress the whole file */
};
LIBCMO_BITFLAG_OPERATORS(CK_FILE_WRITEMODE);
/**
Load Options.
@remark
+ This options apply when loading a Virtools file
or a importing a 3D Model file.
+ They defines whether object geometry,only animations
or only behaviors should be loaded.
+ One can specify (using the CK_LOAD_AS_DYNAMIC_OBJECT) if
created CKObjects should be created as dynamic (See also Dynamic Objects)
See also : CKContext::Load, CKContext::CKSave
*/
enum class CK_LOAD_FLAGS : uint32_t {
CK_LOAD_ANIMATION = 1 << 0, /**< Load animations */
CK_LOAD_GEOMETRY = 1 << 1, /**< Load geometry. */
CK_LOAD_DEFAULT = CK_LOAD_GEOMETRY | CK_LOAD_ANIMATION, /**< Load animations & geometry */
CK_LOAD_ASCHARACTER = 1 << 2, /**< Load all the objects and create a character that contains them all . */
CK_LOAD_DODIALOG = 1 << 3, /**< Check object name unicity and warns the user with a dialog box when duplicate names are found. */
CK_LOAD_AS_DYNAMIC_OBJECT = 1 << 4, /**< Objects loaded from this file may be deleted at run-time or are temporary */
CK_LOAD_AUTOMATICMODE = 1 << 5, /**< Check object name unicity and automatically rename or replace according to the options specified in CKContext::SetAutomaticLoadMode */
CK_LOAD_CHECKDUPLICATES = 1 << 6, /**< Check object name unicity (The list of duplicates is stored in the CKFile class after a OpenFile call */
CK_LOAD_CHECKDEPENDENCIES = 1 << 7, /**< Check if every plugins needed are availables */
CK_LOAD_ONLYBEHAVIORS = 1 << 8, /**< */
};
LIBCMO_BITFLAG_OPERATORS(CK_LOAD_FLAGS);
/**
Options that will be used to create this object...
*/
enum class CK_FO_OPTIONS : uint32_t {
CK_FO_DEFAULT = 0, /**< Default behavior : a new object will be created with the name stored in CKFileObject */
CK_FO_RENAMEOBJECT, /**< Renaming : a new object will be created with the name stored in CKFileObject + a integer value XXX to ensure its uniqueness */
CK_FO_REPLACEOBJECT, /**< Do not create a new object, instead use an existing one which CK_ID is given by CreatedObject to load the chunk on */
CK_FO_DONTLOADOBJECT, /**< Object chunk will not be read either because it is a reference or because the loaded object already exist in the current level and the user choose to keep the existing one. */
};
/**
Type identifier for a Virtools plugin.
@remark
+ Each plugin must be given a type.
+ This enumeration is used to identify a specific catagory
of plugin when using the CKPluginManager.
@see CKPluginManager
*/
enum class CK_PLUGIN_TYPE : uint32_t {
CKPLUGIN_BITMAP_READER = 0, /**< The plugin is bitmap (textures,sprites) loader */
CKPLUGIN_SOUND_READER = 1, /**< Sound Reader Plugin */
CKPLUGIN_MODEL_READER = 2, /**< 3D Model Reader */
CKPLUGIN_MANAGER_DLL = 3, /**< The plugin implements a Manager */
CKPLUGIN_BEHAVIOR_DLL = 4, /**< The plugin implements one or more behaviors */
CKPLUGIN_RENDERENGINE_DLL = 5, /**< Render Engine plugin */
CKPLUGIN_MOVIE_READER = 6, /**< Movie (AVI,Mpeg) reader */
CKPLUGIN_EXTENSION_DLL = 7, /**< Generic extension (definition of new parameter types or operations for ex.) */
};
/**
@remark CHUNK_OPTIONS in original Virtools header.
*/
enum class CK_STATECHUNK_CHUNKOPTIONS : uint32_t {
CHNK_OPTION_IDS = 0x01, /**< IDS are stored inside chunk */
CHNK_OPTION_MAN = 0x02, /**< Managers ints are store inside chunk */
CHNK_OPTION_CHN = 0x04, /**< Sub chunk are stored inside chunk */
CHNK_OPTION_FILE = 0x08, /**< Chunk was written with indices relative to a file.... */
CHNK_OPTION_ALLOWDYN = 0x10, /**< Dynamic object can be written in the chunk */
CHNK_OPTION_LISTBIG = 0x20, /**< List are store in big Endian ? */
CHNK_DONTDELETE_PTR = 0x40, /**< Data buffer stored in m_Buffer is not owned by CKStateChunk , it must not be deleted... */
CHNK_DONTDELETE_PARSER = 0x80, /**< m_Parser Ptr is not owned by CKStateChunk , it must not be deleted... */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATECHUNK_CHUNKOPTIONS);
enum class CK_STATECHUNK_CHUNKVERSION : uint32_t {
CHUNK_VERSIONBASE = 0,
CHUNK_VERSION1 = 4, /**< equal to file version : WriteObjectID => table */
CHUNK_VERSION2 = 5, /**< add Manager Data */
CHUNK_VERSION3 = 6, /**< New ConvertToBuffer / ReadFromBuffer (file system changed to reflect this ) */
CHUNK_VERSION4 = 7, /**< New WriteObjectID when saving to a file */
};
enum class CK_STATECHUNK_DATAVERSION : uint32_t {
CHUNKDATA_OLDVERSION = 0, /**< Before any version was saved */
CHUNKDATA_BASEVERSION = 1, /**< First version */
CHUNK_WAVESOUND_VERSION2 = 2, /**< Changes in wavesound format */
CHUNK_WAVESOUND_VERSION3 = 3, /**< Changes in wavesound format */
CHUNK_MATERIAL_VERSION_ZTEST = 4, /**< Change in material save format */
CHUNK_MAJORCHANGE_VERSION = 5, /**< Optimisations on many save functions */
CHUNK_MACCHANGE_VERSION = 6, /**< Misc new Statechunk functions for macintosh (Big-Endian <-> Little Endian conversion ) */
CHUNK_WAVESOUND_VERSION4 = 7, /**< Changes in wavesound format (Added sound length) */
CHUNK_SCENECHANGE_VERSION = 8, /**< Changes in sceneObjectDesc format (Remove lasttimevalue) */
CHUNK_MESHCHANGE_VERSION = 9, /**< Changes in Mesh save format (primitives) */
CHUNK_DEV_2_1 = 10, /**< Changes in wavesound reading of inside, outside angles */
CHUNKDATA_CURRENTVERSION = CHUNK_DEV_2_1,
};
/**
CKObject Flags
@remark
+ Flags specifying special settings for basic objects.
+ Some of this flags are shared with sub-classes such as CKParameterIn,CKParameterOut and CKBehaviorIO.
+ You rarely need to modify directly this flags through CKObject::SetFlags or CKObject::ModifyObjectFlags instead
you should always use the specific acces function (given between ()) which may need to perform additionnal operations.
See also: CKObject, CKObject::GetObjectFlags, CKObject::ModifyObjectFlags
*/
enum class CK_OBJECT_FLAGS : uint32_t {
CK_OBJECT_INTERFACEOBJ = 0x00000001, /**< Reserved for Inteface Use */
CK_OBJECT_PRIVATE = 0x00000002, /**< The object must not be displayed in interface (Lists,Level view,etc...),nor should it be saved. (CKObject::IsPrivate() */
CK_OBJECT_INTERFACEMARK = 0x00000004,
CK_OBJECT_FREEID = 0x00000008, /**< ID of this object can be released safely and is free to be reused by future CKobjects. */
CK_OBJECT_TOBEDELETED = 0x00000010, /**< This object is being deleted */
CK_OBJECT_NOTTOBESAVED = 0x00000020, /**< This object must not be saved */
CK_OBJECT_VISIBLE = 0x00000040, /**< This object is visible (CKObject::Show) */
CK_OBJECT_NAMESHARED = 0x00000080, /**< This object has its name from another entity */
CK_OBJECT_DYNAMIC = 0x00000108, /**< This object may be created or deleted at run-time, it also contails CK_OBJECT_FREEID. (CKObject::IsDynamic,CKContext::CreateObject) */
CK_OBJECT_HIERACHICALHIDE = 0x00000200, /**< This object hides all its hierarchy (CKObject::Show) */
CK_OBJECT_UPTODATE = 0x00000400, /**< (Camera,etc..) */
CK_OBJECT_TEMPMARKER = 0x00000800,
CK_OBJECT_ONLYFORFILEREFERENCE = 0x00001000,
CK_OBJECT_NOTTOBEDELETED = 0x00002000, /**< This object must not be deleted in a clear all */
CK_OBJECT_APPDATA = 0x00004000, /**< This object has app data */
CK_OBJECT_SINGLEACTIVITY = 0x00008000, /**< this object has an information of single activity */
CK_OBJECT_LOADSKIPBEOBJECT = 0x00010000, /**< When loading this object the CKBeObject part should be skipped */
CK_OBJECT_NOTTOBELISTEDANDSAVED = 0x00000023, /**< Combination of Private and Not To Be Saved The following flags are specific to parameters (they are stored here for object's size purposes ) */
CK_PARAMETEROUT_SETTINGS = 0x00400000,
CK_PARAMETEROUT_PARAMOP = 0x00800000, /**< This parameter is the output of a CKParameterOperation (Automatically set by Engine) */
CK_PARAMETERIN_DISABLED = 0x01000000, /**< Parameter In or Out is disabled (CKBehavior::EnableInputParameter,CKBehavior::DisableInputParameter) */
CK_PARAMETERIN_THIS = 0x02000000, /**< Special parameter type : its value and type are always equal to its owner (CKParameter::SetAsMyselfParameter) */
CK_PARAMETERIN_SHARED = 0x04000000,
CK_PARAMETEROUT_DELETEAFTERUSE = 0x08000000, /**< When adding parameters to CKMessage, they can be automatically deleted when message is released (CKMessage::AddParameter) */
CK_OBJECT_PARAMMASK = 0x0FC00000, /**< Mask for options specific to parameters The Following flags are specific for Behavior ios (CKBehaviorIO) */
CK_BEHAVIORIO_IN = 0x10000000, /**< This BehaviorIO is a behavior input (CKBehaviorIO::SetType} */
CK_BEHAVIORIO_OUT = 0x20000000, /**< This BehaviorIO is a behavior output (CKBehaviorIO::SetType) */
CK_BEHAVIORIO_ACTIVE = 0x40000000, /**< This BehaviorIO is a currently active (CKBehaviorIO::Activate} */
CK_OBJECT_IOTYPEMASK = 0x30000000,
CK_OBJECT_IOMASK = 0xF0000000, /**< The Following flags are specific for Behavior ios (CKBehaviorIO) */
CKBEHAVIORLINK_RESERVED = 0x10000000, /**< This BehaviorIO is a behavior input (CKBehaviorIO::SetType} */
CKBEHAVIORLINK_ACTIVATEDLASTFRAME = 0x20000000, /**< This link had been activated last frame */
CK_OBJECT_BEHAVIORLINKMASK = 0x30000000,
};
LIBCMO_BITFLAG_OPERATORS(CK_OBJECT_FLAGS);
}

188
LibCmo/CK2/CKFile.cpp Normal file
View File

@ -0,0 +1,188 @@
#include "CKFile.hpp"
#include "CKStateChunk.hpp"
#include "CKMinContext.hpp"
#include <cstdarg>
namespace LibCmo::CK2 {
#pragma region CKBufferParser
CKBufferParser::CKBufferParser(void* ptr, size_t rsize, bool need_manual_free) :
m_MemBegin(static_cast<char*>(ptr)),
m_MemPos(0u), m_MemSize(rsize),
m_NeedManualFree(need_manual_free) {
;
}
CKBufferParser::~CKBufferParser() {
if (this->m_NeedManualFree) delete[](this->m_MemBegin);
}
#pragma endregion
#pragma region CKFileInfo
CKFileInfo::CKFileInfo() :
ProductVersion(0u), ProductBuild(0x01010000u), FileWriteMode(CK_FILE_WRITEMODE::CKFILE_UNCOMPRESSED),
FileVersion(8u), CKVersion(CKVERSION), FileSize(0u),
ObjectCount(0u), ManagerCount(0u), MaxIDSaved(0u), Crc(0u),
Hdr1PackSize(0u), Hdr1UnPackSize(0u), DataPackSize(0u), DataUnPackSize(0u) {
}
CKFileInfo::CKFileInfo(const CKFileInfo& rhs) :
ProductVersion(rhs.ProductVersion), ProductBuild(rhs.ProductBuild), FileWriteMode(rhs.FileWriteMode),
FileVersion(rhs.FileVersion), CKVersion(rhs.CKVersion), FileSize(rhs.FileSize),
ObjectCount(rhs.ObjectCount), ManagerCount(rhs.ManagerCount), MaxIDSaved(rhs.MaxIDSaved), Crc(rhs.Crc),
Hdr1PackSize(rhs.Hdr1PackSize), Hdr1UnPackSize(rhs.Hdr1UnPackSize),
DataPackSize(rhs.DataPackSize), DataUnPackSize(rhs.DataUnPackSize) {
}
CKFileInfo& CKFileInfo::operator=(const CKFileInfo& rhs) {
this->ProductVersion = rhs.ProductVersion;
this->ProductBuild = rhs.ProductBuild;
this->FileWriteMode = rhs.FileWriteMode;
this->FileVersion = rhs.FileVersion;
this->CKVersion = rhs.CKVersion;
this->FileSize = rhs.FileSize;
this->ObjectCount = rhs.ObjectCount;
this->ManagerCount = rhs.ManagerCount;
this->MaxIDSaved = rhs.MaxIDSaved;
this->Crc = rhs.Crc;
this->Hdr1PackSize = rhs.Hdr1PackSize;
this->Hdr1UnPackSize = rhs.Hdr1UnPackSize;
this->DataPackSize = rhs.DataPackSize;
this->DataUnPackSize = rhs.DataUnPackSize;
return *this;
}
CKFileInfo::~CKFileInfo() {
}
#pragma endregion
#pragma region CKFileObject
CKFileObject::CKFileObject() :
ObjectId(0u), CreatedObject(0u), ObjectCid(CK_CLASSID::CKCID_OBJECT), Name(),
ObjPtr(nullptr), Data(nullptr), FileIndex(0u) {
}
CKFileObject::CKFileObject(const CKFileObject& rhs) :
ObjectId(rhs.ObjectId), CreatedObject(rhs.CreatedObject), ObjectCid(rhs.ObjectCid), Name(rhs.Name),
ObjPtr(rhs.ObjPtr), Data(rhs.Data), FileIndex(rhs.FileIndex) {
// CKObject is managed by CKMinContext, so we just copy its pointer.
// however, we need copy CKStateChunk.
if (this->Data != nullptr) {
this->Data = new(std::nothrow) CKStateChunk(*(rhs.Data));
}
}
CKFileObject& CKFileObject::operator=(const CKFileObject& rhs) {
this->ObjectId = rhs.ObjectId;
this->CreatedObject = rhs.CreatedObject;
this->ObjectCid = rhs.ObjectCid;
this->Name = rhs.Name;
this->FileIndex = rhs.FileIndex;
// CKObject is managed by CKMinContext, so we just copy its pointer.
this->ObjPtr = rhs.ObjPtr;
// however, we need copy CKStateChunk.
this->Data = rhs.Data;
if (this->Data != nullptr) {
this->Data = new(std::nothrow) CKStateChunk(*(rhs.Data));
}
return *this;
}
CKFileObject::~CKFileObject() {
if (Data != nullptr) delete Data;
}
#pragma endregion
#pragma region CKFileManagerData
CKFileManagerData::CKFileManagerData() :
MgrPtr(nullptr), Data(nullptr), Manager(0u, 0u) {
}
CKFileManagerData::CKFileManagerData(const CKFileManagerData& rhs) :
MgrPtr(rhs.MgrPtr), Data(rhs.Data), Manager(rhs.Manager) {
if (this->Data != nullptr) {
this->Data = new(std::nothrow) CKStateChunk(*(rhs.Data));
}
}
CKFileManagerData& CKFileManagerData::operator=(const CKFileManagerData& rhs) {
this->Manager = rhs.Manager;
this->MgrPtr = rhs.MgrPtr;
this->Data = rhs.Data;
if (this->Data != nullptr) {
this->Data = new(std::nothrow) CKStateChunk(*(rhs.Data));
}
return *this;
}
CKFileManagerData::~CKFileManagerData() {
if (Data != nullptr) delete Data;
}
#pragma endregion
#pragma region CKFilePluginDependencies
CKFilePluginDependencies::CKFilePluginDependencies() :
m_PluginCategory(CK_PLUGIN_TYPE::CKPLUGIN_MANAGER_DLL), m_Guids() {
}
CKFilePluginDependencies::CKFilePluginDependencies(const CKFilePluginDependencies& rhs) :
m_PluginCategory(rhs.m_PluginCategory), m_Guids(rhs.m_Guids) {
}
CKFilePluginDependencies& CKFilePluginDependencies::operator=(const CKFilePluginDependencies& rhs) {
this->m_PluginCategory = rhs.m_PluginCategory;
this->m_Guids = rhs.m_Guids;
return *this;
}
CKFilePluginDependencies::~CKFilePluginDependencies() {
}
#pragma endregion
#pragma region ShallowDocument
CKFileDocument::CKFileDocument() {
/*this->m_IndexByClassId.resize(static_cast<size_t>(CK_CLASSID::CKCID_MAXCLASSID));*/
}
CKFileDocument::~CKFileDocument() {
}
#pragma endregion
#pragma region CKFile Misc
CKFile::CKFile(CKMinContext* ctx) :
m_MinCtx(ctx) {
;
}
CKFile::~CKFile() {
}
#pragma endregion
}

193
LibCmo/CK2/CKFile.hpp Normal file
View File

@ -0,0 +1,193 @@
#pragma once
#include "CKDefines.hpp"
#include "CKEnums.hpp"
namespace LibCmo::CK2 {
class CKBufferParser {
private:
char* m_MemBegin;
size_t m_MemPos;
bool m_NeedManualFree;
size_t m_MemSize;
public:
CKBufferParser(void* ptr, size_t rsize, bool need_manual_free);
CKBufferParser(const CKBufferParser&) = delete;
CKBufferParser& operator=(const CKBufferParser&) = delete;
~CKBufferParser();
inline const void* GetPtr(void) { return (this->m_MemBegin + m_MemPos); }
inline void Read(void* data, size_t data_size) {
std::memcpy(data, (this->m_MemBegin + m_MemPos), data_size);
this->m_MemPos += data_size;
}
inline void Write(const void* data, size_t data_size) {
std::memcpy((this->m_MemBegin + m_MemPos), data, data_size);
this->m_MemPos += data_size;
}
inline void* GetBase(void) { return this->m_MemBegin; }
inline size_t GetSize(void) { return this->m_MemSize; }
inline size_t GetCursor(void) { return this->m_MemPos; }
inline void MoveCursor(size_t off) { this->m_MemPos += off; }
inline void SetCursor(size_t off) { this->m_MemPos = off; }
};
#pragma pack(push)
#pragma pack(1)
struct CKRawFileInfo {
CKBYTE NeMo[8];
CKDWORD Crc;
CKDWORD CKVersion;
CKDWORD FileVersion;
CKDWORD Zero;
CKDWORD FileWriteMode;
CKDWORD Hdr1PackSize;
CKDWORD DataPackSize;
CKDWORD DataUnPackSize;
CKDWORD ManagerCount;
CKDWORD ObjectCount;
CKDWORD MaxIDSaved;
CKDWORD ProductVersion;
CKDWORD ProductBuild;
CKDWORD Hdr1UnPackSize;
};
#pragma pack(pop)
class CKFileInfo {
public:
CKFileInfo();
CKFileInfo(const CKFileInfo&);
CKFileInfo& operator=(const CKFileInfo&);
~CKFileInfo();
CKDWORD ProductVersion; // Virtools Version (Dev/Creation). (CK_VIRTOOLS_VERSION)
CKDWORD ProductBuild; // Virtools Build Number.
CK_FILE_WRITEMODE FileWriteMode; // Options used to save this file. (CK_FILE_WRITEMODE)
CKDWORD FileVersion; // Version of file format when file was saved.
CKDWORD CKVersion; // Version of CK when file was saved.
size_t FileSize; // Size of file in bytes.
CKDWORD ObjectCount; // Number of objects stored in the file.
CKDWORD ManagerCount; // Number of managers which saved data in the file.
CKDWORD MaxIDSaved; // Maximum Object identifier saved
CKDWORD Crc; // Crc of data
CKDWORD Hdr1PackSize; // Reserved
CKDWORD Hdr1UnPackSize; // Reserved
CKDWORD DataPackSize; // Reserved
CKDWORD DataUnPackSize; // Reserved
private:
};
class CKFileObject {
public:
CKFileObject();
CKFileObject(const CKFileObject&);
CKFileObject& operator=(const CKFileObject&);
~CKFileObject();
CK_ID ObjectId; // ID of the object being load/saved (as it will be/was saved in the file)
CK_ID CreatedObject; // ID of the object being created
CK_CLASSID ObjectCid; // Class Identifier of the object
CKObjectImplements::CKObject* ObjPtr; // A pointer to the object itself (as CreatedObject when loading)
std::string Name; // Name of the Object
CKStateChunk* Data; // A CKStateChunk that contains object information
CKDWORD FileIndex; // Position of the object data inside uncompressed file buffer
private:
};
class CKFileManagerData {
public:
CKFileManagerData();
CKFileManagerData(const CKFileManagerData&);
CKFileManagerData& operator=(const CKFileManagerData&);
~CKFileManagerData();
CKManagerImplements::CKBaseManager* MgrPtr;
CKStateChunk* Data;
CKGUID Manager;
private:
};
class CKFilePluginDependencies {
public:
CKFilePluginDependencies();
CKFilePluginDependencies(const CKFilePluginDependencies&);
CKFilePluginDependencies& operator=(const CKFilePluginDependencies&);
~CKFilePluginDependencies();
CK_PLUGIN_TYPE m_PluginCategory;
XArray<CKGUID> m_Guids;
private:
};
class CKFileDocument {
public:
CKFileDocument();
~CKFileDocument();
int32_t m_SaveIDMax;
CKFileInfo m_FileInfo;
XArray<CKFileObject> m_FileObjects;
XArray<CKFileManagerData> m_FileManagersData;
XClassArray<CKFilePluginDependencies> m_PluginDep;
/*XClassArray<XIntArray> m_IndexByClassId;*/
XClassArray<XString> m_IncludedFiles;
private:
};
class CKFile {
public:
CKFile(CKMinContext* ctx);
CKFile(const CKFile&) = delete;
CKFile& operator=(const CKFile&) = delete;
~CKFile();
void ClearData(void);
CKERROR ShallowLoad(CKSTRING u8_filename, CKFileDocument** out_doc);
CKERROR DeepLoad(CKSTRING u8_filename, CKFileDocument** out_doc);
CKERROR Save(CKSTRING u8_filename, CKFileDocument* in_doc);
//CKERROR Load(CKSTRING u8_filename, /*CKObjectArray list, */ CK_LOAD_FLAGS flags);
//CKERROR OpenFile(CKSTRING u8_filename, CK_LOAD_FLAGS flags);
//CKERROR OpenMemory(void* MemoryBuffer, size_t BufferSize, CK_LOAD_FLAGS Flags);
//CKERROR ReadFileHeaders(CKBufferParser** ParserPtr);
//CKERROR ReadFileData(CKBufferParser** ParserPtr);
//CKERROR LoadFileData(void/*CKObjectArray list*/);
//CKERROR FinishLoading(/*CKObjectArray list, */CK_LOAD_FLAGS flags);
//int32_t m_SaveIDMax;
//XArray<CKFileObject> m_FileObject;
//XArray<CKFileManagerData> m_ManagersData;
//XClassArray<CKFilePluginDependencies> m_PluginDep;
//XClassArray<XIntArray> m_IndexByClassId;
//XClassArray<XString> m_IncludedFiles;
//CKFileInfo m_FileInfo;
//CK_LOAD_FLAGS m_Flags;
//bool m_ReadFileDataDone;
private:
// reader function and variables
CKERROR ReadFileHeader(CKBufferParser* ParserPtr, CKFileDocument* doc);
CKERROR ReadFileData(CKBufferParser* ParserPtr, CKFileDocument* doc);
// writer function and varibales
// shared function and variables
CKMinContext* m_MinCtx;
};
}

416
LibCmo/CK2/CKFileReader.cpp Normal file
View File

@ -0,0 +1,416 @@
#include "CKFile.hpp"
#include "CKGlobals.hpp"
#include "CKStateChunk.hpp"
#include "CKObjects.hpp"
#include "VxMemoryMappedFile.hpp"
#include "CKMinContext.hpp"
#include <memory>
namespace LibCmo::CK2 {
/*
* NOTE:
* We onlt support read Virtools file with FileVersion >= 7.
* The file with FileVersion < 7 is older than NeMo 1.0 (CK 1.1).
* No need to support them.
*/
CKERROR CKFile::ShallowLoad(CKSTRING u8_filename, CKFileDocument** out_doc) {
// preset value
*out_doc = nullptr;
// check file and open memory
if (u8_filename == nullptr) return CKERROR::CKERR_INVALIDPARAMETER;
std::unique_ptr<VxMath::VxMemoryMappedFile> mappedFile(new(std::nothrow) VxMath::VxMemoryMappedFile(u8_filename));
if (mappedFile == nullptr) {
this->m_MinCtx->Printf("Out of memory when creating Memory File.");
return CKERROR::CKERR_OUTOFMEMORY;
}
if (!mappedFile->IsValid()) {
this->m_MinCtx->Printf("Fail to create Memory File for \"%s\".", u8_filename);
return CKERROR::CKERR_INVALIDFILE;
}
// create document
std::unique_ptr<CKFileDocument> doc(new(std::nothrow) CKFileDocument());
if (doc == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
// create buffer and start loading
std::unique_ptr<CKBufferParser> parser(new(std::nothrow) CKBufferParser(mappedFile->GetBase(), mappedFile->GetFileSize(), false));
CKERROR err = this->ReadFileHeader(parser.get(), doc.get());
if (err != CKERROR::CKERR_OK) return err;
err = this->ReadFileData(parser.get(), doc.get());
if (err != CKERROR::CKERR_OK) return err;
// unbind document and assign it
*out_doc = doc.release();
// other data will be free automatically
return CKERROR::CKERR_OK;
}
CKERROR CKFile::ReadFileHeader(CKBufferParser* ParserPtr, CKFileDocument* doc) {
std::unique_ptr<CKBufferParser> parser(new(std::nothrow) CKBufferParser(ParserPtr->GetBase(), ParserPtr->GetSize(), false));
if (parser == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
parser->SetCursor(ParserPtr->GetCursor());
std::string name_conv;
// ========== read header ==========
// check header size
if (parser->GetSize() < sizeof(CKRawFileInfo)) return CKERROR::CKERR_INVALIDFILE;
if (std::memcmp(parser->GetPtr(), "Nemo Fi", sizeof(CKRawFileInfo::NeMo))) return CKERROR::CKERR_INVALIDFILE;
// read header
CKRawFileInfo rawHeader;
parser->Read(&rawHeader, sizeof(CKRawFileInfo));
// ========== header checker ==========
// check zero flag?
if (rawHeader.Zero) return CKERROR::CKERR_INVALIDFILE;
// check file version
if (rawHeader.FileVersion > 9 || rawHeader.FileVersion < 7) return CKERROR::CKERR_OBSOLETEVIRTOOLS;
// force reset too big product ver?
if (rawHeader.ProductVersion >= 12u) {
rawHeader.ProductVersion = 0u;
rawHeader.ProductBuild = 0x01010000u;
}
// ========== assign value ==========
doc->m_FileInfo.ProductVersion = rawHeader.ProductVersion;
doc->m_FileInfo.ProductBuild = rawHeader.ProductBuild;
doc->m_FileInfo.FileWriteMode = static_cast<CK_FILE_WRITEMODE>(rawHeader.FileWriteMode);
doc->m_FileInfo.CKVersion = rawHeader.CKVersion;
doc->m_FileInfo.FileVersion = rawHeader.FileVersion;
doc->m_FileInfo.FileSize = parser->GetSize();
doc->m_FileInfo.ManagerCount = rawHeader.ManagerCount;
doc->m_FileInfo.ObjectCount = rawHeader.ObjectCount;
doc->m_FileInfo.MaxIDSaved = rawHeader.MaxIDSaved;
doc->m_FileInfo.Hdr1PackSize = rawHeader.FileVersion >= 8 ? rawHeader.Hdr1PackSize : 0u;
doc->m_FileInfo.Hdr1UnPackSize = rawHeader.FileVersion >= 8 ? rawHeader.Hdr1UnPackSize : 0u;
doc->m_FileInfo.DataPackSize = rawHeader.DataPackSize;
doc->m_FileInfo.DataUnPackSize = rawHeader.DataUnPackSize;
doc->m_FileInfo.Crc = rawHeader.Crc;
// ========== crc and body unpacker ==========
if (doc->m_FileInfo.FileVersion >= 8) {
// crc checker for file ver >= 8
// reset crc field of header
rawHeader.Crc = 0u;
// compute crc
CKDWORD gotten_crc = CKComputeDataCRC(&rawHeader, sizeof(CKRawFileInfo), 0u);
parser->SetCursor(sizeof(CKRawFileInfo));
gotten_crc = CKComputeDataCRC(parser->GetPtr(), doc->m_FileInfo.Hdr1PackSize, gotten_crc);
parser->MoveCursor(doc->m_FileInfo.Hdr1PackSize);
gotten_crc = CKComputeDataCRC(parser->GetPtr(), doc->m_FileInfo.DataPackSize, gotten_crc);
if (gotten_crc != doc->m_FileInfo.Crc) {
this->m_MinCtx->Printf("Virtools file CRC error.");
return CKERROR::CKERR_FILECRCERROR;
}
// reset cursor
parser->SetCursor(sizeof(CKRawFileInfo));
// compare size to decide wheher use compress feature
void* decomp_buffer = CKUnPackData(doc->m_FileInfo.Hdr1UnPackSize, parser->GetPtr(), doc->m_FileInfo.Hdr1PackSize);
if (decomp_buffer != nullptr) {
parser = std::unique_ptr<CKBufferParser>(new(std::nothrow) CKBufferParser(decomp_buffer, doc->m_FileInfo.Hdr1UnPackSize, true));
if (parser == nullptr) {
delete[] reinterpret_cast<char*>(decomp_buffer);
return CKERROR::CKERR_OUTOFMEMORY;
}
}
}
// ========== object list read ==========
// file ver >= 7 have this features
{
// apply max id saved
doc->m_SaveIDMax = doc->m_FileInfo.MaxIDSaved;
// resize
doc->m_FileObjects.resize(doc->m_FileInfo.ObjectCount);
// read data
for (auto& fileobj : doc->m_FileObjects) {
// read basic fields
parser->Read(&(fileobj.ObjectId), sizeof(CK_ID));
parser->Read(&(fileobj.ObjectCid), sizeof(CK_CLASSID));
parser->Read(&(fileobj.FileIndex), sizeof(CKDWORD));
CKDWORD namelen;
parser->Read(&namelen, sizeof(CKDWORD));
if (namelen != 0) {
name_conv.resize(namelen);
parser->Read(name_conv.data(), namelen);
m_MinCtx->GetUtf8String(name_conv, fileobj.Name);
}
}
}
// ========== dep list read ==========
// file ver >= 8 have this feature
if (doc->m_FileInfo.FileVersion >= 8) {
// get size and resize
CKDWORD depSize;
parser->Read(&depSize, sizeof(CKDWORD));
doc->m_PluginDep.resize(depSize);
CKDWORD guid_size;
for (auto& dep : doc->m_PluginDep) {
// read category
parser->Read(&(dep.m_PluginCategory), sizeof(CK_PLUGIN_TYPE));
// get size and resize
parser->Read(&guid_size, sizeof(CKDWORD));
dep.m_Guids.resize(guid_size);
// read data
if (guid_size != 0) {
parser->Read(dep.m_Guids.data(), sizeof(CKGUID) * guid_size);
}
}
}
// ========== included file list read ==========
// file ver >= 8 have this feature
if (doc->m_FileInfo.FileVersion >= 8) {
// MARK: i don't knwo what is this!
int32_t hasIncludedFile;
parser->Read(&hasIncludedFile, sizeof(int32_t));
if (hasIncludedFile > 0) {
// read included file size and resize
CKDWORD includedFileCount;
parser->Read(&includedFileCount, sizeof(CKDWORD));
doc->m_IncludedFiles.resize(includedFileCount);
hasIncludedFile -= 4;
}
// MARK: backward pos
// backward with 0?
parser->MoveCursor(hasIncludedFile);
}
// ========== sync main parser ==========
if (doc->m_FileInfo.FileVersion >= 8) {
// file ver >= 8, use header offset
// because it have compress feature
ParserPtr->SetCursor(doc->m_FileInfo.Hdr1PackSize + sizeof(CKRawFileInfo));
} else {
// otherwise, sync with current parser.
ParserPtr->SetCursor(parser->GetCursor());
}
return CKERROR::CKERR_OK;
}
CKERROR CKFile::ReadFileData(CKBufferParser* ParserPtr, CKFileDocument* doc) {
std::unique_ptr<CKBufferParser> parser(new(std::nothrow) CKBufferParser(ParserPtr->GetBase(), ParserPtr->GetSize(), false));
if (parser == nullptr) return CKERROR::CKERR_OUTOFMEMORY;
parser->SetCursor(ParserPtr->GetCursor());
std::string name_conv;
// ========== compress feature process ==========
if (EnumsHelper::FlagEnumHas(doc->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_CHUNKCOMPRESSED_OLD) ||
EnumsHelper::FlagEnumHas(doc->m_FileInfo.FileWriteMode, CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED)) {
void* decomp_buffer = CKUnPackData(doc->m_FileInfo.DataUnPackSize, parser->GetPtr(), doc->m_FileInfo.DataPackSize);
if (decomp_buffer != nullptr) {
parser = std::unique_ptr<CKBufferParser>(new(std::nothrow) CKBufferParser(decomp_buffer, doc->m_FileInfo.DataUnPackSize, true));
if (parser == nullptr) {
delete[] reinterpret_cast<char*>(decomp_buffer);
return CKERROR::CKERR_OUTOFMEMORY;
}
}
}
// ========== old file crc and obj list read ==========
// only file ver < 8 run this
if (doc->m_FileInfo.FileVersion < 8) {
// check crc
CKDWORD gotten_crc = CKComputeDataCRC(
parser->GetPtr(),
parser->GetSize() - parser->GetCursor(),
0u
);
if (gotten_crc != doc->m_FileInfo.Crc) {
this->m_MinCtx->Printf("Virtools file CRC error.");
return CKERROR::CKERR_FILECRCERROR;
}
// MARK: why read again? especially for file ver == 7.
// get save id max
parser->Read(&doc->m_SaveIDMax, sizeof(int32_t));
// get object count and resize
parser->Read(&doc->m_FileInfo.ObjectCount, sizeof(CKDWORD));
if (doc->m_FileObjects.empty()) {
doc->m_FileObjects.resize(doc->m_FileInfo.ObjectCount);
}
}
// ========== manager read ==========
// only file ver >= 6 have this
if (doc->m_FileInfo.ManagerCount != 0) {
doc->m_FileManagersData.resize(doc->m_FileInfo.ManagerCount);
CKDWORD stateChunkLen = 0u;
bool stateChkParseSuccess = false;
for (auto& mgr : doc->m_FileManagersData) {
// read guid
parser->Read(&(mgr.Manager), sizeof(CKGUID));
// read statechunk len
parser->Read(&stateChunkLen, sizeof(CKDWORD));
// check len
if (stateChunkLen == 0) {
mgr.Data = nullptr;
continue;
}
// read statechunk
mgr.Data = new(std::nothrow) CKStateChunk(doc, this->m_MinCtx);
if (mgr.Data != nullptr) {
stateChkParseSuccess = mgr.Data->ConvertFromBuffer(parser->GetPtr());
if (!stateChkParseSuccess) {
delete mgr.Data;
mgr.Data = nullptr;
}
}
parser->MoveCursor(stateChunkLen);
}
}
// ========== object read ==========
// only works file version >= 4. < 4 section has been removed.
if (doc->m_FileInfo.ObjectCount != 0) {
// new file reader section
CKDWORD stateChunkLen = 0u;
bool stateChkParseSuccess = false;
for (auto& obj : doc->m_FileObjects) {
// get statechunk len
parser->Read(&stateChunkLen, sizeof(CKDWORD));
// check state chunk len
if (stateChunkLen == 0) {
obj.Data = nullptr;
continue;
}
// read state chunk
obj.Data = new(std::nothrow) CKStateChunk(doc, this->m_MinCtx);
if (obj.Data != nullptr) {
stateChkParseSuccess = obj.Data->ConvertFromBuffer(parser->GetPtr());
if (!stateChkParseSuccess) {
delete obj.Data;
obj.Data = nullptr;
}
}
parser->MoveCursor(stateChunkLen);
}
}
// ========== included file get ==========
// before reading, we need switch back to original parser.
// and skip data chunk size
parser = std::unique_ptr<CKBufferParser>(new(std::nothrow) CKBufferParser(ParserPtr->GetBase(), ParserPtr->GetSize(), false));
parser->MoveCursor(doc->m_FileInfo.DataPackSize);
// then we can read it.
if (doc->m_IncludedFiles.size() != 0) {
for (auto& file : doc->m_IncludedFiles) {
// get file name length and resize it
CKDWORD filenamelen = 0u;
parser->Read(&filenamelen, sizeof(CKDWORD));
name_conv.resize(filenamelen);
// read filename
if (filenamelen != 0) {
parser->Read(name_conv.data(), filenamelen);
m_MinCtx->GetUtf8String(name_conv, file);
}
// read file body length
CKDWORD filebodylen = 0u;
parser->Read(&filebodylen, sizeof(CKDWORD));
// read file body
FILE* fp = m_MinCtx->OpenTempFile(file.c_str(), false);
if (fp != nullptr) {
StreamHelper::CopyStream(parser->GetPtr(), fp, filebodylen);
fclose(fp);
}
// move to next
parser->MoveCursor(filebodylen);
}
}
return CKERROR::CKERR_OK;
}
CKERROR CKFile::DeepLoad(CKSTRING u8_filename, CKFileDocument** out_doc) {
// ========== prepare work ==========
// preset value
*out_doc = nullptr;
CKERROR err = CKERROR::CKERR_OK;
// get shallow document first
CKFileDocument* rawShallowDoc = nullptr;
err = this->ShallowLoad(u8_filename, &rawShallowDoc);
if (rawShallowDoc == nullptr) return err;
// use unique ptr wrap it as a deep doc
std::unique_ptr<CKFileDocument> deepDoc(rawShallowDoc);
if (err != CKERROR::CKERR_OK) return err;
// ========== create object first ==========
for (auto& obj : deepDoc->m_FileObjects) {
// todo: skip CK_LEVEL
// todo: resolve references
if (obj.Data == nullptr) continue;
// create object and assign created obj ckid
obj.ObjPtr = m_MinCtx->CreateCKObject(obj.ObjectId, obj.ObjectCid, obj.Name.c_str());
if (obj.ObjPtr == nullptr) {
obj.CreatedObject = 0u;
} else {
obj.CreatedObject = obj.ObjPtr->m_ID;
}
}
// ========== CKStateChunk remap ==========
// todo: remap
// todo: CK_LEVEL special proc
// ========== consume Managers ==========
// todo...
// ========== analyze objects CKStateChunk ==========
for (auto& obj : deepDoc->m_FileObjects) {
if (obj.Data == nullptr || obj.ObjPtr == nullptr) continue;
// todo: special treat for CK_LEVEL
// try parsing data
obj.Data->StartRead();
bool success = obj.ObjPtr->Load(obj.Data, deepDoc.get());
obj.Data->StopRead();
if (success) {
// if success, clear CKStateChunk*
delete obj.Data;
obj.Data = nullptr;
} else {
// if failed, delete it
m_MinCtx->DestroyCKObject(obj.ObjectId);
obj.ObjPtr = nullptr;
obj.CreatedObject = 0u;
}
}
// ========== finalize work ==========
// detach and return
*out_doc = deepDoc.release();
return CKERROR::CKERR_OK;
}
}

View File

@ -0,0 +1,7 @@
#include "CKFile.hpp"
namespace LibCmo {
}

51
LibCmo/CK2/CKGlobals.cpp Normal file
View File

@ -0,0 +1,51 @@
#include "VTUtils.hpp"
#if defined(LIBCMO_OS_WIN32)
#define ZLIB_WINAPI
#endif
#include <zconf.h>
#include "CKGlobals.hpp"
#include <zlib.h>
namespace LibCmo::CK2 {
void* CKPackData(const void* Data, CKINT size, CKINT& NewSize, CKINT compressionlevel) {
uLong boundary = compressBound(static_cast<uLong>(size));
char* DestBuffer = new char[boundary];
uLongf _destLen = static_cast<uLongf>(boundary);
if (compress2(
reinterpret_cast<Bytef*>(DestBuffer), &_destLen,
reinterpret_cast<const Bytef*>(Data), static_cast<uLong>(size),
static_cast<int>(compressionlevel)) != Z_OK) {
NewSize = 0;
delete[] DestBuffer;
return nullptr;
}
NewSize = static_cast<CKINT>(_destLen);
return DestBuffer;
}
void* CKUnPackData(CKINT DestSize, const void* SrcBuffer, CKINT SrcSize) {
char* DestBuffer = new char[DestSize];
uLongf cache = DestSize;
if (uncompress(
reinterpret_cast<Bytef*>(DestBuffer), &cache,
reinterpret_cast<const Bytef*>(SrcBuffer), SrcSize) != Z_OK) {
delete[] DestBuffer;
return nullptr;
}
return DestBuffer;
}
CKDWORD CKComputeDataCRC(const void* data, size_t size, CKDWORD PreviousCRC) {
return static_cast<CKDWORD>(adler32(
static_cast<uLong>(PreviousCRC),
reinterpret_cast<const Bytef*>(data),
static_cast<uInt>(size)
));
}
}

48
LibCmo/CK2/CKGlobals.hpp Normal file
View File

@ -0,0 +1,48 @@
#pragma once
#include "CKTypes.hpp"
namespace LibCmo::CK2 {
// ========== Compression utilities ==========
/**
* @brief Compress a buffer
* @param[in] Data A pointer to the buffer to coompress
* @param[in] size Size of the source buffer.
* @param[out] NewSize A reference that will be filled with the size of the compressed buffer. 0 if failed.
* @param[in] compressionlevel 0-9
* @return
* A pointer to the compressed buffer. nullptr if failed.
* The return pointer should be freed by `delete[]` manually.
* @remark
* The size of allocated return value may greater than the passed value of NewSize.
* NewSize only indicate the size of the part storing useful data in return value.
* @see CKUnPackData, CKComputeDataCRC
*/
void* CKPackData(const void* Data, CKINT size, CKINT& NewSize, CKINT compressionlevel);
/**
* @brief Decompress a buffer
* @param[in] DestSize Expected size of the decompressed buffer.
* @param[in] SrcBuffer Compressed buffer.
* @param[in] SrcSize Size of the compressed buffer.
* @return
* A pointer to the decompressed buffer or nullptr if there was a error.
* The return pointer should be freed by `delete[]` manually.
* @see CKPackData, CKComputeDataCRC
*/
void* CKUnPackData(CKINT DestSize, const void* SrcBuffer, CKINT SrcSize);
/**
* @brief Computes a CRC for a buffer.
* @param[in] data A pointer to the buffer to create a CRC for.
* @param[in] size Size of the source buffer.
* @param[in] PreviousCRC
* The first time a CRC is computed this value should be 0,
* but it can be use to compute a single CRC for a several buffers
* by using the currently computed CRC for previous buffers in this value.
* @return CRC of the buffer.
* @see CKPackData, CKUnPackData
*/
CKDWORD CKComputeDataCRC(const void* data, size_t size, CKDWORD PreviousCRC = 0);
}

View File

@ -0,0 +1,699 @@
#pragma once
// This file original name is Ckdefines2.hpp
// Change its name accoding to it use to
#include "../VTUtils.hpp"
#include "CKTypes.hpp"
#include <cinttypes>
#include <cstdint>
namespace LibCmo::CK2 {
constexpr const CKDWORD CK_STATESAVE_ALL = 0xFFFFFFFF;
/**
Object
*/
enum class CK_STATESAVEFLAGS_OBJECT : uint32_t {
CK_STATESAVE_NAME = 0x00000001, /**< Obsolete */
CK_STATESAVE_ID = 0x00000002, /**< Obsolete */
CK_STATESAVE_OBJECTHIDDEN = 0x00000004, /**< The object is hidden */
CK_STATESAVE_OBJECTHIERAHIDDEN = 0x00000018, /**< The object is hidden hierarchically */
CK_STATESAVE_OBJECTALL = 0x0000000F,
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_OBJECT);
/**
Be Object
*/
enum class CK_STATESAVEFLAGS_BEOBJECT : uint32_t {
CK_STATESAVE_ATTRIBUTES = 0x00000010, /**< Obsolete */
CK_STATESAVE_NEWATTRIBUTES = 0x00000011, /**< Save Attributes */
CK_STATESAVE_GROUPS = 0x00000020, /**< Obsolete */
CK_STATESAVE_DATAS = 0x00000040, /**< Save Flags and (Waiting for message) status */
CK_STATESAVE_SOUNDS = 0x00000080, /**< Obsolete */
CK_STATESAVE_BEHAVIORS = 0x00000100, /**< Obsolete */
CK_STATESAVE_PARAMETERS = 0x00000200, /**< Obsolete */
CK_STATESAVE_SINGLEACTIVITY = 0x00000400, /**< SINGLE ACTIVITY */
CK_STATESAVE_SCRIPTS = 0x00000800, /**< Obsolete */
CK_STATESAVE_BEOBJECTONLY = 0x00000FF0, /**< Save only BeObject specific datas */
CK_STATESAVE_BEOBJECTALL = 0x00000FFF, /**< Save All datas */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_BEOBJECT);
/**
3dEntity
*/
enum class CK_STATESAVEFLAGS_3DENTITY : uint32_t {
CK_STATESAVE_3DENTITYSKINDATANORMALS = 0x00001000, /**< Save Skin normals */
CK_STATESAVE_ANIMATION = 0x00002000, /**< Obsolete */
CK_STATESAVE_MESHS = 0x00004000, /**< Save List of mesh */
CK_STATESAVE_PARENT = 0x00008000, /**< Save Parent */
CK_STATESAVE_3DENTITYFLAGS = 0x00010000, /**< Save Flags */
CK_STATESAVE_3DENTITYMATRIX = 0x00020000, /**< Save Position/orientation/Scale */
CK_STATESAVE_3DENTITYHIERARCHY = 0x00040000, /**< obsolete */
CK_STATESAVE_3DENTITYPLACE = 0x00080000, /**< Save Place in which the Entity is referenced */
CK_STATESAVE_3DENTITYNDATA = 0x00100000, /**< Reserved for future use */
CK_STATESAVE_3DENTITYSKINDATA = 0x00200000, /**< Save Skin data */
CK_STATESAVE_3DENTITYONLY = 0x003FF000, /**< Save only 3dEntity specific datas */
CK_STATESAVE_3DENTITYALL = 0x003FFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_3DENTITY);
/**
Light
*/
enum class CK_STATESAVEFLAGS_LIGHT : uint32_t {
CK_STATESAVE_LIGHTDATA = 0x00400000, /**< Save Color,Type,Attenuation,Range and cone */
CK_STATESAVE_LIGHTDATA2 = 0x00800000, /**< Reserved for future use */
CK_STATESAVE_LIGHTRESERVED1 = 0x01000000, /**< Reserved for future use */
CK_STATESAVE_LIGHTRESERVED2 = 0x02000000, /**< Reserved for future use */
CK_STATESAVE_LIGHTRESERVED3 = 0x04000000, /**< Reserved for future use */
CK_STATESAVE_LIGHTRESERVED4 = 0x08000000, /**< Reserved for future use */
CK_STATESAVE_LIGHTONLY = 0x0FC00000, /**< Save only Light specific datas */
CK_STATESAVE_LIGHTALL = 0x0FFFFFFF, /**< Save All datas for sub-classes Target Light */
CK_STATESAVE_TLIGHTTARGET = 0x80000000, /**< Save Light Target */
CK_STATESAVE_TLIGHTRESERVED0 = 0x10000000, /**< Reserved for future use */
CK_STATESAVE_TLIGHTRESERVED1 = 0x20000000, /**< Reserved for future use */
CK_STATESAVE_TLIGHTRESERVED2 = 0x40000000, /**< Reserved for future use */
CK_STATESAVE_TLIGHTONLY = 0xF0000000, /**< Save only Target Light specific datas */
CK_STATESAVE_TLIGHTALL = 0xFFFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_LIGHT);
/**
Camera
*/
enum class CK_STATESAVEFLAGS_CAMERA : uint32_t {
CK_STATESAVE_CAMERAFOV = 0x00400000, /**< Save Camera Field of View */
CK_STATESAVE_CAMERAPROJTYPE = 0x00800000, /**< Save Camera projection type */
CK_STATESAVE_CAMERAOTHOZOOM = 0x01000000, /**< Save Camera orhographic zoom */
CK_STATESAVE_CAMERAASPECT = 0x02000000, /**< Save Camera aspect ration */
CK_STATESAVE_CAMERAPLANES = 0x04000000, /**< Save Camera near and far clip planes */
CK_STATESAVE_CAMERARESERVED2 = 0x08000000, /**< Reserved for future use */
CK_STATESAVE_CAMERAONLY = 0x0FC00000, /**< Save only camera specific datas */
CK_STATESAVE_CAMERAALL = 0x0FFFFFFF, /**< Save All datas for sub-classes Target Camera */
CK_STATESAVE_TCAMERATARGET = 0x10000000, /**< Save camera Target */
CK_STATESAVE_TCAMERARESERVED1 = 0x20000000, /**< Reserved for future use */
CK_STATESAVE_TCAMERARESERVED2 = 0x40000000, /**< Reserved for future use */
CK_STATESAVE_TCAMERAONLY = 0x70000000, /**< Save only Target camera specific datas */
CK_STATESAVE_TCAMERAALL = 0x7FFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_CAMERA);
/**
Sprite3D
*/
enum class CK_STATESAVEFLAGS_SPRITE3D : uint32_t {
CK_STATESAVE_SPRITE3DDATA = 0x00400000, /**< Save offset,mapping,size and material */
CK_STATESAVE_SPRITE3DRESERVED0 = 0x00800000, /**< Reserved for future use */
CK_STATESAVE_SPRITE3DRESERVED1 = 0x01000000, /**< Reserved for future use */
CK_STATESAVE_SPRITE3DRESERVED2 = 0x02000000, /**< Reserved for future use */
CK_STATESAVE_SPRITE3DRESERVED3 = 0x04000000, /**< Reserved for future use */
CK_STATESAVE_SPRITE3DRESERVED4 = 0x08000000, /**< Reserved for future use */
CK_STATESAVE_SPRITE3DONLY = 0x0FC00000, /**< Save only Sprite3D specific datas */
CK_STATESAVE_SPRITE3DALL = 0x0FFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_SPRITE3D);
/**
Object 3D
*/
enum class CK_STATESAVEFLAGS_3DOBJECT : uint32_t {
CK_STATESAVE_3DOBJECTATTRIBUTES = 0x00400000, /**< Obsolete */
CK_STATESAVE_3DOBJECTRESERVED = 0x00800000, /**< Reserved for future use */
CK_STATESAVE_3DOBJECTRONLY = 0x00C00000, /**< Save only 3dObject specific datas */
CK_STATESAVE_3DOBJECTALL = 0x03FFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_3DOBJECT);
/**
BodyPart
*/
enum class CK_STATESAVEFLAGS_BODYPART : uint32_t {
CK_STATESAVE_BODYPARTROTJOINT = 0x01000000, /**< Save rotation joint data */
CK_STATESAVE_BODYPARTPOSJOINT = 0x02000000, /**< Save position joint data */
CK_STATESAVE_BODYPARTCHARACTER = 0x04000000, /**< Save character owning this bodypart */
CK_STATESAVE_BODYPARTRESERVED1 = 0x08000000, /**< Reserved for future use */
CK_STATESAVE_BODYPARTRESERVED2 = 0x10000000, /**< Reserved for future use */
CK_STATESAVE_BODYPARTRESERVED3 = 0x20000000, /**< Reserved for future use */
CK_STATESAVE_BODYPARTRESERVED4 = 0x40000000, /**< Reserved for future use */
CK_STATESAVE_BODYPARTONLY = 0x7F000000, /**< Save only bodypart specific datas */
CK_STATESAVE_BODYPARTALL = 0x7FFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_BODYPART);
/**
Character
*/
enum class CK_STATESAVEFLAGS_CHARACTER : uint32_t {
CK_STATESAVE_CHARACTERBODYPARTS = 0x00400000, /**< Obsolete */
CK_STATESAVE_CHARACTERKINECHAINS = 0x00800000, /**< Obsolete */
CK_STATESAVE_CHARACTERANIMATIONS = 0x01000000, /**< Obsolete */
CK_STATESAVE_CHARACTERROOT = 0x02000000, /**< Obsolete */
CK_STATESAVE_CHARACTERSAVEANIMS = 0x04000000, /**< Save current and next active animations */
CK_STATESAVE_CHARACTERSAVECHAINS = 0x08000000, /**< Obsolete */
CK_STATESAVE_CHARACTERSAVEPARTS = 0x10000000, /**< Save sub bodyparts and sub-bodyparts data (saved with flag :CK_STATESAVE_BODYPARTALL) */
CK_STATESAVE_CHARACTERFLOORREF = 0x20000000, /**< Save Character floor reference object */
CK_STATESAVE_CHARACTERRESERVED2 = 0x40000000, /**< Reserved for future use */
CK_STATESAVE_CHARACTERRESERVED3 = 0x80000000, /**< Reserved for future use */
CK_STATESAVE_CHARACTERONLY = 0xFFC00000, /**< Save only character specific datas */
CK_STATESAVE_CHARACTERALL = 0xFFFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_CHARACTER);
/**
CURVE && Curve Point
*/
enum class CK_STATESAVEFLAGS_CURVE : uint32_t {
CK_STATESAVE_CURVEFITCOEFF = 0x00400000, /**< Save fitting coef */
CK_STATESAVE_CURVECONTROLPOINT = 0x00800000, /**< Save list of control points */
CK_STATESAVE_CURVESTEPS = 0x01000000, /**< Save number of step setting */
CK_STATESAVE_CURVEOPEN = 0x02000000, /**< Save Open/Close flag */
CK_STATESAVE_CURVERESERVED1 = 0x04000000, /**< Reserved for future use */
CK_STATESAVE_CURVERESERVED2 = 0x08000000, /**< Reserved for future use Control points */
CK_STATESAVE_CURVEPOINTDEFAULTDATA = 0x10000000, /**< Save Control point setting and position */
CK_STATESAVE_CURVEPOINTTCB = 0x20000000, /**< Save Control point tcb settings */
CK_STATESAVE_CURVEPOINTTANGENTS = 0x40000000, /**< Save Control point tangents */
CK_STATESAVE_CURVEPOINTCURVEPOS = 0x80000000, /**< Save Control point position in curve */
CK_STATESAVE_CURVESAVEPOINTS = 0xFF000000, /**< Save control points data */
CK_STATESAVE_CURVEONLY = 0xFFC00000, /**< Save only curve specific data */
CK_STATESAVE_CURVEALL = 0xFFFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_CURVE);
/**
2dEntity
*/
enum class CK_STATESAVEFLAGS_2DENTITY : uint32_t {
CK_STATESAVE_2DENTITYSRCSIZE = 0x00001000, /**< Save source size */
CK_STATESAVE_2DENTITYSIZE = 0x00002000, /**< Save size */
CK_STATESAVE_2DENTITYFLAGS = 0x00004000, /**< Save Flags */
CK_STATESAVE_2DENTITYPOS = 0x00008000, /**< Save position */
CK_STATESAVE_2DENTITYZORDER = 0x00100000, /**< Save Z order */
CK_STATESAVE_2DENTITYONLY = 0x0010F000, /**< Save only 2dEntity specific data */
CK_STATESAVE_2DENTITYMATERIAL = 0x00200000, /**< Save Material */
CK_STATESAVE_2DENTITYHIERARCHY = 0x00400000, /**< Save Material */
CK_STATESAVE_2DENTITYALL = 0x0070FFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_2DENTITY);
/**
Sprite
*/
enum class CK_STATESAVEFLAGS_SPRITE : uint32_t {
CK_STATESAVE_SPRITECURRENTIMAGE = 0x00010000, /**< Save current image */
CK_STATESAVE_SPRITETRANSPARENT = 0x00020000, /**< Save transparency settings */
CK_STATESAVE_SPRITEBITMAPS = 0x00040000, /**< Obsolete */
CK_STATESAVE_SPRITESHARED = 0x00080000, /**< Save shared sprite */
CK_STATESAVE_SPRITEDONOTUSE = 0x00100000, /**< Reseved by CK_STATESAVEFLAGS_2DENTITY */
CK_STATESAVE_SPRITEAVIFILENAME = 0x00200000, /**< Obsolete */
CK_STATESAVE_SPRITEFILENAMES = 0x00400000, /**< Obsolete */
CK_STATESAVE_SPRITECOMPRESSED = 0x00800000, /**< Obsolete */
CK_STATESAVE_SPRITEREADER = 0x10000000, /**< Reserved for future use */
CK_STATESAVE_SPRITEFORMAT = 0x20000000, /**< Reserved for future use */
CK_STATESAVE_SPRITEVIDEOFORMAT = 0x40000000, /**< Video Format */
CK_STATESAVE_SPRITESYSTEMCACHING = 0x80000000, /**< System Memory Caching */
CK_STATESAVE_SPRITERENDEROPTIONS = 0x80800000, /**< Render options if any... */
CK_STATESAVE_SPRITEONLY = 0xF0EF0000, /**< Save only sprite specific data */
CK_STATESAVE_SPRITEALL = 0x70FFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_SPRITE);
/**
Sprite Text
*/
enum class CK_STATESAVEFLAGS_SPRITETEXT : uint32_t {
CK_STATESAVE_SPRITETEXT = 0x01000000, /**< Save text */
CK_STATESAVE_SPRITEFONT = 0x02000000, /**< Save font settings */
CK_STATESAVE_SPRITETEXTCOLOR = 0x04000000, /**< Save text color */
CK_STATESAVE_SPRITETEXTRESERVED = 0x08000000, /**< Reserved for future use */
CK_STATESAVE_SPRITETEXTDOTNOTUSE = 0x10000000, /**< Reserved by CK_STATESAVE_SPRITEREADER */
CK_STATESAVE_SPRITETEXTDONOTUSED2 = 0x20000000, /**< Reserved by CK_STATESAVE_SPRITEFORMAT */
CK_STATESAVE_SPRITETEXTONLY = 0x0F000000, /**< Save only SpriteText specific data */
CK_STATESAVE_SPRITETEXTALL = 0x3FFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_SPRITETEXT);
/**
Sound
*/
enum class CK_STATESAVEFLAGS_SOUND : uint32_t {
CK_STATESAVE_SOUNDFILENAME = 0x00001000, /**< Reserved for future use */
CK_STATESAVE_SOUNDRESERVED1 = 0x00002000, /**< Reserved for future use */
CK_STATESAVE_SOUNDRESERVED2 = 0x00004000, /**< Reserved for future use */
CK_STATESAVE_SOUNDRESERVED3 = 0x00008000, /**< Reserved for future use */
CK_STATESAVE_SOUNDRESERVED4 = 0x00010000, /**< Reserved for future use */
CK_STATESAVE_SOUNDRESERVED5 = 0x00020000, /**< Reserved for future use */
CK_STATESAVE_SOUNDRESERVED6 = 0x00040000, /**< Reserved for future use */
CK_STATESAVE_SOUNDRESERVED7 = 0x00080000, /**< Reserved for future use */
CK_STATESAVE_SOUNDONLY = 0x000FF000, /**< Save only Sound specific data */
CK_STATESAVE_SOUNDALL = 0x000FFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_SOUND);
/**
Wave Sound
*/
enum class CK_STATESAVEFLAGS_WAVSOUND : uint32_t {
CK_STATESAVE_WAVSOUNDFILE = 0x00100000, /**< Save sound filename */
CK_STATESAVE_WAVSOUNDDATA = 0x00200000, /**< Obsolete */
CK_STATESAVE_WAVSOUNDDATA2 = 0x00400000, /**< Save sound properties (3D/2D,pitch,gain,streaming,loop,etc..) */
CK_STATESAVE_WAVSOUNDDURATION = 0x00800000, /**< Sound Length (in case it cannot be calculated latter) */
CK_STATESAVE_WAVSOUNDRESERVED4 = 0x01000000, /**< Reserved for future use */
CK_STATESAVE_WAVSOUNDRESERVED5 = 0x02000000, /**< Reserved for future use */
CK_STATESAVE_WAVSOUNDRESERVED6 = 0x04000000, /**< Reserved for future use */
CK_STATESAVE_WAVSOUNDRESERVED7 = 0x08000000, /**< Reserved for future use */
CK_STATESAVE_WAVSOUNDONLY = 0x0FF00000, /**< Save All datas for sub-classes */
CK_STATESAVE_WAVSOUNDALL = 0x0FFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_WAVSOUND);
/**
Wave Sound
*/
enum class CK_STATESAVEFLAGS_MIDISOUND : uint32_t {
CK_STATESAVE_MIDISOUNDFILE = 0x00100000, /**< Save sound filename */
CK_STATESAVE_MIDISOUNDDATA = 0x00200000, /**< Save midi data */
CK_STATESAVE_MIDISOUNDRESERVED2 = 0x00400000, /**< Reserved for future use */
CK_STATESAVE_MIDISOUNDRESERVED3 = 0x00800000, /**< Reserved for future use */
CK_STATESAVE_MIDISOUNDRESERVED4 = 0x01000000, /**< Reserved for future use */
CK_STATESAVE_MIDISOUNDRESERVED5 = 0x02000000, /**< Reserved for future use */
CK_STATESAVE_MIDISOUNDRESERVED6 = 0x04000000, /**< Reserved for future use */
CK_STATESAVE_MIDISOUNDRESERVED7 = 0x08000000, /**< Reserved for future use */
CK_STATESAVE_MIDISOUNDONLY = 0x0FF00000,
CK_STATESAVE_MIDISOUNDALL = 0x0FFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_MIDISOUND);
/**
Place
*/
enum class CK_STATESAVEFLAGS_PLACE : uint32_t {
CK_STATESAVE_PLACEPORTALS = 0x00001000, /**< Save level using the place */
CK_STATESAVE_PLACECAMERA = 0x00002000, /**< Save attached camera */
CK_STATESAVE_PLACEREFERENCES = 0x00004000, /**< Save list of objects in the place */
CK_STATESAVE_PLACELEVEL = 0x00008000, /**< Save level using the place */
CK_STATESAVE_PLACEALL = 0x0000FFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_PLACE);
/**
Level CKSaveObjectState will not save any data
*/
enum class CK_STATESAVEFLAGS_LEVEL : uint32_t {
CK_STATESAVE_LEVELRESERVED0 = 0x00001000, /**< Reserved for future use */
CK_STATESAVE_LEVELINACTIVEMAN = 0x00002000, /**< Reserved for future use */
CK_STATESAVE_LEVELDUPLICATEMAN = 0x00004000, /**< Reserved for future use */
CK_STATESAVE_LEVELDEFAULTDATA = 0x20000000, /**< Save Places,Scenes and Objects */
CK_STATESAVE_LEVELSCENE = 0x80000000, /**< Default and active scene */
CK_STATESAVE_LEVELALL = 0xFFFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_LEVEL);
/**
GROUP
*/
enum class CK_STATESAVEFLAGS_GROUP : uint32_t {
CK_STATESAVE_GROUPDATA = 0x00001000, /**< Save list of objects in the group */
CK_STATESAVE_GROUPRESERVED1 = 0x00002000, /**< Reserved for future use */
CK_STATESAVE_GROUPRESERVED2 = 0x00004000, /**< Reserved for future use */
CK_STATESAVE_GROUPRESERVED3 = 0x00008000, /**< Reserved for future use */
CK_STATESAVE_GROUPRESERVED4 = 0x00010000, /**< Reserved for future use */
CK_STATESAVE_GROUPRESERVED5 = 0x00020000, /**< Reserved for future use */
CK_STATESAVE_GROUPRESERVED6 = 0x00040000, /**< Reserved for future use */
CK_STATESAVE_GROUPRESERVED7 = 0x00080000, /**< Reserved for future use */
CK_STATESAVE_GROUPALL = 0x000FFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_GROUP);
/**
MESH CKSaveOjectSave will save all data and does not take flags into account
*/
enum class CK_STATESAVEFLAGS_MESH : uint32_t {
CK_STATESAVE_MESHRESERVED0 = 0x00001000, /**< Reserved for future use */
CK_STATESAVE_MESHFLAGS = 0x00002000, /**< Save flags */
CK_STATESAVE_MESHCHANNELS = 0x00004000, /**< Save Channels */
CK_STATESAVE_MESHFACECHANMASK = 0x00008000, /**< Save face channel Mask */
CK_STATESAVE_MESHFACES = 0x00010000, /**< Save face data */
CK_STATESAVE_MESHVERTICES = 0x00020000, /**< Save geometry */
CK_STATESAVE_MESHLINES = 0x00040000, /**< Save line data */
CK_STATESAVE_MESHWEIGHTS = 0x00080000, /**< Save Vertex Weight info */
CK_STATESAVE_MESHMATERIALS = 0x00100000, /**< Reserved for future use */
CK_STATESAVE_MESHRESERVED1 = 0x00200000, /**< Reserved for future use */
CK_STATESAVE_MESHRESERVED2 = 0x00400000, /**< Reserved for future use */
CK_STATESAVE_PROGRESSIVEMESH = 0x00800000, /**< Save All datas for sub-classes */
CK_STATESAVE_MESHONLY = 0x00FFF000, /**< Save All datas for sub-classes */
CK_STATESAVE_MESHALL = 0x00FFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_MESH);
/**
PATCH MESH CKSaveOjectSave will save all data and does not take flags into account
*/
enum class CK_STATESAVEFLAGS_PATCHMESH : uint32_t {
CK_STATESAVE_PATCHMESHDATA = 0x00800000, /**< Obsolete */
CK_STATESAVE_PATCHMESHDATA2 = 0x01000000, /**< Obsolete */
CK_STATESAVE_PATCHMESHSMOOTH = 0x02000000, /**< Obsolete */
CK_STATESAVE_PATCHMESHMATERIALS = 0x04000000, /**< Obsolete */
CK_STATESAVE_PATCHMESHDATA3 = 0x08000000, /**< Save Patch Data */
CK_STATESAVE_PATCHMESHONLY = 0x0FF00000, /**< Save All datas for sub-classes */
CK_STATESAVE_PATCHMESHALL = 0x0FFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_PATCHMESH);
/**
Material
*/
enum class CK_STATESAVEFLAGS_MATERIAL : uint32_t {
CK_STATESAVE_MATDATA = 0x00001000, /**< Save colors,blending modes,shade modes,fill modes etc... */
CK_STATESAVE_MATDATA2 = 0x00002000, /**< Additional texture objects... */
CK_STATESAVE_MATDATA3 = 0x00004000, /**< Effect Alone */
CK_STATESAVE_MATDATA4 = 0x00008000, /**< none */
CK_STATESAVE_MATDATA5 = 0x00010000, /**< Effect + parameter */
CK_STATESAVE_MATRESERVED5 = 0x00020000, /**< Reserved for future use */
CK_STATESAVE_MATRESERVED6 = 0x00040000, /**< Reserved for future use */
CK_STATESAVE_MATRESERVED7 = 0x00080000, /**< Reserved for future use */
CK_STATESAVE_MATERIALONLY = 0x000FF000, /**< Save All datas for sub-classes */
CK_STATESAVE_MATERIALALL = 0x0FFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_MATERIAL);
/**
Texture CKSaveOjectSave will save all relevant data and does not take flags into account
*/
enum class CK_STATESAVEFLAGS_TEXTURE : uint32_t {
CK_STATESAVE_TEXAVIFILENAME = 0x00001000, /**< Save movie file name */
CK_STATESAVE_TEXCURRENTIMAGE = 0x00002000, /**< Save current slot */
CK_STATESAVE_TEXBITMAPS = 0x00004000, /**< Obsolete */
CK_STATESAVE_TEXTRANSPARENT = 0x00008000, /**< Save transparency data */
CK_STATESAVE_TEXFILENAMES = 0x00010000, /**< Save texture slot filenames */
CK_STATESAVE_TEXCOMPRESSED = 0x00020000, /**< Save raw texture data */
CK_STATESAVE_TEXVIDEOFORMAT = 0x00040000, /**< Save chosen video format */
CK_STATESAVE_TEXSAVEFORMAT = 0x00080000, /**< Save chosen save format */
CK_STATESAVE_TEXREADER = 0x00100000, /**< Save texture data using a specific BitmapReader */
CK_STATESAVE_PICKTHRESHOLD = 0x00200000, /**< Save pick threshold */
CK_STATESAVE_USERMIPMAP = 0x00400000, /**< User mipmap levels */
CK_STATESAVE_TEXSYSTEMCACHING = 0x00800000, /**< System Memory Caching */
CK_STATESAVE_OLDTEXONLY = 0x002FF000, /**< Kept for compatibility */
CK_STATESAVE_TEXONLY = 0x00FFF000, /**< Save Only Texture Data (Dot NOT MODIFY ! Texture loading/saving relies on this value) */
CK_STATESAVE_TEXALL = 0x002FFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_TEXTURE);
/**
2d CURVE && 2d Curve Point
*/
enum class CK_STATESAVEFLAGS_2DCURVE : uint32_t {
CK_STATESAVE_2DCURVERESERVED0 = 0x00000010, /**< Reserved for future use */
CK_STATESAVE_2DCURVERESERVED4 = 0x00000020, /**< Reserved for future use */
CK_STATESAVE_2DCURVEFITCOEFF = 0x00000040, /**< Obsolete */
CK_STATESAVE_2DCURVECONTROLPOINT = 0x00000080, /**< Obsolete */
CK_STATESAVE_2DCURVENEWDATA = 0x00000100, /**< Save All relevant data */
CK_STATESAVE_2DCURVERESERVED2 = 0x00000200, /**< Obsolete */
CK_STATESAVE_2DCURVERESERVED3 = 0x00000400, /**< Obsolete */
CK_STATESAVE_2DCURVEPOINTTCB = 0x00000800, /**< Obsolete */
CK_STATESAVE_2DCURVEPOINTTANGENTS = 0x00001000, /**< Obsolete */
CK_STATESAVE_2DCURVEPOINT2DCURVEPOS = 0x00002000, /**< Obsolete */
CK_STATESAVE_2DCURVEPOINTDEFAULTDATA = 0x00004000, /**< Obsolete */
CK_STATESAVE_2DCURVEPOINTNEWDATA = 0x00008000, /**< Save All relevant data */
CK_STATESAVE_2DCURVEPOINTRESERVED1 = 0x00010000, /**< Reserved for future use */
CK_STATESAVE_2DCURVEPOINTRESERVED2 = 0x00020000, /**< Reserved for future use */
CK_STATESAVE_2DCURVESAVEPOINTS = 0x0003F800, /**< Obsolete */
CK_STATESAVE_2DCURVEALL = 0x0007FFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_2DCURVE);
/**
Kinematic Chain
*/
enum class CK_STATESAVEFLAGS_KINEMATICCHAIN : uint32_t {
CK_STATESAVE_KINEMATICCHAINDATA = 0x00000010, /**< Save chain data */
CK_STATESAVE_KINEMATICCHAINRESERVED1 = 0x00000020, /**< Reserved for future use */
CK_STATESAVE_KINEMATICCHAINRESERVED2 = 0x00000040, /**< Reserved for future use */
CK_STATESAVE_KINEMATICCHAINRESERVED3 = 0x00000080, /**< Reserved for future use */
CK_STATESAVE_KINEMATICCHAINALL = 0x000000FF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_KINEMATICCHAIN);
/**
Animation
*/
enum class CK_STATESAVEFLAGS_ANIMATION : uint32_t {
CK_STATESAVE_ANIMATIONDATA = 0x00000010, /**< Save Flags & Framerate data */
CK_STATESAVE_ANIMATIONRESERVED1 = 0x00000020, /**< Reserved for future use */
CK_STATESAVE_ANIMATIONLENGTH = 0x00000040, /**< Save animation Length */
CK_STATESAVE_ANIMATIONBODYPARTS = 0x00000080, /**< Save root & list of bodypart */
CK_STATESAVE_ANIMATIONCHARACTER = 0x00000100, /**< Save character */
CK_STATESAVE_ANIMATIONCURRENTSTEP = 0x00000200, /**< Save current step */
CK_STATESAVE_ANIMATIONRESERVED5 = 0x00000400, /**< Reserved for future use */
CK_STATESAVE_ANIMATIONRESERVED6 = 0x00000800, /**< Reserved for future use */
CK_STATESAVE_ANIMATIONALL = 0x0FFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_ANIMATION);
/**
Keyed Anim
*/
enum class CK_STATESAVEFLAGS_KEYEDANIMATION : uint32_t {
CK_STATESAVE_KEYEDANIMANIMLIST = 0x00001000, /**< Save list of object animations */
CK_STATESAVE_KEYEDANIMLENGTH = 0x00002000, /**< Obsolete */
CK_STATESAVE_KEYEDANIMPOSKEYS = 0x00004000, /**< Obsolete */
CK_STATESAVE_KEYEDANIMROTKEYS = 0x00008000, /**< Obsolete */
CK_STATESAVE_KEYEDANIMMORPHKEYS = 0x00010000, /**< Obsolete */
CK_STATESAVE_KEYEDANIMSCLKEYS = 0x00020000, /**< Obsolete */
CK_STATESAVE_KEYEDANIMFLAGS = 0x00040000, /**< Obsolete */
CK_STATESAVE_KEYEDANIMENTITY = 0x00080000, /**< Obsolete */
CK_STATESAVE_KEYEDANIMMERGE = 0x00100000, /**< Save merged animations */
CK_STATESAVE_KEYEDANIMSUBANIMS = 0x00200000, /**< Save object animations data (using same flags than CKSaveObjectState) */
CK_STATESAVE_KEYEDANIMRESERVED0 = 0x00400000, /**< Reserved for future use */
CK_STATESAVE_KEYEDANIMRESERVED1 = 0x00800000, /**< Reserved for future use */
CK_STATESAVE_KEYEDANIMRESERVED2 = 0x01000000, /**< Reserved for future use */
CK_STATESAVE_KEYEDANIMRESERVED3 = 0x02000000, /**< Reserved for future use */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_KEYEDANIMATION);
/**
Object Animation CKSaveOjectSave will save all relevant data and does not take flags into account
*/
enum class CK_STATESAVEFLAGS_OBJECTANIMATION : uint32_t {
CK_STATESAVE_OBJANIMNEWDATA = 0x00001000, /**< Save all relevant data */
CK_STATESAVE_OBJANIMLENGTH = 0x00002000, /**< Not used */
CK_STATESAVE_OBJANIMPOSKEYS = 0x00004000, /**< Not used */
CK_STATESAVE_OBJANIMROTKEYS = 0x00008000, /**< Not used */
CK_STATESAVE_OBJANIMMORPHKEYS = 0x00010000, /**< Not used */
CK_STATESAVE_OBJANIMSCLKEYS = 0x00020000, /**< Not used */
CK_STATESAVE_OBJANIMFLAGS = 0x00040000, /**< Not used */
CK_STATESAVE_OBJANIMENTITY = 0x00080000, /**< Not used */
CK_STATESAVE_OBJANIMMERGE = 0x00100000, /**< Not used */
CK_STATESAVE_OBJANIMMORPHKEYS2 = 0x00200000, /**< Not used */
CK_STATESAVE_OBJANIMNEWSAVE1 = 0x00400000, /**< Not used */
CK_STATESAVE_OBJANIMMORPHNORMALS = 0x00800000, /**< Not used (Virtools 1.1) */
CK_STATESAVE_OBJANIMMORPHCOMP = 0x01000000, /**< Not used (Virtools 1.1) */
CK_STATESAVE_OBJANIMSHARED = 0x02000000, /**< Save Data for a shared animation */
CK_STATESAVE_OBJANIMCONTROLLERS = 0x04000000, /**< (Virtools 1.5) Save All Controller information */
CK_STATESAVE_OBJANIMONLY = 0x07FFF000,
CK_STATESAVE_OBJANIMALL = 0x07FFFFFF,
CK_STATESAVE_KEYEDANIMONLY = 0x03FFF000, /**< Save All datas for sub-classes */
CK_STATESAVE_KEYEDANIMALL = 0x03FFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_OBJECTANIMATION);
/**
IK Animation
*/
enum class CK_STATESAVEFLAGS_IKANIMATION : uint32_t {
CK_STATESAVE_IKANIMATIONDATA = 0x00001000, /**< Save IK data */
CK_STATESAVE_IKANIMATIONRESERVED2 = 0x00002000, /**< Reserved for future use */
CK_STATESAVE_IKANIMATIONRESERVED3 = 0x00004000, /**< Reserved for future use */
CK_STATESAVE_IKANIMATIONRESERVED4 = 0x00008000, /**< Reserved for future use */
CK_STATESAVE_IKANIMATIONRESERVED5 = 0x00010000, /**< Reserved for future use */
CK_STATESAVE_IKANIMATIONRESERVED6 = 0x00020000, /**< Reserved for future use */
CK_STATESAVE_IKANIMATIONRESERVED7 = 0x00040000, /**< Reserved for future use */
CK_STATESAVE_IKANIMATIONRESERVED8 = 0x00100000, /**< Reserved for future use */
CK_STATESAVE_IKANIMATIONRESERVED9 = 0x00200000, /**< Reserved for future use */
CK_STATESAVE_IKANIMATIONALL = 0x003FFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_IKANIMATION);
/**
BehaviorLink
*/
enum class CK_STATESAVEFLAGS_BEHAV_LINK : uint32_t {
CK_STATESAVE_BEHAV_LINK_CURDELAY = 0x00000004, /**< Obsolete */
CK_STATESAVE_BEHAV_LINK_IOS = 0x00000008, /**< Obsolete */
CK_STATESAVE_BEHAV_LINK_DELAY = 0x00000010, /**< Obsolete */
CK_STATESAVE_BEHAV_LINK_NEWDATA = 0x00000020, /**< Save all relevant data (In,Out,Activation delay) */
CK_STATESAVE_BEHAV_LINKRESERVED5 = 0x00000040, /**< Reserved for future use */
CK_STATESAVE_BEHAV_LINKRESERVED6 = 0x00000080, /**< Reserved for future use */
CK_STATESAVE_BEHAV_LINKONLY = 0x000000F0, /**< */
CK_STATESAVE_BEHAV_LINKALL = 0x000000FF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_BEHAV_LINK);
/**
BehaviorIO
*/
enum class CK_STATESAVEFLAGS_BEHAV_IO : uint32_t {
CK_STATESAVE_BEHAV_IOFLAGS = 0x00000008, /**< Save IO flags */
CK_STATESAVE_BEHAV_IORESERVED3 = 0x00000010, /**< Reserved for future use */
CK_STATESAVE_BEHAV_IORESERVED4 = 0x00000020, /**< Reserved for future use */
CK_STATESAVE_BEHAV_IORESERVED5 = 0x00000040, /**< Reserved for future use */
CK_STATESAVE_BEHAV_IORESERVED6 = 0x00000080, /**< Reserved for future use */
CK_STATESAVE_BEHAVIOONLY = 0x000000F0, /**< */
CK_STATESAVE_BEHAVIOALL = 0x000000FF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_BEHAV_IO);
/**
BehaviorPrototype
*/
enum class CK_STATESAVEFLAGS_PROTOTYPE : uint32_t {
CK_STATESAVE_PROTORESERVED0 = 0x00000010, /**< Reserved for future use */
CK_STATESAVE_PROTORESERVED1 = 0x00000020, /**< Reserved for future use */
CK_STATESAVE_PROTOFLAGS = 0x00000040, /**< Save Flags */
CK_STATESAVE_PROTOSUBPROTOS = 0x00000080, /**< Save sub prototypes */
CK_STATESAVE_PROTOLINKS = 0x00000100, /**< Save links */
CK_STATESAVE_PROTOBEHAVFLAG = 0x00000200, /**< Save behavior flags */
CK_STATESAVE_PROTOGUID = 0x00000400, /**< Save GUID */
CK_STATESAVE_PROTOINPUTS = 0x00000800, /**< Save inputs */
CK_STATESAVE_PROTOOUTPUTS = 0x00001000, /**< Save outputs */
CK_STATESAVE_PROTOINPARAMS = 0x00002000, /**< Save input parameters */
CK_STATESAVE_PROTOOUTPARAMS = 0x00004000, /**< Save output parameters */
CK_STATESAVE_PROTOLOCALPARAMS = 0x00008000, /**< Save local parameters */
CK_STATESAVE_PROTOOPERATIONS = 0x00010000, /**< Save parameter operations */
CK_STATESAVE_PROTOPARAMETERLINKS = 0x00020000, /**< Save parameter links */
CK_STATESAVE_PROTOAPPLYTO = 0x00040000, /**< Save ClassID of object to which it applies */
CK_STATESAVE_PROTORESERVED14 = 0x00080000, /**< Reserved for future use */
CK_STATESAVE_PROTOALL = 0x000FFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_PROTOTYPE);
/**
Behavior
*/
enum class CK_STATESAVEFLAGS_BEHAVIOR : uint32_t {
CK_STATESAVE_BEHAVIORRESERVED0 = 0x00000010, /**< Reserved for internal use */
CK_STATESAVE_BEHAVIORNEWDATA = 0x00000020, /**< not used */
CK_STATESAVE_BEHAVIORFLAGS = 0x00000040, /**< not used */
CK_STATESAVE_BEHAVIORCOMPATIBLECID = 0x00000080, /**< not used */
CK_STATESAVE_BEHAVIORSUBBEHAV = 0x00000100, /**< Save Sub-Behaviors */
CK_STATESAVE_BEHAVIORINPARAMS = 0x00000200, /**< not used */
CK_STATESAVE_BEHAVIOROUTPARAMS = 0x00000400, /**< not used */
CK_STATESAVE_BEHAVIORINPUTS = 0x00000800, /**< not used */
CK_STATESAVE_BEHAVIOROUTPUTS = 0x00001000, /**< not used */
CK_STATESAVE_BEHAVIORINFO = 0x00002000, /**< not used */
CK_STATESAVE_BEHAVIOROPERATIONS = 0x00004000, /**< not used */
CK_STATESAVE_BEHAVIORTYPE = 0x00008000, /**< not used */
CK_STATESAVE_BEHAVIOROWNER = 0x00010000, /**< not used */
CK_STATESAVE_BEHAVIORLOCALPARAMS = 0x00020000, /**< Save local parameters */
CK_STATESAVE_BEHAVIORPROTOGUID = 0x00040000, /**< not used */
CK_STATESAVE_BEHAVIORSUBLINKS = 0x00080000, /**< not used */
CK_STATESAVE_BEHAVIORACTIVESUBLINKS = 0x00100000, /**< not used */
CK_STATESAVE_BEHAVIORSINGLEACTIVITY = 0x00200000, /**< SINGLE ACTIVITY */
CK_STATESAVE_BEHAVIORSCRIPTDATA = 0x00400000, /**< not used */
CK_STATESAVE_BEHAVIORPRIORITY = 0x00800000, /**< not used */
CK_STATESAVE_BEHAVIORTARGET = 0x01000000, /**< not used */
CK_STATESAVE_BEHAVIORONLY = 0x01FFFFF0,
CK_STATESAVE_BEHAVIORALL = 0x01FFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_BEHAVIOR);
/**
SCENE CKSaveOjectSave will save all relevant data and does not take flags into account
*/
enum class CK_STATESAVEFLAGS_SCENE : uint32_t {
CK_STATESAVE_SCENERESERVED0 = 0x00001000, /**< Reserved for future use */
CK_STATESAVE_SCENERESERVED8 = 0x00002000, /**< Reserved for future use */
CK_STATESAVE_SCENEFLAGS = 0x00004000,
CK_STATESAVE_SCENELEVEL = 0x00008000,
CK_STATESAVE_SCENEOBJECTS = 0x00010000,
CK_STATESAVE_SCENENEWDATA = 0x00020000, /**< every object description and initial conditions */
CK_STATESAVE_SCENELAUNCHED = 0x00040000, /**< Scene was already launched once */
CK_STATESAVE_SCENERENDERSETTINGS = 0x00080000, /**< Background Color, Fog Color etc.. */
CK_STATESAVE_SCENERESERVED1 = 0x00100000, /**< Reserved for future use */
CK_STATESAVE_SCENERESERVED2 = 0x00200000, /**< Reserved for future use */
CK_STATESAVE_SCENERESERVED3 = 0x00400000, /**< Reserved for future use */
CK_STATESAVE_SCENERESERVED4 = 0x00800000, /**< Reserved for future use */
CK_STATESAVE_SCENERESERVED5 = 0x01000000, /**< Reserved for future use */
CK_STATESAVE_SCENERESERVED12 = 0x02000000, /**< Reserved for future use */
CK_STATESAVE_SCENERESERVED13 = 0x04000000, /**< Reserved for future use */
CK_STATESAVE_SCENERESERVED14 = 0x08000000, /**< Reserved for future use */
CK_STATESAVE_SCENEALL = 0x0FFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_SCENE);
/**
ParameterIn
*/
enum class CK_STATESAVEFLAGS_PARAMETERIN : uint32_t {
CK_STATESAVE_PARAMETERIN_RESERVED4 = 0x00000010, /**< Reserved for future use */
CK_STATESAVE_PARAMETERIN_RESERVED0 = 0x00000020, /**< Reserved for future use */
CK_STATESAVE_PARAMETERIN_RESERVED1 = 0x00000040, /**< Reserved for future use */
CK_STATESAVE_PARAMETERIN_OWNER = 0x00000080, /**< Obsolete */
CK_STATESAVE_PARAMETERIN_INSHARED = 0x00000100, /**< Obsolete */
CK_STATESAVE_PARAMETERIN_OUTSOURCE = 0x00000200, /**< Obsolete */
CK_STATESAVE_PARAMETERIN_DEFAULTDATA = 0x00000400, /**< Obsolete */
CK_STATESAVE_PARAMETERIN_DATASHARED = 0x00000800, /**< Save reference to shared inparameter */
CK_STATESAVE_PARAMETERIN_DATASOURCE = 0x00001000, /**< Save reference to source outparameter */
CK_STATESAVE_PARAMETERIN_DISABLED = 0x00002000, /**< The parameter was disabled */
CK_STATESAVE_PARAMETERIN_ALL = 0x0000FFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_PARAMETERIN);
/**
ParameterLocal et ParameterOut
*/
enum class CK_STATESAVEFLAGS_PARAMETEROUT : uint32_t {
CK_STATESAVE_PARAMETEROUT_RESERVED0 = 0x00000010, /**< Reserved for future use */
CK_STATESAVE_PARAMETEROUT_DESTINATIONS = 0x00000020, /**< Save destinations */
CK_STATESAVE_PARAMETEROUT_VAL = 0x00000040, /**< Save value */
CK_STATESAVE_PARAMETEROUT_OWNER = 0x00000080, /**< Save Owner */
CK_STATESAVE_PARAMETEROUT_MYSELF = 0x00000200, /**< */
CK_STATESAVE_PARAMETEROUT_ISSETTING = 0x00000400, /**< Reserved for future use */
CK_STATESAVE_PARAMETEROUT_ALL = 0x0000FFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_PARAMETEROUT);
/**
Parameter Operation
*/
enum class CK_STATESAVEFLAGS_OPERATION : uint32_t {
CK_STATESAVE_OPERATIONRESERVED0 = 0x00000010, /**< Reserved for future use */
CK_STATESAVE_OPERATIONRESERVED1 = 0x00000020, /**< Reserved for future use */
CK_STATESAVE_OPERATIONINPUTS = 0x00000040,
CK_STATESAVE_OPERATIONOUTPUT = 0x00000080,
CK_STATESAVE_OPERATIONOP = 0x00000100,
CK_STATESAVE_OPERATIONDEFAULTDATA = 0x00000200,
CK_STATESAVE_OPERATIONNEWDATA = 0x00000400,
CK_STATESAVE_OPERATIONALL = 0x000007FF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_OPERATION);
/**
Synchro Object CKSaveOjectSave will save all relevant data and does not take flags into account
*/
enum class CK_STATESAVEFLAGS_SYNCHRO : uint32_t {
CK_STATESAVE_SYNCHRODATA = 0x00000010, /**< Save data */
CK_STATESAVE_SYNCHRORESERVED0 = 0x00000040, /**< Reserved for future use */
CK_STATESAVE_SYNCHRORESERVED1 = 0x00000080, /**< Reserved for future use */
CK_STATESAVE_SYNCHRORESERVED2 = 0x00000100, /**< Reserved for future use */
CK_STATESAVE_SYNCHRORESERVED3 = 0x00000200, /**< Reserved for future use */
CK_STATESAVE_SYNCHRONALL = 0x000003FF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_SYNCHRO);
/**
Grid
*/
enum class CK_STATESAVEFLAGS_GRID : uint32_t {
CK_STATESAVE_GRIDDATA = 0x00400000, /**< Save Grid Data */
CK_STATESAVE_GRIDRESERVED0 = 0x00800000, /**< Reserved for future use */
CK_STATESAVE_GRIDRESERVED1 = 0x01000000, /**< Reserved for future use */
CK_STATESAVE_GRIDRESERVED2 = 0x02000000, /**< Reserved for future use */
CK_STATESAVE_GRIDRESERVED3 = 0x04000000, /**< Reserved for future use */
CK_STATESAVE_GRIDRESERVED4 = 0x08000000, /**< Reserved for future use */
CK_STATESAVE_GRIDONLY = 0x0FC00000, /**< */
CK_STATESAVE_GRIDALL = 0x0FFFFFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_GRID);
/**
Layer (For Grids)
*/
enum class CK_STATESAVEFLAGS_LAYER : uint32_t {
CK_STATESAVE_LAYERDATA = 0x00000010, /**< Save Layer Data */
CK_STATESAVE_LAYERRESERVED0 = 0x00800020, /**< Reserved for future use */
CK_STATESAVE_LAYERRESERVED1 = 0x00000040, /**< Reserved for future use */
CK_STATESAVE_LAYERRESERVED2 = 0x00000080, /**< Reserved for future use */
CK_STATESAVE_LAYERRESERVED3 = 0x00000100, /**< Reserved for future use */
CK_STATESAVE_LAYERRESERVED4 = 0x00000200, /**< Reserved for future use */
CK_STATESAVE_LAYERONLY = 0x000003F0, /**< */
CK_STATESAVE_LAYERALL = 0x000003FF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_LAYER);
/**
DataArray CKSaveOjectSave will save all relevant data and does not take flags into account
*/
enum class CK_STATESAVEFLAGS_DATAARRAY : uint32_t {
CK_STATESAVE_DATAARRAYFORMAT = 0x00001000, /**< Save format */
CK_STATESAVE_DATAARRAYDATA = 0x00002000, /**< Save array data */
CK_STATESAVE_DATAARRAYMEMBERS = 0x00004000, /**< Save members */
CK_STATESAVE_DATAARRAYALL = 0x0000FFFF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_DATAARRAY);
/**
SceneObjectDesc
*/
enum class CK_STATESAVEFLAGS_SCENEOBJECTDESC : uint32_t {
CK_STATESAVE_SCENEOBJECTDESC = 0x00000010,
CK_STATESAVE_SCENEOBJECTRES1 = 0x00000020, /**< Reserved for future use */
CK_STATESAVE_SCENEOBJECTRES2 = 0x00000040, /**< Reserved for future use */
CK_STATESAVE_SCENEOBJECTRES3 = 0x00000080, /**< Reserved for future use */
CK_STATESAVE_SCENEOBJECTDESCALL = 0x000000FF, /**< Save All datas for sub-classes */
};
LIBCMO_BITFLAG_OPERATORS(CK_STATESAVEFLAGS_SCENEOBJECTDESC);
}

View File

@ -0,0 +1,27 @@
#include "../CKManagers.hpp"
namespace LibCmo::CK2::CKManagerImplements {
CKBaseManager::CKBaseManager(CKMinContext* ctx, CK_ID ckid) {
}
CKBaseManager::~CKBaseManager() {
}
CKERROR CKBaseManager::LoadData(CKStateChunk* statechunk, CKFileDocument* doc) {
return CKERROR::CKERR_OK;
}
CKStateChunk* CKBaseManager::SaveData(CKFileDocument* doc) {
return nullptr;
}
CKAttributeManager::CKAttributeManager(CKMinContext* ctx, CK_ID ckid) : CKBaseManager(ctx, ckid) {
}
CKAttributeManager::~CKAttributeManager() {
}
}

244
LibCmo/CK2/CKObject.hpp Normal file
View File

@ -0,0 +1,244 @@
#pragma once
#include "CKDefines.hpp"
#include "CKEnums.hpp"
namespace LibCmo::CK2::CKObjectImplements {
class CKObject {
public:
CK_ID m_ID;
std::string m_Name;
CK_OBJECT_FLAGS m_ObjectFlags;
CKMinContext* m_Context;
CKObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKObject(const CKObject&) = delete;
CKObject& operator=(const CKObject&) = delete;
virtual ~CKObject();
CK_ID GetID(void) { return this->m_ID; }
CKSTRING GetName(void) { return (this->m_Name.empty() ? nullptr : this->m_Name.c_str()); }
void SetName(CKSTRING u8_name) { this->m_Name = (u8_name == nullptr ? "" : u8_name); }
CK_OBJECT_FLAGS GetObjectFlags(void) { return this->m_ObjectFlags; }
void SetObjectFlags(CK_OBJECT_FLAGS flags) { this->m_ObjectFlags = flags; }
virtual CK_CLASSID GetClassID(void) { return CK_CLASSID::CKCID_OBJECT; }
virtual bool Load(CKStateChunk* chunk, const CKFileDocument* doc);
virtual CKStateChunk* Save(const CKFileDocument* doc);
};
class CKSceneObject : public CKObject {
public:
CKSceneObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKSceneObject(const CKSceneObject&) = delete;
CKSceneObject& operator=(const CKSceneObject&) = delete;
virtual ~CKSceneObject();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_SCENEOBJECT; }
protected:
XBitArray m_Scenes;
};
class CKBeObject : public CKSceneObject {
public:
CKBeObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKBeObject(const CKBeObject&) = delete;
CKBeObject& operator=(const CKBeObject&) = delete;
virtual ~CKBeObject();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_BEOBJECT; }
protected:
};
#pragma region Map Related
class CKGroup : public CKBeObject {
public:
CKGroup(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKGroup(const CKGroup&) = delete;
CKGroup& operator=(const CKGroup&) = delete;
virtual ~CKGroup();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_GROUP; }
protected:
};
class CKMesh : public CKBeObject {
public:
CKMesh(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKMesh(const CKMesh&) = delete;
CKMesh& operator=(const CKMesh&) = delete;
virtual ~CKMesh();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_MESH; }
protected:
};
class CKTexture : public CKBeObject {
public:
CKTexture(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKTexture(const CKTexture&) = delete;
CKTexture& operator=(const CKTexture&) = delete;
virtual ~CKTexture();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_TEXTURE; }
protected:
};
class CKMaterial : public CKBeObject {
public:
CKMaterial(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKMaterial(const CKMaterial&) = delete;
CKMaterial& operator=(const CKMaterial&) = delete;
virtual ~CKMaterial();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_MATERIAL; }
protected:
};
class CKRenderObject : public CKBeObject {
public:
CKRenderObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKRenderObject(const CKRenderObject&) = delete;
CKRenderObject& operator=(const CKRenderObject&) = delete;
~CKRenderObject();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_RENDEROBJECT; }
protected:
};
class CK3dEntity : public CKRenderObject {
public:
CK3dEntity(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CK3dEntity(const CK3dEntity&) = delete;
CK3dEntity& operator=(const CK3dEntity&) = delete;
virtual ~CK3dEntity();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_3DENTITY; }
protected:
};
class CK3dObject :public CK3dEntity {
public:
CK3dObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CK3dObject(const CK3dObject&) = delete;
CK3dObject& operator=(const CK3dObject&) = delete;
~CK3dObject();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_3DOBJECT; }
protected:
};
#pragma endregion
#pragma region Behavior Related
class CKParameterIn :public CKObject {
public:
CKParameterIn(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKParameterIn(const CKParameterIn&) = delete;
CKParameterIn& operator=(const CKParameterIn&) = delete;
~CKParameterIn();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_PARAMETERIN; }
protected:
};
class CKParameter :public CKObject {
public:
CKParameter(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKParameter(const CKParameter&) = delete;
CKParameter& operator=(const CKParameter&) = delete;
~CKParameter();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_PARAMETER; }
protected:
};
class CKParameterOut :public CKParameter {
public:
CKParameterOut(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKParameterOut(const CKParameterOut&) = delete;
CKParameterOut& operator=(const CKParameterOut&) = delete;
~CKParameterOut();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_PARAMETEROUT; }
protected:
};
class CKParameterLocal :public CKParameter {
public:
CKParameterLocal(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKParameterLocal(const CKParameterLocal&) = delete;
CKParameterLocal& operator=(const CKParameterLocal&) = delete;
~CKParameterLocal();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_PARAMETERLOCAL; }
protected:
};
class CKParameterOperation :public CKObject {
public:
CKParameterOperation(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKParameterOperation(const CKParameterOperation&) = delete;
CKParameterOperation& operator=(const CKParameterOperation&) = delete;
~CKParameterOperation();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_PARAMETEROPERATION; }
protected:
};
class CKBehaviorLink :public CKObject {
public:
CKBehaviorLink(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKBehaviorLink(const CKBehaviorLink&) = delete;
CKBehaviorLink& operator=(const CKBehaviorLink&) = delete;
~CKBehaviorLink();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_BEHAVIORLINK; }
protected:
};
class CKBehaviorIO :public CKObject {
public:
CKBehaviorIO(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKBehaviorIO(const CKBehaviorIO&) = delete;
CKBehaviorIO& operator=(const CKBehaviorIO&) = delete;
~CKBehaviorIO();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_BEHAVIORIO; }
protected:
};
class CKBehavior :public CKSceneObject {
public:
CKBehavior(CKMinContext* ctx, CK_ID ckid, CKSTRING name);
CKBehavior(const CKBehavior&) = delete;
CKBehavior& operator=(const CKBehavior&) = delete;
~CKBehavior();
virtual CK_CLASSID GetClassID(void) override { return CK_CLASSID::CKCID_BEHAVIOR; }
protected:
};
#pragma endregion
}

View File

@ -0,0 +1,138 @@
#include "../CKObjects.hpp"
#include "../CKStateChunk.hpp"
#include "../CKIdentifiers.hpp"
#include "../VTUtils.hpp"
namespace LibCmo::CK2::CKObjectImplements {
CKObject::CKObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name) :
m_ID(ckid), m_Context(ctx),
m_Name(name == nullptr ? "" : name),
m_ObjectFlags(CK_OBJECT_FLAGS::CK_PARAMETERIN_DISABLED) {
;
}
CKObject::~CKObject() {
}
bool CKObject::Load(CKStateChunk* chunk, const CKFileDocument* doc) {
if (chunk->SeekIdentifier(Identifiers::CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIDDEN)) {
EnumsHelper::FlagEnumRm(this->m_ObjectFlags,
{ CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE,
CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE }
);
} else {
if (chunk->SeekIdentifier(Identifiers::CK_STATESAVEFLAGS_OBJECT::CK_STATESAVE_OBJECTHIERAHIDDEN)) {
// != 0
EnumsHelper::FlagEnumRm(this->m_ObjectFlags,
{ CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE, }
);
EnumsHelper::FlagEnumAdd(this->m_ObjectFlags,
{ CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE, }
);
} else {
// == 0
EnumsHelper::FlagEnumAdd(this->m_ObjectFlags,
{ CK_OBJECT_FLAGS::CK_OBJECT_VISIBLE, }
);
EnumsHelper::FlagEnumRm(this->m_ObjectFlags,
{ CK_OBJECT_FLAGS::CK_OBJECT_HIERACHICALHIDE, }
);
}
}
return true;
}
CKStateChunk* CKObject::Save(const CKFileDocument* doc) {
return nullptr;
}
CKSceneObject::CKSceneObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKObject(ctx, ckid, name) {
}
CKSceneObject::~CKSceneObject() {
}
CKBeObject::CKBeObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKSceneObject(ctx, ckid, name) {
}
CKBeObject::~CKBeObject() {
}
CKGroup::CKGroup(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKBeObject(ctx, ckid, name) {
}
CKGroup::~CKGroup() {
}
CKMesh::CKMesh(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKBeObject(ctx, ckid, name) {
}
CKMesh::~CKMesh() {
}
CKTexture::CKTexture(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKBeObject(ctx, ckid, name) {
}
CKTexture::~CKTexture() {
}
CKMaterial::CKMaterial(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKBeObject(ctx, ckid, name) {
}
CKMaterial::~CKMaterial() {
}
CKRenderObject::CKRenderObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKBeObject(ctx, ckid, name) {
}
CKRenderObject::~CKRenderObject() {
}
CK3dEntity::CK3dEntity(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKRenderObject(ctx, ckid, name) {
}
CK3dEntity::~CK3dEntity() {
}
CK3dObject::CK3dObject(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CK3dEntity(ctx, ckid, name) {
}
CK3dObject::~CK3dObject() {
}
CKParameterIn::CKParameterIn(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKObject(ctx, ckid, name) {
}
CKParameterIn::~CKParameterIn() {
}
CKParameter::CKParameter(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKObject(ctx, ckid, name) {
}
CKParameter::~CKParameter() {
}
CKParameterOut::CKParameterOut(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKParameter(ctx, ckid, name) {
}
CKParameterOut::~CKParameterOut() {
}
CKParameterLocal::CKParameterLocal(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKParameter(ctx, ckid, name) {
}
CKParameterLocal::~CKParameterLocal() {
}
CKParameterOperation::CKParameterOperation(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKObject(ctx, ckid, name) {
}
CKParameterOperation::~CKParameterOperation() {
}
CKBehaviorLink::CKBehaviorLink(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKObject(ctx, ckid, name) {
}
CKBehaviorLink::~CKBehaviorLink() {
}
CKBehaviorIO::CKBehaviorIO(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKObject(ctx, ckid, name) {
}
CKBehaviorIO::~CKBehaviorIO() {
}
CKBehavior::CKBehavior(CKMinContext* ctx, CK_ID ckid, CKSTRING name) : CKSceneObject(ctx, ckid, name) {
}
CKBehavior::~CKBehavior() {
}
}

805
LibCmo/CK2/CKStateChunk.cpp Normal file
View File

@ -0,0 +1,805 @@
#include "VTUtils.hpp"
#include "CKStateChunk.hpp"
#include "CKMinContext.hpp"
#include "CKFile.hpp"
namespace LibCmo::CK2 {
#pragma region Ctor Dtor
//CKStateChunk::CKStateChunk() :
// 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_Parser{ CKStateChunkStatus::IDLE, 0u, 0u, 0u },
// m_ObjectList(), m_ChunkList(), m_ManagerList(),
// m_BindDoc(nullptr), m_BindContext(nullptr)
//{
// ;
//}
CKStateChunk::CKStateChunk(CKFileDocument* doc, CKMinContext* ctx) :
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_Parser{ CKStateChunkStatus::IDLE, 0u, 0u, 0u },
m_ObjectList(), m_ChunkList(), m_ManagerList(),
m_BindDoc(doc), m_BindContext(ctx)
{
;
}
CKStateChunk::CKStateChunk(const CKStateChunk& rhs) :
m_ClassId(rhs.m_ClassId), m_DataVersion(rhs.m_DataVersion), m_ChunkVersion(rhs.m_ChunkVersion),
m_Parser(rhs.m_Parser),
m_ObjectList(rhs.m_ObjectList), m_ManagerList(rhs.m_ManagerList), m_ChunkList(rhs.m_ChunkList),
m_pData(nullptr), m_DataDwSize(rhs.m_DataDwSize),
m_BindDoc(rhs.m_BindDoc), m_BindContext(rhs.m_BindContext) {
// copy buffer
if (rhs.m_pData != nullptr) {
this->m_pData = new(std::nothrow) CKDWORD[rhs.m_DataDwSize];
if (this->m_pData != nullptr) {
std::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;
this->m_BindDoc = rhs.m_BindDoc;
this->m_BindContext = rhs.m_BindContext;
// copy buffer
if (rhs.m_pData != nullptr) {
this->m_pData = new(std::nothrow) CKDWORD[rhs.m_DataDwSize];
if (this->m_pData != nullptr) {
std::memcpy(this->m_pData, rhs.m_pData, sizeof(CKDWORD) * rhs.m_DataDwSize);
}
}
this->m_DataDwSize = rhs.m_DataDwSize;
return *this;
}
CKStateChunk::~CKStateChunk() {
if (this->m_pData != nullptr)
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;
}
CK_STATECHUNK_DATAVERSION CKStateChunk::GetDataVersion() {
return this->m_DataVersion;
}
void CKStateChunk::SetDataVersion(CK_STATECHUNK_DATAVERSION version) {
this->m_DataVersion = version;
}
void CKStateChunk::DeleteBuffer(void* buf) {
if (buf == nullptr) return;
delete[] reinterpret_cast<char*>(buf);
}
bool CKStateChunk::Skip(CKDWORD DwordCount) {
bool result;
switch (this->m_Parser.m_Status) {
case CKStateChunkStatus::READ:
result = EnsureReadSpace(DwordCount);
break;
case CKStateChunkStatus::WRITE:
result = EnsureWriteSpace(DwordCount);
break;
case CKStateChunkStatus::IDLE:
default:
result = false;
break;
}
// if success, move cursor
if (result) {
this->m_Parser.m_CurrentPos += DwordCount;
}
return result;
}
size_t CKStateChunk::GetCeilDwordSize(size_t char_size) {
return (char_size + 3) >> 2;
}
bool CKStateChunk::ResizeBuffer(CKDWORD new_dwsize) {
if (new_dwsize == 0u) {
// if reuqired size is zero, we just delete it
if (this->m_pData != nullptr) {
delete[] this->m_pData;
this->m_pData = nullptr;
}
} else {
// otherwise, we create a new buffer instead it
CKDWORD* newbuf = new(std::nothrow) CKDWORD[new_dwsize];
if (newbuf == nullptr) return false; // if fail to create, return
// if no original data, we do not need copy it and free it
if (this->m_pData != nullptr) {
std::memcpy(newbuf, this->m_pData, sizeof(CKDWORD) * new_dwsize);
delete[] this->m_pData;
}
// assign new buffer
this->m_pData = newbuf;
}
return true;
}
bool CKStateChunk::EnsureWriteSpace(CKDWORD dwsize) {
if (this->m_Parser.m_Status != CKStateChunkStatus::WRITE) return false;
// check whether need enlarge
CKDWORD needed = dwsize + this->m_Parser.m_CurrentPos;
if (needed > this->m_Parser.m_DataSize) {
// add a very enough space to buffer
if (dwsize < 512) dwsize = 512;
needed = dwsize + this->m_Parser.m_CurrentPos;
// try resizing it
if (!this->ResizeBuffer(needed)) return false;
// update size
this->m_Parser.m_DataSize = needed;
}
return true;
}
bool CKStateChunk::EnsureReadSpace(CKDWORD dword_required) {
return (m_Parser.m_Status == CKStateChunkStatus::READ) &&
(this->m_Parser.m_CurrentPos + dword_required <= this->m_Parser.m_DataSize);
}
#pragma endregion
#pragma region Buffer Related
bool CKStateChunk::ConvertFromBuffer(const void* buf) {
if (buf == nullptr) return false;
// read chunk ver and data ver first
// chunk ver always set in the 3rd BYTE in every format
this->m_ChunkVersion = static_cast<CK_STATECHUNK_CHUNKVERSION>(
reinterpret_cast<const char*>(buf)[2]
);
// data ver always set in the 1st BYTE in every format
this->m_DataVersion = static_cast<CK_STATECHUNK_DATAVERSION>(
reinterpret_cast<const char*>(buf)[0]
);
// switch according to chunk ver
const CKDWORD* dwbuf = reinterpret_cast<const CKDWORD*>(buf);
size_t bufpos = 0u;
if (this->m_ChunkVersion < CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION2) {
// very old file
this->m_ClassId = static_cast<CK_CLASSID>(dwbuf[1]);
this->m_DataDwSize = dwbuf[2];
this->m_ObjectList.resize(dwbuf[4]);
this->m_ChunkList.resize(dwbuf[5]);
bufpos = 6u;
if (this->m_DataDwSize != 0) {
this->m_pData = new(std::nothrow) CKDWORD[this->m_DataDwSize];
if (m_pData == nullptr) return false;
std::memcpy(this->m_pData, dwbuf + bufpos, sizeof(CKDWORD) * this->m_DataDwSize);
bufpos += this->m_DataDwSize;
}
if (!this->m_ObjectList.empty()) {
std::memcpy(this->m_ObjectList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ObjectList.size());
bufpos += this->m_ObjectList.size();
}
if (!this->m_ChunkList.empty()) {
std::memcpy(this->m_ChunkList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ChunkList.size());
bufpos += this->m_ChunkList.size();
}
} else if (this->m_ChunkVersion == CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION2) {
// medium ver file
this->m_ClassId = static_cast<CK_CLASSID>(dwbuf[1]);
this->m_DataDwSize = dwbuf[2];
this->m_ObjectList.resize(dwbuf[4]);
this->m_ChunkList.resize(dwbuf[5]);
this->m_ManagerList.resize(dwbuf[6]);
bufpos = 7u;
if (this->m_DataDwSize != 0) {
this->m_pData = new(std::nothrow) CKDWORD[this->m_DataDwSize];
if (m_pData == nullptr) return false;
std::memcpy(this->m_pData, dwbuf + bufpos, sizeof(CKDWORD) * this->m_DataDwSize);
bufpos += this->m_DataDwSize;
}
if (!this->m_ObjectList.empty()) {
std::memcpy(this->m_ObjectList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ObjectList.size());
bufpos += this->m_ObjectList.size();
}
if (!this->m_ChunkList.empty()) {
std::memcpy(this->m_ChunkList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ChunkList.size());
bufpos += this->m_ChunkList.size();
}
if (!this->m_ManagerList.empty()) {
std::memcpy(this->m_ManagerList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ManagerList.size());
bufpos += this->m_ManagerList.size();
}
} else if (this->m_ChunkVersion <= CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4) {
// the latest file
// re-read some extra data
// class id located the 2nd BYTE
this->m_ClassId = static_cast<CK_CLASSID>(
reinterpret_cast<const char*>(buf)[1]
);
// options located the 4th BYTE
CK_STATECHUNK_CHUNKOPTIONS options = static_cast<CK_STATECHUNK_CHUNKOPTIONS>(
reinterpret_cast<const char*>(buf)[3]
);
// read normal data
this->m_DataDwSize = dwbuf[1];
bufpos = 2u;
if (this->m_DataDwSize != 0) {
this->m_pData = new(std::nothrow) CKDWORD[this->m_DataDwSize];
if (m_pData == nullptr) return false;
std::memcpy(this->m_pData, dwbuf + bufpos, sizeof(CKDWORD) * this->m_DataDwSize);
bufpos += this->m_DataDwSize;
}
if (EnumsHelper::FlagEnumHas(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_FILE)) {
// MARK: set ckfile = nullptr;
;
}
if (EnumsHelper::FlagEnumHas(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_IDS)) {
this->m_ObjectList.resize(dwbuf[bufpos]);
bufpos += 1u;
std::memcpy(this->m_ObjectList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ObjectList.size());
bufpos += this->m_ObjectList.size();
}
if (EnumsHelper::FlagEnumHas(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_CHN)) {
this->m_ChunkList.resize(dwbuf[bufpos]);
bufpos += 1u;
std::memcpy(this->m_ChunkList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ChunkList.size());
bufpos += this->m_ChunkList.size();
}
if (EnumsHelper::FlagEnumHas(options, CK_STATECHUNK_CHUNKOPTIONS::CHNK_OPTION_MAN)) {
this->m_ManagerList.resize(dwbuf[bufpos]);
bufpos += 1u;
std::memcpy(this->m_ManagerList.data(), dwbuf + bufpos, sizeof(CKDWORD) * this->m_ManagerList.size());
bufpos += this->m_ManagerList.size();
}
} else {
// too new. can not read, skip
;
}
return true;
}
CKDWORD CKStateChunk::ConvertToBuffer(void* buf) {
return 0u;
}
#pragma endregion
//bool CKStateChunk::UnPack(CKDWORD DestSize) {
// // NOTE: in UnPack. pData store the compressed buffer, and
// // dwSize store the length of compressed buffer as CHAR size, not DWORD size!
// // create a enough buffer
// char* buffer = new(std::nothrow) char[DestSize];
// if (buffer == nullptr) return false;
// uLongf destSize = DestSize;
// // uncompress it
// auto err = uncompress(
// reinterpret_cast<Bytef*>(buffer), &destSize,
// reinterpret_cast<const Bytef*>(this->m_pData), static_cast<uLong>(this->m_DataDwSize)
// );
// // if no error, assign data
// if (err == Z_OK) {
// // get dw size and copy it to remove useless blank data
// this->m_DataDwSize = static_cast<CKDWORD>(destSize) / sizeof(CKDWORD);
// delete[] this->m_pData;
// this->m_pData = nullptr;
// this->m_pData = new(std::nothrow) CKDWORD[this->m_DataDwSize];
// if (this->m_pData != nullptr) {
// std::memcpy(this->m_pData, buffer, this->m_DataDwSize * sizeof(CKDWORD));
// }
// }
// delete[] buffer;
// return true;
//}
#pragma region Read Functions
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::StopRead(void) {
if (this->m_Parser.m_Status != CKStateChunkStatus::READ) 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::IDLE;
}
/* ========== Identifier Functions ==========*/
bool CKStateChunk::SeekIdentifierDword(CKDWORD identifier) {
CKDWORD cache;
return SeekIdentifierDwordAndReturnSize(identifier, &cache);
}
bool CKStateChunk::SeekIdentifierDwordAndReturnSize(CKDWORD identifier, CKDWORD* out_size) {
if (this->m_Parser.m_Status != CKStateChunkStatus::READ) return false;
CKDWORD pos = 0u;
if (this->m_DataDwSize < 2) return false; // impossible to have a identifier
// search identifier
while (this->m_pData[pos] != identifier) {
pos = this->m_pData[pos + 1];
if (pos == 0u) return false; // got tail. no more identifier
if (pos + 1 >= this->m_DataDwSize) return false; // out of buffer
}
// got identifier
this->m_Parser.m_PrevIdentifierPos = pos;
this->m_Parser.m_CurrentPos = pos + 2;
// calc size
CKDWORD nextptr = this->m_pData[pos + 1];
if (nextptr == 0) {
// the last identifier, use chunk size instead
nextptr = this->m_DataDwSize;
}
*out_size = sizeof(CKDWORD) * (nextptr - pos);
return true;
}
/* ========== Basic Data Read Functions ==========*/
bool CKStateChunk::ReadByteData(void* data_ptr, CKDWORD size_in_byte) {
if (this->m_Parser.m_Status != CKStateChunkStatus::READ) return false;
if (data_ptr == nullptr) return false;
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);
return true;
} else {
// failed, report to context
m_BindContext->Printf("CKStateChunk read length error at %" PRICKdword ".", this->m_Parser.m_CurrentPos);
return false;
}
}
bool CKStateChunk::ReadString(std::string* strl) {
if (strl == nullptr) return false;
// get byte based size
CKDWORD strByteSize = 0u;
if (!this->ReadStruct(strByteSize)) {
strl->clear();
return false;
}
// read data
strl->resize(strByteSize);
if (!this->ReadByteData(strl->data(), strByteSize)) {
strl->clear();
return false;
}
return true;
}
/* ========== Complex Data Read Functions ==========*/
bool CKStateChunk::ReadObjectID(CK_ID* id) {
if (id == nullptr) return false;
// get basic value
CKINT gotten_id = 0;
if (!this->ReadStruct(gotten_id)) return false;
// different strategy according to chunk ver
if (this->m_ChunkVersion >= CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION1) {
// new file
// if no doc associated, return directly
if (this->m_BindDoc == nullptr) {
*id = static_cast<CK_ID>(gotten_id);
return true;
}
// if it is positive, return corresponding value
if (gotten_id >= 0) {
*id = this->m_BindDoc->m_FileObjects[gotten_id].CreatedObject;
return true;
}
} else {
// old file
// i don't know why I need skip 2 DWORD
// just copy IDA code.
if (gotten_id) {
this->Skip(2);
return this->ReadStruct(id);
}
}
// all failed
*id = 0u;
return false;
}
bool CKStateChunk::ReadManagerInt(CKGUID* guid, CKINT* intval) {
if (guid == nullptr || intval == nullptr) return false;
// read guid first
if (!this->ReadStruct(guid)) return false;
// then read int value
if (!this->ReadStruct(intval)) return false;
return true;
}
CKStateChunk* CKStateChunk::ReadSubChunk(void) {
CKStateChunk* subchunk = nullptr;
// get size and do a enough space check
CKDWORD subChunkSize;
if (!this->ReadStruct(subChunkSize)) goto subchunk_defer;
if (!this->EnsureReadSpace(subChunkSize)) goto subchunk_defer;
// create statechunk
subchunk = new(std::nothrow) CKStateChunk(this->m_BindDoc, this->m_BindContext);
if (subchunk == nullptr) goto subchunk_defer;
// start read data
// read class id
if (!this->ReadStruct(subchunk->m_ClassId)) goto subchunk_defer;
// different read strategy by chunk version
if (this->m_ChunkVersion >= CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION1) {
// new file
// read combined version
CKDWORD versionInfo;
if (!this->ReadStruct(versionInfo)) goto subchunk_defer;
subchunk->m_DataVersion = static_cast<CK_STATECHUNK_DATAVERSION>(versionInfo & 0xffff);
subchunk->m_ChunkVersion = static_cast<CK_STATECHUNK_CHUNKVERSION>((versionInfo >> 16) & 0xffff);
// read data size and create it
if (!this->ReadStruct(subchunk->m_DataDwSize)) goto subchunk_defer;
subchunk->m_pData = new(std::nothrow) CKDWORD[subchunk->m_DataDwSize];
if (subchunk->m_pData == nullptr) goto subchunk_defer;
// has bind file?
CKDWORD hasBindFile;
if (!this->ReadStruct(hasBindFile)) goto subchunk_defer;
if (hasBindFile == 1) subchunk->m_BindDoc = nullptr;
// 3 list size
// manager only existed when ver > 4
CKDWORD lssize;
if (!this->ReadStruct(lssize)) goto subchunk_defer;
subchunk->m_ObjectList.resize(lssize);
if (!this->ReadStruct(lssize)) goto subchunk_defer;
subchunk->m_ChunkList.resize(lssize);
if (this->m_ChunkVersion > CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION1) {
if (!this->ReadStruct(lssize)) goto subchunk_defer;
subchunk->m_ManagerList.resize(lssize);
}
// core data
if (subchunk->m_DataDwSize != 0) {
if (!this->ReadByteData(subchunk->m_pData, subchunk->m_DataDwSize * sizeof(CKDWORD))) goto subchunk_defer;
}
// 3 list data
if (!subchunk->m_ObjectList.empty()) {
if (!this->ReadByteData(
subchunk->m_ObjectList.data(),
subchunk->m_ObjectList.size() * sizeof(CKDWORD)
)) goto subchunk_defer;
}
if (!subchunk->m_ChunkList.empty()) {
if (!this->ReadByteData(
subchunk->m_ChunkList.data(),
subchunk->m_ChunkList.size() * sizeof(CKDWORD)
)) goto subchunk_defer;
}
if (!subchunk->m_ManagerList.empty()) {
if (!this->ReadByteData(
subchunk->m_ManagerList.data(),
subchunk->m_ManagerList.size() * sizeof(CKDWORD)
)) goto subchunk_defer;
}
} else {
// old file
// read data size and create it
if (!this->ReadStruct(subchunk->m_DataDwSize)) goto subchunk_defer;
subchunk->m_pData = new(std::nothrow) CKDWORD[subchunk->m_DataDwSize];
if (subchunk->m_pData == nullptr) goto subchunk_defer;
// skip one?
// I don't know why
this->Skip(1u);
// read core buf
if (!this->ReadByteData(subchunk->m_pData, subchunk->m_DataDwSize * sizeof(CKDWORD))) goto subchunk_defer;
}
return subchunk;
subchunk_defer:
if (subchunk != nullptr) delete subchunk;
return nullptr;
}
/* ========== Buffer Functions ==========*/
bool CKStateChunk::ReadNoSizeBuffer(CKDWORD size_in_byte, void* allocatedBuf) {
if (allocatedBuf == nullptr) return false;
return this->ReadByteData(allocatedBuf, size_in_byte);
}
bool CKStateChunk::ReadBuffer(void** buf, CKDWORD* len_in_byte) {
if (buf == nullptr || len_in_byte == nullptr) return false;
// get buffer size.
CKDWORD bufByteSize = 0u;
if (!this->ReadStruct(bufByteSize)) {
*buf = nullptr;
*len_in_byte = 0;
return false;
}
*len_in_byte = bufByteSize;
// create buffer
*buf = new(std::nothrow) char[bufByteSize];
if (*buf == nullptr) {
*len_in_byte = 0;
return false;
}
// read data
if (!this->ReadByteData(*buf, bufByteSize)) {
this->DeleteBuffer(*buf);
*buf = nullptr;
*len_in_byte = 0;
return false;
}
return true;
}
/* ========== Sequence Functions ==========*/
bool CKStateChunk::ReadObjectIDSequence(std::vector<CK_ID>* ls) {
if (ls == nullptr) return false;
ls->clear();
// read count
CKDWORD count;
if (!this->ReadStruct(count)) return false;
// resize list and read it
ls->resize(count);
for (size_t i = 0; i < count; ++i) {
if (!this->ReadObjectID(ls->data() + i)) {
ls->clear();
return false;
}
}
return true;
}
bool CKStateChunk::ReadManagerIntSequence(CKGUID* guid, std::vector<CKINT>* ls) {
if (guid == nullptr || ls == nullptr) return false;
// read count
CKDWORD count;
if (!this->ReadStruct(count)) return false;
// read guid
if (!this->ReadStruct(guid)) return false;
// resize list and read it
ls->resize(count);
for (size_t i = 0; i < count; ++i) {
if (!this->ReadStruct(ls->data() + i)) {
ls->clear();
return false;
}
}
return true;
}
bool CKStateChunk::ReadSubChunkSequence(std::vector<CKStateChunk*>* ls) {
if (ls == nullptr) return false;
// clear first
for (auto& item : *ls) {
if (item != nullptr)
delete (item);
}
ls->clear();
// read count
CKDWORD count;
if (!this->ReadStruct(count)) return false;
// resize list and read it
ls->resize(count, nullptr);
for (size_t i = 0; i < count; ++i) {
(*ls)[i] = this->ReadSubChunk();
if ((*ls)[i] == nullptr) {
// fail. remove all created statechunk and clear it
for (auto& item : *ls) {
if (item != nullptr)
delete (item);
}
ls->clear();
// return
return false;
}
}
return true;
}
bool CKStateChunk::ReadObjectArray(std::vector<CK_ID>* ls) {
if (ls == nullptr) return false;
ls->clear();
// read count
CKDWORD count;
if (!this->ReadStruct(count)) return false;
if (!count) return true; // 0 size array
// old file size correction
if (this->m_ChunkVersion < CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION1) {
// skip 4. but I don't know why!!!
this->Skip(4);
if (!this->ReadStruct(count)) return false;
}
// resize list and read
ls->resize(count);
for (auto& id : *ls) {
// read ID first
CKINT cache;
if (!this->ReadStruct(cache)) {
ls->clear();
return false;
}
// remap id
if (this->m_BindDoc != nullptr) {
if (cache < 0) {
id = 0u;
} else {
id = this->m_BindDoc->m_FileObjects[cache].CreatedObject;
}
} else {
id = static_cast<CK_ID>(cache);
}
}
return true;
}
#pragma endregion
#pragma region Write Functions
void CKStateChunk::StartWrite() {
if (this->m_Parser.m_Status != CKStateChunkStatus::IDLE) return;
// delete all current buffer
if (this->m_pData != nullptr) {
delete[] this->m_pData;
this->m_pData = nullptr;
}
this->m_DataDwSize = 0u;
// reset parser
this->m_Parser.m_CurrentPos = 0u;
this->m_Parser.m_DataSize = this->m_DataDwSize;
this->m_Parser.m_PrevIdentifierPos = 0u;
// force chunk version
this->m_ChunkVersion = CK_STATECHUNK_CHUNKVERSION::CHUNK_VERSION4;
// switch status
this->m_Parser.m_Status = CKStateChunkStatus::WRITE;
}
void CKStateChunk::StopWrite(void) {
if (this->m_Parser.m_Status != CKStateChunkStatus::WRITE) return;
// update buffer size
this->m_DataDwSize = this->m_Parser.m_CurrentPos;
// shrink it
ResizeBuffer(this->m_DataDwSize);
// shrink 3 vector also
this->m_ObjectList.shrink_to_fit();
this->m_ManagerList.shrink_to_fit();
this->m_ChunkList.shrink_to_fit();
// reset parser
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::IDLE;
}
#pragma endregion
}

298
LibCmo/CK2/CKStateChunk.hpp Normal file
View File

@ -0,0 +1,298 @@
#pragma once
#include "CKDefines.hpp"
#include "CKEnums.hpp"
#include <type_traits>
#include <cinttypes>
namespace LibCmo::CK2 {
class CKStateChunk {
public:
//CKStateChunk();
CKStateChunk(CKFileDocument* doc, CKMinContext* ctx);
CKStateChunk(const CKStateChunk&);
CKStateChunk& operator=(const CKStateChunk&);
~CKStateChunk();
private:
enum class CKStateChunkStatus : int32_t {
IDLE,
READ,
WRITE
};
CK_CLASSID m_ClassId;
CKDWORD m_DataDwSize;
CKDWORD* m_pData;
CK_STATECHUNK_DATAVERSION m_DataVersion;
CK_STATECHUNK_CHUNKVERSION m_ChunkVersion;
struct {
CKStateChunkStatus m_Status;
CKDWORD m_CurrentPos;
CKDWORD m_DataSize;
CKDWORD m_PrevIdentifierPos;
}m_Parser;
std::vector<CKDWORD> m_ObjectList;
std::vector<CKDWORD> m_ChunkList;
std::vector<CKDWORD> m_ManagerList;
CKFileDocument* m_BindDoc;
CKMinContext* m_BindContext;
#pragma region Buffer Related
public:
bool ConvertFromBuffer(const void* buf);
CKDWORD ConvertToBuffer(void* buf);
#pragma endregion
#pragma region Misc Functions
public:
//bool UnPack(CKDWORD DestSize);
void Clear(void);
CKDWORD GetDataSize(void);
CK_STATECHUNK_DATAVERSION GetDataVersion();
void SetDataVersion(CK_STATECHUNK_DATAVERSION version);
void DeleteBuffer(void* buf);
bool Skip(CKDWORD DwordCount);
private:
size_t GetCeilDwordSize(size_t char_size);
bool ResizeBuffer(CKDWORD new_dwsize);
bool EnsureWriteSpace(CKDWORD dwsize);
bool EnsureReadSpace(CKDWORD dword_required);
#pragma endregion
#pragma region Read Function
public:
void StartRead(void);
void StopRead(void);
/* ========== Identifier Functions ==========*/
bool SeekIdentifierDword(CKDWORD identifier);
bool SeekIdentifierDwordAndReturnSize(CKDWORD identifier, CKDWORD* out_size);
template<typename TEnum>
inline bool SeekIdentifier(TEnum enum_v) {
return SeekIdentifierDword(static_cast<CKDWORD>(enum_v));
}
template<typename TEnum>
inline bool SeekIdentifierAndReturnSize(TEnum enum_v, CKDWORD* out_size) {
return SeekIdentifierDwordAndReturnSize(static_cast<CKDWORD>(enum_v), out_size);
}
/* ========== Basic Data Read Functions ==========*/
private:
/// <summary>
/// The base read function for all data.
/// <para>This function will check all read requirements.</para>
/// <para>If you have use this function or functions calling this function. You do not need check any reading requirements anymore</para>
/// </summary>
/// <param name="data_ptr">the pointer to data. must be allocated first.</param>
/// <param name="size_in_byte">the size of data in byte.</param>
/// <returns></returns>
bool ReadByteData(void* data_ptr, CKDWORD size_in_byte);
public:
/// <summary>
/// Read Struct
/// <para>Primitive type: ReadInt, ReadByte, ReadWord, ReadDword, ReadFloat, etc...</para>
/// <para>Struct type: ReadGuid, ReadVector, ReadMatrix, etc...</para>
/// <para>Both of them are redirected to this.</para>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <returns></returns>
template<typename T>
bool ReadStruct(T* data) {
return ReadByteData(data, static_cast<CKDWORD>(sizeof(T)));
}
/// <summary>
/// Read Struct
/// <para>A wrapper for ReadStructPtr.</para>
/// <para>Use reference, not pointer.</para>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <returns></returns>
template<typename T>
inline bool ReadStruct(T& data) {
return ReadByteData(&data, static_cast<CKDWORD>(sizeof(T)));
}
/// <summary>
/// Read string
/// </summary>
/// <param name="strl"></param>
/// <returns></returns>
bool ReadString(std::string* strl);
inline bool ReadString(std::string& strl) {
return ReadString(&strl);
}
/* ========== Complex Data Read Functions ==========*/
bool ReadObjectID(CK_ID* id);
inline bool ReadObjectID(CK_ID& id) {
return ReadObjectID(&id);
}
bool ReadManagerInt(CKGUID* guid, CKINT* intval);
inline bool ReadManagerInt(CKGUID& guid, CKINT& intval) {
return ReadManagerInt(&guid, &intval);
}
/// <summary>
/// Read sub chunk
/// <para>Return nullptr if failed.</para>
/// <para>Returned CKStateChunk should be manually released!</para>
/// </summary>
/// <param name=""></param>
/// <returns></returns>
CKStateChunk* ReadSubChunk(void);
/* ========== Buffer Functions ==========*/
/*
Buffer related function implements:
ReadBuffer(void**) Read Byte based size. -> ReadBuffer
ReadAndFillBuffer(int, void*) User give Byte based size. -> ReadNoSizeBuffer
ReadAndFillBuffer(void*) Read Byte based size. -> ReadBuffer
ReadAndFillBuffer_LEndian(int, void*) User give Byte based size. -> ReadNoSizeBuffer
ReadAndFillBuffer_LEndian(void*) Read Byte based size. -> ReadBuffer
ReadAndFillBuffer_LEndian16(int, void*) User give Byte based size. -> ReadNoSizeBuffer
ReadAndFillBuffer_LEndian16(void*) Read Byte based size. -> ReadBuffer
*/
/// <summary>
/// Read a buffer with unknow size (order user specific it).
/// <para>ReadAndFillBuffer(int, void*), ReadAndFillBuffer_LEndian(int, void*), ReadAndFillBuffer_LEndian16(int, void*) are redirected to this.</para>
/// <para>The buffer should be allocated by caller first.</para>
/// </summary>
/// <param name="size"></param>
/// <param name="allocatedBuf"></param>
/// <returns></returns>
bool ReadNoSizeBuffer(CKDWORD size_in_byte, void* allocatedBuf);
/// <summary>
/// Read a buffer with knowen size stored in chunk.
/// <para>ReadBuffer(void**), ReadAndFillBuffer(void*), ReadAndFillBuffer_LEndian(void*), ReadAndFillBuffer_LEndian16(void*) are redirected to this.</para>
/// <para>The buffer will be allocated by function.</para>
/// <para>Use CKStateChunk::DeleteBuffer() to delete it.</para>
/// </summary>
/// <param name="buf">a pointer to the pointer receiving data start address.</param>
/// <param name="len">a pointer to the variable receiving the length of gotten buffer.</param>
/// <returns></returns>
bool ReadBuffer(void** buf, CKDWORD* len_in_byte);
/* ========== Sequence Functions ==========*/
/// <summary>
/// Read Object ID Sequence
/// <para>The combination using of StartReadSequence(), ReadObjectID(), and ReadObject() redirect to this.</para>
/// </summary>
/// <param name="ls"></param>
/// <returns></returns>
bool ReadObjectIDSequence(std::vector<CK_ID>* ls);
inline bool ReadObjectIDSequence(std::vector<CK_ID>& ls) {
return ReadObjectIDSequence(&ls);
}
/// <summary>
/// Read Manager Sequence
/// <para>The combination using of StartManagerReadSequence() and ReadManagerIntSequence() redirect to this.</para>
/// </summary>
/// <param name="guid"></param>
/// <param name="ls"></param>
/// <returns></returns>
bool ReadManagerIntSequence(CKGUID* guid, std::vector<CKINT>* ls);
inline bool ReadManagerIntSequence(CKGUID& guid, std::vector<CKINT>& ls) {
return ReadManagerIntSequence(&guid, &ls);
}
/// <summary>
/// Read Sub Chunk Sequence
/// <para>The combination using of StartReadSequence() and ReadSubChunk() redirect to this.</para>
/// <para>The item of returned CKStateChunk* list should be manually released!</para>
/// </summary>
/// <param name="ls"></param>
/// <returns></returns>
bool ReadSubChunkSequence(std::vector<CKStateChunk*>* ls);
inline bool ReadSubChunkSequence(std::vector<CKStateChunk*>& ls) {
return ReadSubChunkSequence(&ls);
}
/// <summary>
/// Read Object Array (actually still is CK_ID)
/// <para>ReadXObjectArray() and ReadObjectArray() redirect to this.</para>
/// </summary>
/// <param name="ls"></param>
/// <returns></returns>
bool ReadObjectArray(std::vector<CK_ID>* ls);
inline bool ReadObjectArray(std::vector<CK_ID>& ls) {
return ReadObjectArray(&ls);
}
//int ReadInt();
//int StartReadSequence();
//CK_ID ReadObjectID();
//CKStateChunk* ReadSubChunk();
//int StartManagerReadSequence(CKGUID* guid);
//CKGUID ReadGuid();
//void ReadAndFillBuffer_LEndian(void* buffer);
//void ReadAndFillBuffer_LEndian16(void* buffer);
//float ReadFloat();
//CKWORD ReadWord();
//CKDWORD ReadDword();
//CKDWORD ReadDwordAsWords();
//void ReadVector(VxMath::VxVector* v);
//void ReadMatrix(VxMath::VxMatrix& mat);
//CKObjectImplements::CKObject* ReadObject(CKMinContext*);
//void ReadAndFillBuffer(void* buffer);
//CKBYTE* ReadRawBitmap(VxMath::VxImageDescEx& desc);
//XObjectArray ReadXObjectArray(void);
#pragma endregion
#pragma region Write Function
public:
void StartWrite();
//void WriteIdentifier(CKDWORD id);
//void AddChunkAndDelete(CKStateChunk*);
//void StartObjectIDSequence(int count);
//void WriteObjectSequence(CKObjectImplements::CKObject* obj);
//void WriteInt(int data);
//void WriteFloat(float data);
//void WriteDword(CKDWORD data);
//void WriteDwordAsWords(CKDWORD data);
//void WriteVector(const VxMath::VxVector* v);
//void WriteMatrix(const VxMath::VxMatrix& mat);
//void WriteObject(CKObjectImplements::CKObject* obj);
//void WriteBuffer_LEndian(int size, void* buf);
//void WriteBuffer_LEndian16(int size, void* buf);
//void WriteBufferNoSize_LEndian(int size, void* buf);
///*void UpdateDataSize();*/
//void* LockWriteBuffer(int DwordCount);
/*
* Old Name: CloseChunk();
*/
void StopWrite(void);
#pragma endregion
};
}

340
LibCmo/CK2/CKTypes.hpp Normal file
View File

@ -0,0 +1,340 @@
#pragma once
#include <string>
#include <vector>
#include <cstring>
#include <cinttypes>
/**
* @brief The CK2 part of LibCmo.
* These classes are prefixed with CK in original Virtools SDK.
*/
namespace LibCmo::CK2 {
/**
@brief Unique Identifier for all Objects instanciated in a given CKContext
@remarks
+ Each instance of CKObject and derived classes are automatically given a global unique
ID at creation time. This ID can be accessed through the CKObject::GetID method.
It is safer, though a bit slower, to reference object through their global ID than through
a direct pointer reference. In any case the referenced object may be deleted even though
the client object has a ID for it. The client object should verify that the referenced object
still exists when used with the CKGetObject function.
+ The global ID for an instance remains unique and unchanged through a application session, but there
is no garanty that this ID will be the same when a level is saved and loaded back again.
@see CKObject::GetID, CKContext::GetObject
*/
using CK_ID = uint32_t;
enum class CKERROR : int32_t {
CKERR_OK = 0, /**< Operation successful */
CKERR_INVALIDPARAMETER = -1, /**< One of the parameter passed to the function was invalid */
CKERR_INVALIDPARAMETERTYPE = -2, /**< One of the parameter passed to the function was invalid */
CKERR_INVALIDSIZE = -3, /**< The parameter size was invalid */
CKERR_INVALIDOPERATION = -4, /**< The operation type didn't exist */
CKERR_OPERATIONNOTIMPLEMENTED = -5, /**< The function used to execute the operation is not yet implemented */
CKERR_OUTOFMEMORY = -6, /**< There was not enough memory to perform the action */
CKERR_NOTIMPLEMENTED = -7, /**< The function is not yet implemented */
CKERR_NOTFOUND = -11, /**< There was an attempt to remove something not present */
CKERR_NOLEVEL = -13, /**< There is no level currently created */
CKERR_CANCREATERENDERCONTEXT = -14, /**< */
CKERR_NOTIFICATIONNOTHANDLED = -16, /**< The notification message was not used */
CKERR_ALREADYPRESENT = -17, /**< Attempt to add an item that was already present */
CKERR_INVALIDRENDERCONTEXT = -18, /**< the render context is not valid */
CKERR_RENDERCONTEXTINACTIVE = -19, /**< the render context is not activated for rendering */
CKERR_NOLOADPLUGINS = -20, /**< there was no plugins to load this kind of file */
CKERR_NOSAVEPLUGINS = -21, /**< there was no plugins to save this kind of file */
CKERR_INVALIDFILE = -22, /**< attempt to load an invalid file */
CKERR_INVALIDPLUGIN = -23, /**< attempt to load with an invalid plugin */
CKERR_NOTINITIALIZED = -24, /**< attempt use an object that wasnt initialized */
CKERR_INVALIDMESSAGE = -25, /**< attempt use a message type that wasn't registred */
CKERR_INVALIDPROTOTYPE = -28, /**< attempt use an invalid prototype */
CKERR_NODLLFOUND = -29, /**< No dll file found in the parse directory */
CKERR_ALREADYREGISTREDDLL = -30, /**< this dll has already been registred */
CKERR_INVALIDDLL = -31, /**< this dll does not contain information to create the prototype */
CKERR_INVALIDOBJECT = -34, /**< Invalid Object (attempt to Get an object from an invalid ID) */
CKERR_INVALIDCONDSOLEWINDOW = -35, /**< Invalid window was provided as console window */
CKERR_INVALIDKINEMATICCHAIN = -36, /**< Invalid kinematic chain ( end and start effector may not be part of the same hierarchy ) */
CKERR_NOKEYBOARD = -37, /**< Keyboard not attached or not working properly */
CKERR_NOMOUSE = -38, /**< Mouse not attached or not working properly */
CKERR_NOJOYSTICK = -39, /**< Joystick not attached or not working properly */
CKERR_INCOMPATIBLEPARAMETERS = -40, /**< Try to link imcompatible Parameters */
CKERR_NORENDERENGINE = -44, /**< There is no render engine dll */
CKERR_NOCURRENTLEVEL = -45, /**< There is no current level (use CKSetCurrentLevel ) */
CKERR_SOUNDDISABLED = -46, /**< Sound Management has been disabled */
CKERR_DINPUTDISABLED = -47, /**< DirectInput Management has been disabled */
CKERR_INVALIDGUID = -48, /**< Guid is already in use or invalid */
CKERR_NOTENOUGHDISKPLACE = -49, /**< There was no more free space on disk when trying to save a file */
CKERR_CANTWRITETOFILE = -50, /**< Impossible to write to file (write-protection ?) */
CKERR_BEHAVIORADDDENIEDBYCB = -51, /**< The behavior cannnot be added to this entity */
CKERR_INCOMPATIBLECLASSID = -52, /**< The behavior cannnot be added to this entity */
CKERR_MANAGERALREADYEXISTS = -53, /**< A manager was registered more than once */
CKERR_PAUSED = -54, /**< CKprocess or TimeManager process while CK is paused will fail */
CKERR_PLUGINSMISSING = -55, /**< Some plugins were missing whileloading a file */
CKERR_OBSOLETEVIRTOOLS = -56, /**< Virtools version too old to load this file */
CKERR_FILECRCERROR = -57, /**< CRC Error while loading file */
CKERR_ALREADYFULLSCREEN = -58, /**< A Render context is already in Fullscreen Mode */
CKERR_CANCELLED = -59, /**< Operation was cancelled by user */
CKERR_NOANIMATIONKEY = -121, /**< there were no animation key at the given index */
CKERR_INVALIDINDEX = -122, /**< attemp to acces an animation key with an invalid index */
CKERR_INVALIDANIMATION = -123, /**< the animation is invalid (no entity associated or zero length) */
};
/**
@brief Per Class Unique Identifier.
@remark
+ Each class derived from the CKObject class has a unique class ID.
+ This ID can be accessed through each instance of these classes, with the
CKObject::GetClassID method.
+ This class ID is used internally for various matching operations, like matching behaviors on
objects, etc..
@see CKObject::GetClassID, CKIsChildClassOf, Class Identifiers
*/
enum class CK_CLASSID : int32_t {
CKCID_OBJECT = 1,
CKCID_PARAMETERIN = 2,
CKCID_PARAMETEROPERATION = 4,
CKCID_STATE = 5,
CKCID_BEHAVIORLINK = 6,
CKCID_BEHAVIOR = 8,
CKCID_BEHAVIORIO = 9,
CKCID_RENDERCONTEXT = 12,
CKCID_KINEMATICCHAIN = 13,
CKCID_SCENEOBJECT = 11,
CKCID_OBJECTANIMATION = 15,
CKCID_ANIMATION = 16,
CKCID_KEYEDANIMATION = 18,
CKCID_BEOBJECT = 19,
CKCID_DATAARRAY = 52,
CKCID_SCENE = 10,
CKCID_LEVEL = 21,
CKCID_PLACE = 22,
CKCID_GROUP = 23,
CKCID_SOUND = 24,
CKCID_WAVESOUND = 25,
CKCID_MIDISOUND = 26,
CKCID_MATERIAL = 30,
CKCID_TEXTURE = 31,
CKCID_MESH = 32,
CKCID_PATCHMESH = 53,
CKCID_RENDEROBJECT = 47,
CKCID_2DENTITY = 27,
CKCID_SPRITE = 28,
CKCID_SPRITETEXT = 29,
CKCID_3DENTITY = 33,
CKCID_GRID = 50,
CKCID_CURVEPOINT = 36,
CKCID_SPRITE3D = 37,
CKCID_CURVE = 43,
CKCID_CAMERA = 34,
CKCID_TARGETCAMERA = 35,
CKCID_LIGHT = 38,
CKCID_TARGETLIGHT = 39,
CKCID_CHARACTER = 40,
CKCID_3DOBJECT = 41,
CKCID_BODYPART = 42,
CKCID_PARAMETER = 46,
CKCID_PARAMETERLOCAL = 45,
CKCID_PARAMETEROUT = 3,
CKCID_INTERFACEOBJECTMANAGER = 48,
CKCID_CRITICALSECTION = 49,
CKCID_LAYER = 51,
CKCID_PROGRESSIVEMESH = 54,
CKCID_SYNCHRO = 20,
CKCID_OBJECTARRAY = 80,
CKCID_SCENEOBJECTDESC = 81,
CKCID_ATTRIBUTEMANAGER = 82,
CKCID_MESSAGEMANAGER = 83,
CKCID_COLLISIONMANAGER = 84,
CKCID_OBJECTMANAGER = 85,
CKCID_FLOORMANAGER = 86,
CKCID_RENDERMANAGER = 87,
CKCID_BEHAVIORMANAGER = 88,
CKCID_INPUTMANAGER = 89,
CKCID_PARAMETERMANAGER = 90,
CKCID_GRIDMANAGER = 91,
CKCID_SOUNDMANAGER = 92,
CKCID_TIMEMANAGER = 93,
CKCID_CUIKBEHDATA = -1,
CKCID_MAXCLASSID = 55,
CKCID_MAXMAXCLASSID = 128,
};
// ========== Type Definition ==========
using CKMUTSTRING = char*;
using CKSTRING = const char*;
using CKCHAR = char;
using CKBOOL = int32_t;
using CKBYTE = uint8_t;
using CKDWORD = uint32_t;
using CKWORD = uint16_t;
using CKINT = int32_t;
using CKParameterType = int32_t;
using CKOperationType = int32_t;
using CKMessageType = int32_t;
using CKAttributeType = int32_t;
using CKAttributeCategory = int32_t;
// ========== Class List ==========
// Objects and derivated classes
class CKObject;
class CKInterfaceObjectManager;
class CKRenderContext;
class CKParameterIn;
class CKParameter;
class CKParameterOut;
class CKParameterLocal;
class CKParameterOperation;
class CKBehaviorLink;
class CKBehaviorIO;
class CKRenderContext;
class CKSynchroObject;
class CKStateObject;
class CKCriticalSectionObject;
class CKKinematicChain;
class CKObjectAnimation;
class CKLayer;
class CKSceneObject;
class CKBehavior;
class CKAnimation;
class CKKeyedAnimation;
class CKBeObject;
class CKScene;
class CKLevel;
class CKPlace;
class CKGroup;
class CKMaterial;
class CKTexture;
class CKMesh;
class CKPatchMesh;
class CKProgressiveMesh;
class CKDataArray;
class CKSound;
class CKMidiSound;
class CKWaveSound;
class CKRenderObject;
class CK2dEntity;
class CKSprite;
class CKSpriteText;
class CK3dEntity;
class CKCamera;
class CKTargetCamera;
class CKCurvePoint;
class CKSprite3D;
class CKLight;
class CKTargetLight;
class CKCharacter;
class CK3dObject;
class CKBodyPart;
class CKCurve;
class CKGrid;
//---- Misc
class CKBehaviorPrototype;
class CKMessage;
class CK2dCurvePoint;
class CK2dCurve;
class CKStateChunk;
class CKFile;
class CKDependencies;
class CKDependenciesContext;
class CKPluginManager;
class CKDebugContext;
class CKObjectArray;
class CKObjectDeclaration;
class CKContext;
struct CKBitmapProperties;
class CKVertexBuffer;
//--- Managers
class CKBaseManager;
class CKSoundManager;
class CKTimeManager;
class CKRenderManager;
class CKBehaviorManager;
class CKMessageManager;
class CKParameterManager;
class CKAttributeManager;
class CKPathManager;
class CKVariableManager;
class CKSceneObjectDesc;
//--- Important classes
class CKContext;
class CKStateChunk;
class CKFile;
/**
@brief Global Unique Identifier Struture.
@remark
+ Guids are used to uniquely identify plugins,operation types, parameter types and behavior prototypes.
+ Its defined as
```
typedef struct CKGUID {
union {
struct { CKDWORD d1,d2; };
CKDWORD d[2];
};
};
```
+ Comparison operators are defined so CKGUIDS can be compared with
==, != , <, > operators.
@see Pre-Registred Parameter Types, ParameterOperation Types
*/
struct CKGUID {
CKDWORD d1, d2;
constexpr CKGUID(CKDWORD gd1 = 0, CKDWORD gd2 = 0) : d1(gd1), d2(gd2) {}
CKGUID(const CKGUID& rhs) : d1(rhs.d1), d2(rhs.d2) {}
CKGUID& operator=(const CKGUID& rhs) {
this->d1 = rhs.d1;
this->d2 = rhs.d2;
return *this;
}
bool operator ==(const CKGUID& rhs) const {
return ((this->d1 == rhs.d1) && (this->d2 == rhs.d2));
}
bool operator !=(const CKGUID& rhs) const {
return ((this->d1 != rhs.d1) || (this->d2 != rhs.d2));
}
bool operator <(const CKGUID& rhs) const {
if (this->d1 < rhs.d1) {
return true;
}
if (this->d1 == rhs.d1) {
return (this->d2 < rhs.d2);
}
return false;
}
bool operator <=(const CKGUID& rhs) const {
return (this->d1 <= rhs.d1);
}
bool operator >(const CKGUID& rhs) const {
if (this->d1 > rhs.d1) {
return true;
}
if (this->d1 == rhs.d1) {
return (this->d2 > rhs.d2);
}
return false;
}
bool operator >=(const CKGUID& rhs) const {
return (this->d1 >= rhs.d1);
}
};
}