refactor: update project

- add documentation CMake build script. re-organise document layout for future changes.
- move LIBCMO_EXPORT to BMap and rename it to BMAP_EXPORT because only BMap need to use this macro.
- fully refactor VTEncoding to make it more like Python
	- Now language name is platform independent.
	- Hide implementation detail as possible as I can.
	- Language mapping are still work in progress.
- add code gen for new added universal encoding feature to generate language name mapping in Windows and Iconv respectively.
- remove old code of CMake build script.
- update VTUtils for new requirement.
	- remove useless functions.
	- create LibCmo specific custom exception classes.
This commit is contained in:
yyc12345 2024-08-16 22:07:23 +08:00
parent afa06339b2
commit f870d4dde3
20 changed files with 1013 additions and 726 deletions

View File

@ -721,14 +721,14 @@ bool BMMaterial_SetZFunc(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::
#pragma region CKMesh
LIBCMO_EXPORT bool BMMesh_GetLitMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXMESH_LITMODE, out_mode)) {
bool BMMesh_GetLitMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXMESH_LITMODE, out_mode)) {
auto obj = CheckCKMesh(bmfile, objid);
if (obj == nullptr) return false;
BMPARAM_OUT_ASSIGN(out_mode, obj->GetLitMode());
return true;
}
LIBCMO_EXPORT bool BMMesh_SetLitMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXMESH_LITMODE, mode)) {
bool BMMesh_SetLitMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXMESH_LITMODE, mode)) {
auto obj = CheckCKMesh(bmfile, objid);
if (obj == nullptr) return false;

View File

@ -11,7 +11,7 @@
All exported interface functions will always return a bool to indicate whether current operations is successful.
The layout of interface functions' parameters is Essential Param -> Input Param -> Out Param.
A example is in there: `LIBCMO_EXPORT bool BMSomeFunc(BMPARAM_OBJECT_DECL, BMPARAM_IN(LibCmo::CK2::CK_ID, someobj), BMPARAM_OUT(LibCmo::CKSTRING, out_name));`
A example is in there: `BMAP_EXPORT bool BMSomeFunc(BMPARAM_OBJECT_DECL, BMPARAM_IN(LibCmo::CK2::CK_ID, someobj), BMPARAM_OUT(LibCmo::CKSTRING, out_name));`
First param is `BMPARAM_OBJECT_DECL`. It is essential param for this function. In this exmaple, it is the combination of BMFile* and CK_ID. If your provide invalid value for them, the function will failed immediately.
Second param is `BMPARAM_IN(LibCmo::CK2::CK_ID, someobj)`. It declare this function accept a Object ID for underlying function calling.
Last param is `BMPARAM_OUT(LibCmo::CKSTRING, out_name)`. It is the return value of this function. Only will be filled when this function success.
@ -31,7 +31,46 @@ Each CK_ID also should be used with its corresponding BMFile*, because each BMfi
*/
// ===== Interface Used Macro =====
#pragma region Macros for Exporting Functions
// Reference: https://stackoverflow.com/questions/2164827/explicitly-exporting-shared-library-functions-in-linux
// Generate macro for import and export respectively.
#if defined(_MSC_VER)
// Microsoft
#define BMAP_RAW_EXPORT __declspec(dllexport)
#define BMAP_RAW_IMPORT __declspec(dllimport)
#elif defined(__GNUC__)
// GCC
#define BMAP_RAW_EXPORT __attribute__((visibility("default")))
#define BMAP_RAW_IMPORT
#elif defined(__clang__)
// Clang
#define BMAP_RAW_EXPORT __attribute__((visibility("default")))
#define BMAP_RAW_IMPORT
#else
// Do nothing and hope for the best?
#define BMAP_RAW_EXPORT
#define BMAP_RAW_IMPORT
#pragma error "Unknown dynamic link import/export semantics."
#endif
// Choosee import or export command according to special macro.
#if defined(BMAP_EXPORTING)
#define BMAP_NAKED_EXPORT BMAP_RAW_EXPORT
#else
#define BMAP_NAKED_EXPORT BMAP_RAW_IMPORT
#endif
// Create real export macro according to whether in C++ environment.
#if defined(__cplusplus)
#define BMAP_EXPORT extern "C" BMAP_NAKED_EXPORT
#else
#define BMAP_EXPORT BMAP_NAKED_EXPORT
#endif
#pragma endregion
#pragma region Interface Used Macros
/** The first param used by BMFile function family */
#define BMPARAM_FILE_DECL(_bmfile) BMap::BMFile* _bmfile
@ -61,16 +100,18 @@ bool some_interface_func(BMPARAM_OUT(Type_t, param_name)) {
/** Visit value for out param in function body. */
#define BMPARAM_OUT_VAL(_name) (*(_name))
#pragma endregion
#pragma region Init / Dispose
LIBCMO_EXPORT bool BMInit();
LIBCMO_EXPORT bool BMDispose();
BMAP_EXPORT bool BMInit();
BMAP_EXPORT bool BMDispose();
#pragma endregion
#pragma region BMFile
LIBCMO_EXPORT bool BMFile_Load(
BMAP_EXPORT bool BMFile_Load(
BMPARAM_IN(LibCmo::CKSTRING, file_name),
BMPARAM_IN(LibCmo::CKSTRING, temp_folder),
BMPARAM_IN(LibCmo::CKSTRING, texture_folder),
@ -79,7 +120,7 @@ LIBCMO_EXPORT bool BMFile_Load(
BMPARAM_IN(LibCmo::CKSTRING*, encodings),
BMPARAM_OUT(BMap::BMFile*, out_file)
);
LIBCMO_EXPORT bool BMFile_Create(
BMAP_EXPORT bool BMFile_Create(
BMPARAM_IN(LibCmo::CKSTRING, temp_folder),
BMPARAM_IN(LibCmo::CKSTRING, texture_folder),
BMPARAM_IN(BMap::NakedOutputCallback, raw_callback),
@ -87,170 +128,170 @@ LIBCMO_EXPORT bool BMFile_Create(
BMPARAM_IN(LibCmo::CKSTRING*, encodings),
BMPARAM_OUT(BMap::BMFile*, out_file)
);
LIBCMO_EXPORT bool BMFile_Save(
BMAP_EXPORT bool BMFile_Save(
BMPARAM_IN(BMap::BMFile*, map_file),
BMPARAM_IN(LibCmo::CKSTRING, file_name),
BMPARAM_IN(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS, texture_save_opt),
BMPARAM_IN(bool, use_compress),
BMPARAM_IN(LibCmo::CKINT, compreess_level)
);
LIBCMO_EXPORT bool BMFile_Free(
BMAP_EXPORT bool BMFile_Free(
BMPARAM_IN(BMap::BMFile*, map_file)
);
LIBCMO_EXPORT bool BMFile_GetGroupCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
LIBCMO_EXPORT bool BMFile_GetGroup(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
LIBCMO_EXPORT bool BMFile_CreateGroup(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
LIBCMO_EXPORT bool BMFile_Get3dObjectCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
LIBCMO_EXPORT bool BMFile_Get3dObject(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
LIBCMO_EXPORT bool BMFile_Create3dObject(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
LIBCMO_EXPORT bool BMFile_GetMeshCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
LIBCMO_EXPORT bool BMFile_GetMesh(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
LIBCMO_EXPORT bool BMFile_CreateMesh(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
LIBCMO_EXPORT bool BMFile_GetMaterialCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
LIBCMO_EXPORT bool BMFile_GetMaterial(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
LIBCMO_EXPORT bool BMFile_CreateMaterial(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
LIBCMO_EXPORT bool BMFile_GetTextureCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
LIBCMO_EXPORT bool BMFile_GetTexture(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
LIBCMO_EXPORT bool BMFile_CreateTexture(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
BMAP_EXPORT bool BMFile_GetGroupCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
BMAP_EXPORT bool BMFile_GetGroup(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
BMAP_EXPORT bool BMFile_CreateGroup(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
BMAP_EXPORT bool BMFile_Get3dObjectCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
BMAP_EXPORT bool BMFile_Get3dObject(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
BMAP_EXPORT bool BMFile_Create3dObject(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
BMAP_EXPORT bool BMFile_GetMeshCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
BMAP_EXPORT bool BMFile_GetMesh(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
BMAP_EXPORT bool BMFile_CreateMesh(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
BMAP_EXPORT bool BMFile_GetMaterialCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
BMAP_EXPORT bool BMFile_GetMaterial(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
BMAP_EXPORT bool BMFile_CreateMaterial(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
BMAP_EXPORT bool BMFile_GetTextureCount(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
BMAP_EXPORT bool BMFile_GetTexture(BMPARAM_FILE_DECL(bmfile), BMPARAM_IN(LibCmo::CKDWORD, idx), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
BMAP_EXPORT bool BMFile_CreateTexture(BMPARAM_FILE_DECL(bmfile), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_id));
#pragma endregion
#pragma region BMMeshTransition
LIBCMO_EXPORT bool BMMeshTrans_New(BMPARAM_OUT(BMap::BMMeshTransition*, out_trans));
LIBCMO_EXPORT bool BMMeshTrans_Delete(BMPARAM_IN(BMap::BMMeshTransition*, trans));
BMAP_EXPORT bool BMMeshTrans_New(BMPARAM_OUT(BMap::BMMeshTransition*, out_trans));
BMAP_EXPORT bool BMMeshTrans_Delete(BMPARAM_IN(BMap::BMMeshTransition*, trans));
LIBCMO_EXPORT bool BMMeshTrans_PrepareVertexCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count));
LIBCMO_EXPORT bool BMMeshTrans_PrepareVertex(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::VxMath::VxVector3*, out_mem));
LIBCMO_EXPORT bool BMMeshTrans_PrepareNormalCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count));
LIBCMO_EXPORT bool BMMeshTrans_PrepareNormal(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::VxMath::VxVector3*, out_mem));
LIBCMO_EXPORT bool BMMeshTrans_PrepareUVCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count));
LIBCMO_EXPORT bool BMMeshTrans_PrepareUV(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::VxMath::VxVector2*, out_mem));
LIBCMO_EXPORT bool BMMeshTrans_PrepareMtlSlotCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count));
LIBCMO_EXPORT bool BMMeshTrans_PrepareMtlSlot(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CK2::CK_ID*, out_mem));
LIBCMO_EXPORT bool BMMeshTrans_PrepareFaceCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count));
LIBCMO_EXPORT bool BMMeshTrans_PrepareFaceVertexIndices(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem));
LIBCMO_EXPORT bool BMMeshTrans_PrepareFaceNormalIndices(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem));
LIBCMO_EXPORT bool BMMeshTrans_PrepareFaceUVIndices(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem));
LIBCMO_EXPORT bool BMMeshTrans_PrepareFaceMtlSlot(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem));
LIBCMO_EXPORT bool BMMeshTrans_Parse(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(BMap::BMFile*, bmfile), BMPARAM_IN(LibCmo::CK2::CK_ID, objid));
BMAP_EXPORT bool BMMeshTrans_PrepareVertexCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count));
BMAP_EXPORT bool BMMeshTrans_PrepareVertex(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::VxMath::VxVector3*, out_mem));
BMAP_EXPORT bool BMMeshTrans_PrepareNormalCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count));
BMAP_EXPORT bool BMMeshTrans_PrepareNormal(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::VxMath::VxVector3*, out_mem));
BMAP_EXPORT bool BMMeshTrans_PrepareUVCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count));
BMAP_EXPORT bool BMMeshTrans_PrepareUV(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::VxMath::VxVector2*, out_mem));
BMAP_EXPORT bool BMMeshTrans_PrepareMtlSlotCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count));
BMAP_EXPORT bool BMMeshTrans_PrepareMtlSlot(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CK2::CK_ID*, out_mem));
BMAP_EXPORT bool BMMeshTrans_PrepareFaceCount(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(LibCmo::CKDWORD, count));
BMAP_EXPORT bool BMMeshTrans_PrepareFaceVertexIndices(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem));
BMAP_EXPORT bool BMMeshTrans_PrepareFaceNormalIndices(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem));
BMAP_EXPORT bool BMMeshTrans_PrepareFaceUVIndices(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem));
BMAP_EXPORT bool BMMeshTrans_PrepareFaceMtlSlot(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_OUT(LibCmo::CKDWORD*, out_mem));
BMAP_EXPORT bool BMMeshTrans_Parse(BMPARAM_MESHTRANS_DECL(trans), BMPARAM_IN(BMap::BMFile*, bmfile), BMPARAM_IN(LibCmo::CK2::CK_ID, objid));
#pragma endregion
#pragma region CKObject
LIBCMO_EXPORT bool BMObject_GetName(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKSTRING, out_name));
LIBCMO_EXPORT bool BMObject_SetName(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKSTRING, name));
BMAP_EXPORT bool BMObject_GetName(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKSTRING, out_name));
BMAP_EXPORT bool BMObject_SetName(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKSTRING, name));
#pragma endregion
#pragma region CKGroup
LIBCMO_EXPORT bool BMGroup_AddObject(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, memberid));
LIBCMO_EXPORT bool BMGroup_GetObjectCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
LIBCMO_EXPORT bool BMGroup_GetObject(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, pos), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_objid));
BMAP_EXPORT bool BMGroup_AddObject(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, memberid));
BMAP_EXPORT bool BMGroup_GetObjectCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
BMAP_EXPORT bool BMGroup_GetObject(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, pos), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_objid));
#pragma endregion
#pragma region CKTexture
LIBCMO_EXPORT bool BMTexture_GetFileName(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKSTRING, out_filename));
LIBCMO_EXPORT bool BMTexture_LoadImage(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKSTRING, filename));
LIBCMO_EXPORT bool BMTexture_SaveImage(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKSTRING, filename));
LIBCMO_EXPORT bool BMTexture_GetSaveOptions(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS, out_saveopt));
LIBCMO_EXPORT bool BMTexture_SetSaveOptions(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS, saveopt));
LIBCMO_EXPORT bool BMTexture_GetVideoFormat(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VX_PIXELFORMAT, out_vfmt));
LIBCMO_EXPORT bool BMTexture_SetVideoFormat(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VX_PIXELFORMAT, vfmt));
BMAP_EXPORT bool BMTexture_GetFileName(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKSTRING, out_filename));
BMAP_EXPORT bool BMTexture_LoadImage(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKSTRING, filename));
BMAP_EXPORT bool BMTexture_SaveImage(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKSTRING, filename));
BMAP_EXPORT bool BMTexture_GetSaveOptions(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS, out_saveopt));
BMAP_EXPORT bool BMTexture_SetSaveOptions(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS, saveopt));
BMAP_EXPORT bool BMTexture_GetVideoFormat(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VX_PIXELFORMAT, out_vfmt));
BMAP_EXPORT bool BMTexture_SetVideoFormat(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VX_PIXELFORMAT, vfmt));
#pragma endregion
#pragma region CKMaterial
LIBCMO_EXPORT bool BMMaterial_GetDiffuse(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxColor, out_val));
LIBCMO_EXPORT bool BMMaterial_SetDiffuse(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxColor, col));
LIBCMO_EXPORT bool BMMaterial_GetAmbient(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxColor, out_val));
LIBCMO_EXPORT bool BMMaterial_SetAmbient(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxColor, col));
LIBCMO_EXPORT bool BMMaterial_GetSpecular(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxColor, out_val));
LIBCMO_EXPORT bool BMMaterial_SetSpecular(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxColor, col));
LIBCMO_EXPORT bool BMMaterial_GetEmissive(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxColor, out_val));
LIBCMO_EXPORT bool BMMaterial_SetEmissive(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxColor, col));
LIBCMO_EXPORT bool BMMaterial_GetSpecularPower(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val));
LIBCMO_EXPORT bool BMMaterial_SetSpecularPower(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val));
BMAP_EXPORT bool BMMaterial_GetDiffuse(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxColor, out_val));
BMAP_EXPORT bool BMMaterial_SetDiffuse(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxColor, col));
BMAP_EXPORT bool BMMaterial_GetAmbient(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxColor, out_val));
BMAP_EXPORT bool BMMaterial_SetAmbient(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxColor, col));
BMAP_EXPORT bool BMMaterial_GetSpecular(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxColor, out_val));
BMAP_EXPORT bool BMMaterial_SetSpecular(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxColor, col));
BMAP_EXPORT bool BMMaterial_GetEmissive(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxColor, out_val));
BMAP_EXPORT bool BMMaterial_SetEmissive(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxColor, col));
BMAP_EXPORT bool BMMaterial_GetSpecularPower(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKFLOAT, out_val));
BMAP_EXPORT bool BMMaterial_SetSpecularPower(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKFLOAT, val));
LIBCMO_EXPORT bool BMMaterial_GetTexture(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_texid));
LIBCMO_EXPORT bool BMMaterial_SetTexture(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, texid));
LIBCMO_EXPORT bool BMMaterial_GetTextureBorderColor(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_val));
LIBCMO_EXPORT bool BMMaterial_SetTextureBorderColor(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, val));
BMAP_EXPORT bool BMMaterial_GetTexture(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_texid));
BMAP_EXPORT bool BMMaterial_SetTexture(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, texid));
BMAP_EXPORT bool BMMaterial_GetTextureBorderColor(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_val));
BMAP_EXPORT bool BMMaterial_SetTextureBorderColor(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, val));
LIBCMO_EXPORT bool BMMaterial_GetTextureBlendMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXTEXTURE_BLENDMODE, out_val));
LIBCMO_EXPORT bool BMMaterial_SetTextureBlendMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXTEXTURE_BLENDMODE, val));
LIBCMO_EXPORT bool BMMaterial_GetTextureMinMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXTEXTURE_FILTERMODE, out_val));
LIBCMO_EXPORT bool BMMaterial_SetTextureMinMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXTEXTURE_FILTERMODE, val));
LIBCMO_EXPORT bool BMMaterial_GetTextureMagMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXTEXTURE_FILTERMODE, out_val));
LIBCMO_EXPORT bool BMMaterial_SetTextureMagMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXTEXTURE_FILTERMODE, val));
LIBCMO_EXPORT bool BMMaterial_GetTextureAddressMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXTEXTURE_ADDRESSMODE, out_val));
LIBCMO_EXPORT bool BMMaterial_SetTextureAddressMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXTEXTURE_ADDRESSMODE, val));
BMAP_EXPORT bool BMMaterial_GetTextureBlendMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXTEXTURE_BLENDMODE, out_val));
BMAP_EXPORT bool BMMaterial_SetTextureBlendMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXTEXTURE_BLENDMODE, val));
BMAP_EXPORT bool BMMaterial_GetTextureMinMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXTEXTURE_FILTERMODE, out_val));
BMAP_EXPORT bool BMMaterial_SetTextureMinMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXTEXTURE_FILTERMODE, val));
BMAP_EXPORT bool BMMaterial_GetTextureMagMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXTEXTURE_FILTERMODE, out_val));
BMAP_EXPORT bool BMMaterial_SetTextureMagMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXTEXTURE_FILTERMODE, val));
BMAP_EXPORT bool BMMaterial_GetTextureAddressMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXTEXTURE_ADDRESSMODE, out_val));
BMAP_EXPORT bool BMMaterial_SetTextureAddressMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXTEXTURE_ADDRESSMODE, val));
LIBCMO_EXPORT bool BMMaterial_GetSourceBlend(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXBLEND_MODE, out_val));
LIBCMO_EXPORT bool BMMaterial_SetSourceBlend(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXBLEND_MODE, val));
LIBCMO_EXPORT bool BMMaterial_GetDestBlend(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXBLEND_MODE, out_val));
LIBCMO_EXPORT bool BMMaterial_SetDestBlend(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXBLEND_MODE, val));
LIBCMO_EXPORT bool BMMaterial_GetFillMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXFILL_MODE, out_val));
LIBCMO_EXPORT bool BMMaterial_SetFillMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXFILL_MODE, val));
LIBCMO_EXPORT bool BMMaterial_GetShadeMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXSHADE_MODE, out_val));
LIBCMO_EXPORT bool BMMaterial_SetShadeMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXSHADE_MODE, val));
BMAP_EXPORT bool BMMaterial_GetSourceBlend(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXBLEND_MODE, out_val));
BMAP_EXPORT bool BMMaterial_SetSourceBlend(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXBLEND_MODE, val));
BMAP_EXPORT bool BMMaterial_GetDestBlend(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXBLEND_MODE, out_val));
BMAP_EXPORT bool BMMaterial_SetDestBlend(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXBLEND_MODE, val));
BMAP_EXPORT bool BMMaterial_GetFillMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXFILL_MODE, out_val));
BMAP_EXPORT bool BMMaterial_SetFillMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXFILL_MODE, val));
BMAP_EXPORT bool BMMaterial_GetShadeMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXSHADE_MODE, out_val));
BMAP_EXPORT bool BMMaterial_SetShadeMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXSHADE_MODE, val));
LIBCMO_EXPORT bool BMMaterial_GetAlphaTestEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_val));
LIBCMO_EXPORT bool BMMaterial_SetAlphaTestEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, enabled));
LIBCMO_EXPORT bool BMMaterial_GetAlphaBlendEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_val));
LIBCMO_EXPORT bool BMMaterial_SetAlphaBlendEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, enabled));
LIBCMO_EXPORT bool BMMaterial_GetPerspectiveCorrectionEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_val));
LIBCMO_EXPORT bool BMMaterial_SetPerspectiveCorrectionEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, enabled));
LIBCMO_EXPORT bool BMMaterial_GetZWriteEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_val));
LIBCMO_EXPORT bool BMMaterial_SetZWriteEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, enabled));
LIBCMO_EXPORT bool BMMaterial_GetTwoSidedEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_val));
LIBCMO_EXPORT bool BMMaterial_SetTwoSidedEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, enabled));
BMAP_EXPORT bool BMMaterial_GetAlphaTestEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_val));
BMAP_EXPORT bool BMMaterial_SetAlphaTestEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, enabled));
BMAP_EXPORT bool BMMaterial_GetAlphaBlendEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_val));
BMAP_EXPORT bool BMMaterial_SetAlphaBlendEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, enabled));
BMAP_EXPORT bool BMMaterial_GetPerspectiveCorrectionEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_val));
BMAP_EXPORT bool BMMaterial_SetPerspectiveCorrectionEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, enabled));
BMAP_EXPORT bool BMMaterial_GetZWriteEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_val));
BMAP_EXPORT bool BMMaterial_SetZWriteEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, enabled));
BMAP_EXPORT bool BMMaterial_GetTwoSidedEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_val));
BMAP_EXPORT bool BMMaterial_SetTwoSidedEnabled(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, enabled));
LIBCMO_EXPORT bool BMMaterial_GetAlphaRef(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKBYTE, out_val));
LIBCMO_EXPORT bool BMMaterial_SetAlphaRef(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKBYTE, val));
LIBCMO_EXPORT bool BMMaterial_GetAlphaFunc(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXCMPFUNC, out_val));
LIBCMO_EXPORT bool BMMaterial_SetAlphaFunc(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXCMPFUNC, val));
LIBCMO_EXPORT bool BMMaterial_GetZFunc(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXCMPFUNC, out_val));
LIBCMO_EXPORT bool BMMaterial_SetZFunc(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXCMPFUNC, val));
BMAP_EXPORT bool BMMaterial_GetAlphaRef(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKBYTE, out_val));
BMAP_EXPORT bool BMMaterial_SetAlphaRef(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKBYTE, val));
BMAP_EXPORT bool BMMaterial_GetAlphaFunc(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXCMPFUNC, out_val));
BMAP_EXPORT bool BMMaterial_SetAlphaFunc(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXCMPFUNC, val));
BMAP_EXPORT bool BMMaterial_GetZFunc(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXCMPFUNC, out_val));
BMAP_EXPORT bool BMMaterial_SetZFunc(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXCMPFUNC, val));
#pragma endregion
#pragma region CKMesh
LIBCMO_EXPORT bool BMMesh_GetLitMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXMESH_LITMODE, out_mode));
LIBCMO_EXPORT bool BMMesh_SetLitMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXMESH_LITMODE, mode));
BMAP_EXPORT bool BMMesh_GetLitMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VXMESH_LITMODE, out_mode));
BMAP_EXPORT bool BMMesh_SetLitMode(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VXMESH_LITMODE, mode));
LIBCMO_EXPORT bool BMMesh_GetVertexCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
LIBCMO_EXPORT bool BMMesh_SetVertexCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, count));
LIBCMO_EXPORT bool BMMesh_GetVertexPositions(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxVector3*, out_mem));
LIBCMO_EXPORT bool BMMesh_GetVertexNormals(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxVector3*, out_mem));
LIBCMO_EXPORT bool BMMesh_GetVertexUVs(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxVector2*, out_mem));
BMAP_EXPORT bool BMMesh_GetVertexCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
BMAP_EXPORT bool BMMesh_SetVertexCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, count));
BMAP_EXPORT bool BMMesh_GetVertexPositions(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxVector3*, out_mem));
BMAP_EXPORT bool BMMesh_GetVertexNormals(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxVector3*, out_mem));
BMAP_EXPORT bool BMMesh_GetVertexUVs(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxVector2*, out_mem));
LIBCMO_EXPORT bool BMMesh_GetFaceCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
LIBCMO_EXPORT bool BMMesh_SetFaceCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, count));
LIBCMO_EXPORT bool BMMesh_GetFaceIndices(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKWORD*, out_mem));
LIBCMO_EXPORT bool BMMesh_GetFaceMaterialSlotIndexs(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKWORD*, out_mem));
BMAP_EXPORT bool BMMesh_GetFaceCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
BMAP_EXPORT bool BMMesh_SetFaceCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, count));
BMAP_EXPORT bool BMMesh_GetFaceIndices(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKWORD*, out_mem));
BMAP_EXPORT bool BMMesh_GetFaceMaterialSlotIndexs(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKWORD*, out_mem));
LIBCMO_EXPORT bool BMMesh_GetMaterialSlotCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
LIBCMO_EXPORT bool BMMesh_SetMaterialSlotCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, count));
LIBCMO_EXPORT bool BMMesh_GetMaterialSlot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, index), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_mtlid));
LIBCMO_EXPORT bool BMMesh_SetMaterialSlot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, index), BMPARAM_IN(LibCmo::CK2::CK_ID, mtlid));
BMAP_EXPORT bool BMMesh_GetMaterialSlotCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CKDWORD, out_count));
BMAP_EXPORT bool BMMesh_SetMaterialSlotCount(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, count));
BMAP_EXPORT bool BMMesh_GetMaterialSlot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, index), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_mtlid));
BMAP_EXPORT bool BMMesh_SetMaterialSlot(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CKDWORD, index), BMPARAM_IN(LibCmo::CK2::CK_ID, mtlid));
#pragma endregion
#pragma region CK3dObject
LIBCMO_EXPORT bool BM3dObject_GetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxMatrix, out_mat));
LIBCMO_EXPORT bool BM3dObject_SetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxMatrix, mat));
LIBCMO_EXPORT bool BM3dObject_GetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_meshid));
LIBCMO_EXPORT bool BM3dObject_SetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, meshid));
LIBCMO_EXPORT bool BM3dObject_GetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_isVisible));
LIBCMO_EXPORT bool BM3dObject_SetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, is_visible));
BMAP_EXPORT bool BM3dObject_GetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::VxMath::VxMatrix, out_mat));
BMAP_EXPORT bool BM3dObject_SetWorldMatrix(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::VxMath::VxMatrix, mat));
BMAP_EXPORT bool BM3dObject_GetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(LibCmo::CK2::CK_ID, out_meshid));
BMAP_EXPORT bool BM3dObject_SetCurrentMesh(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(LibCmo::CK2::CK_ID, meshid));
BMAP_EXPORT bool BM3dObject_GetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_OUT(bool, out_isVisible));
BMAP_EXPORT bool BM3dObject_SetVisibility(BMPARAM_OBJECT_DECL(bmfile, objid), BMPARAM_IN(bool, is_visible));
#pragma endregion

View File

@ -34,8 +34,12 @@ PROPERTIES
CXX_STANDARD_REQUIRED 20
CXX_EXTENSION OFF
)
# Order Unicode charset for private using
# Setup project macros
target_compile_definitions(BMap
# Enable export macro
PRIVATE
BMAP_EXPORTING
# Order Unicode charset for private using
PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:UNICODE>
$<$<CXX_COMPILER_ID:MSVC>:_UNICODE>
@ -51,69 +55,3 @@ install(TARGETS BMap
CONFIGURATIONS Release
RUNTIME DESTINATION ${YYCC_INSTALL_BIN_PATH}
)
# cmake_minimum_required(VERSION 3.12)
# project(BMap LANGUAGES CXX)
# # add libcmo if not existed
# if (NOT TARGET LibCmo)
# add_subdirectory("../LibCmo" "LibCmo.out")
# endif ()
# # add ironpad if not existed
# if (NOT TARGET IronPad)
# add_subdirectory("../IronPad" "IronPad.out")
# endif ()
# # hide all function in default
# # fix imported library PIC issue (i don't know why. just make it works)
# set_target_properties(LibCmo
# PROPERTIES
# CXX_VISIBILITY_PRESET hidden
# POSITION_INDEPENDENT_CODE ON
# )
# set_target_properties(IronPad
# PROPERTIES
# CXX_VISIBILITY_PRESET hidden
# POSITION_INDEPENDENT_CODE ON
# )
# # setup sources
# set(bmap_headers ".")
# set(bmap_sources
# BMap.cpp
# BMExports.cpp
# )
# # generate shared library
# add_library(BMap
# SHARED
# ${bmap_sources}
# )
# target_link_libraries(BMap
# PRIVATE
# LibCmo
# IronPad
# )
# target_include_directories(BMap
# PRIVATE
# ${bmap_headers}
# )
# # set project standard
# set_target_properties(BMap
# PROPERTIES
# CXX_STANDARD 20
# CXX_STANDARD_REQUIRED 20
# CXX_EXTENSION OFF
# )
# # set default visibility to hidden
# set_target_properties(BMap
# PROPERTIES
# CXX_VISIBILITY_PRESET hidden
# )
# # add export used macro flag
# target_compile_definitions(BMap
# PUBLIC
# LIBCMO_EXPORTING
# )

2
CodeGen/UniversalEncoding/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
# Result
*.cpp

View File

@ -0,0 +1,98 @@
Encoding Alias Code Page Iconv Identifier
ascii 646, us-ascii ASCII
big5 big5-tw, csbig5 950 BIG5
big5hkscs big5-hkscs, hkscs BIG5-HKSCS
cp037 IBM037, IBM039 037
cp273 273, IBM273, csIBM273
cp424 EBCDIC-CP-HE, IBM424
cp437 437, IBM437 437
cp500 EBCDIC-CP-BE, EBCDIC-CP-CH, IBM500 500
cp720 720
cp737 737
cp775 IBM775 775
cp850 850, IBM850 850 CP850
cp852 852, IBM852 852
cp855 855, IBM855 855
cp856
cp857 857, IBM857 857
cp858 858, IBM858 858
cp860 860, IBM860 860
cp861 861, CP-IS, IBM861 861
cp862 862, IBM862 862 CP862
cp863 863, IBM863 863
cp864 IBM864 864
cp865 865, IBM865 865
cp866 866, IBM866 866 CP866
cp869 869, CP-GR, IBM869 869
cp874 874 CP874
cp875 875
cp932 932, ms932, mskanji, ms-kanji, windows-31j 932 CP932
cp949 949, ms949, uhc 949 CP949
cp950 950, ms950 950 CP950
cp1006
cp1026 ibm1026 1026
cp1125 1125, ibm1125, cp866u, ruscii
cp1140 ibm1140 1140
cp1250 windows-1250 1250 CP1250
cp1251 windows-1251 1251 CP1251
cp1252 windows-1252 1252 CP1252
cp1253 windows-1253 1253 CP1253
cp1254 windows-1254 1254 CP1254
cp1255 windows-1255 1255 CP1255
cp1256 windows-1256 1256 CP1256
cp1257 windows-1257 1257 CP1257
cp1258 windows-1258 1258 CP1258
euc_jp eucjp, ujis, u-jis EUC-JP
euc_jis_2004 jisx0213, eucjis2004
euc_jisx0213 eucjisx0213
euc_kr euckr, korean, ksc5601, ks_c-5601, ks_c-5601-1987, ksx1001, ks_x-1001 51949 EUC-KR
gb2312 chinese, csiso58gb231280, euc-cn, euccn, eucgb2312-cn, gb2312-1980, gb2312-80, iso-ir-58
gbk 936, cp936, ms936 936 CP936
gb18030 gb18030-2000 54936 GB18030
hz hzgb, hz-gb, hz-gb-2312 52936 HZ
iso2022_jp csiso2022jp, iso2022jp, iso-2022-jp ISO-2022-JP
iso2022_jp_1 iso2022jp-1, iso-2022-jp-1 ISO-2022-JP-1
iso2022_jp_2 iso2022jp-2, iso-2022-jp-2 ISO-2022-JP-2
iso2022_jp_2004 iso2022jp-2004, iso-2022-jp-2004
iso2022_jp_3 iso2022jp-3, iso-2022-jp-3
iso2022_jp_ext iso2022jp-ext, iso-2022-jp-ext
iso2022_kr csiso2022kr, iso2022kr, iso-2022-kr 50225 ISO-2022-KR
latin_1 iso-8859-1, iso8859-1, 8859, cp819, latin, latin1, L1 28591 ISO-8859-1
iso8859_2 iso-8859-2, latin2, L2 28592 ISO-8859-2
iso8859_3 iso-8859-3, latin3, L3 28593 ISO-8859-3
iso8859_4 iso-8859-4, latin4, L4 28594 ISO-8859-4
iso8859_5 iso-8859-5, cyrillic 28595 ISO-8859-5
iso8859_6 iso-8859-6, arabic 28596 ISO-8859-6
iso8859_7 iso-8859-7, greek, greek8 28597 ISO-8859-7
iso8859_8 iso-8859-8, hebrew 28598 ISO-8859-8
iso8859_9 iso-8859-9, latin5, L5 28599 ISO-8859-9
iso8859_10 iso-8859-10, latin6, L6 ISO-8859-10
iso8859_11 iso-8859-11, thai ISO-8859-11
iso8859_13 iso-8859-13, latin7, L7 28603 ISO-8859-13
iso8859_14 iso-8859-14, latin8, L8 ISO-8859-14
iso8859_15 iso-8859-15, latin9, L9 28605 ISO-8859-15
iso8859_16 iso-8859-16, latin10, L10 ISO-8859-16
johab cp1361, ms1361 1361 JOHAB
koi8_r
koi8_t KOI8-T
koi8_u
kz1048 kz_1048, strk1048_2002, rk1048
mac_cyrillic maccyrillic 10007 MacCyrillic
mac_greek macgreek 10006 MacGreek
mac_iceland maciceland 10079 MacIceland
mac_latin2 maclatin2, maccentraleurope, mac_centeuro
mac_roman macroman, macintosh MacRoman
mac_turkish macturkish 10081 MacTurkish
ptcp154 csptcp154, pt154, cp154, cyrillic-asian PT154
shift_jis csshiftjis, shiftjis, sjis, s_jis 932 SHIFT_JIS
shift_jis_2004 shiftjis2004, sjis_2004, sjis2004
shift_jisx0213 shiftjisx0213, sjisx0213, s_jisx0213
utf_32 U32, utf32 UTF-32
utf_32_be UTF-32BE UTF-32BE
utf_32_le UTF-32LE UTF-32LE
utf_16 U16, utf16 UTF16
utf_16_be UTF-16BE UTF-16BE
utf_16_le UTF-16LE UTF-16LE
utf_7 U7, unicode-1-1-utf-7 65000 UTF-7
utf_8 U8, UTF, utf8, cp65001 65001 UTF-8
utf_8_sig
1 Encoding Alias Code Page Iconv Identifier
2 ascii 646, us-ascii ASCII
3 big5 big5-tw, csbig5 950 BIG5
4 big5hkscs big5-hkscs, hkscs BIG5-HKSCS
5 cp037 IBM037, IBM039 037
6 cp273 273, IBM273, csIBM273
7 cp424 EBCDIC-CP-HE, IBM424
8 cp437 437, IBM437 437
9 cp500 EBCDIC-CP-BE, EBCDIC-CP-CH, IBM500 500
10 cp720 720
11 cp737 737
12 cp775 IBM775 775
13 cp850 850, IBM850 850 CP850
14 cp852 852, IBM852 852
15 cp855 855, IBM855 855
16 cp856
17 cp857 857, IBM857 857
18 cp858 858, IBM858 858
19 cp860 860, IBM860 860
20 cp861 861, CP-IS, IBM861 861
21 cp862 862, IBM862 862 CP862
22 cp863 863, IBM863 863
23 cp864 IBM864 864
24 cp865 865, IBM865 865
25 cp866 866, IBM866 866 CP866
26 cp869 869, CP-GR, IBM869 869
27 cp874 874 CP874
28 cp875 875
29 cp932 932, ms932, mskanji, ms-kanji, windows-31j 932 CP932
30 cp949 949, ms949, uhc 949 CP949
31 cp950 950, ms950 950 CP950
32 cp1006
33 cp1026 ibm1026 1026
34 cp1125 1125, ibm1125, cp866u, ruscii
35 cp1140 ibm1140 1140
36 cp1250 windows-1250 1250 CP1250
37 cp1251 windows-1251 1251 CP1251
38 cp1252 windows-1252 1252 CP1252
39 cp1253 windows-1253 1253 CP1253
40 cp1254 windows-1254 1254 CP1254
41 cp1255 windows-1255 1255 CP1255
42 cp1256 windows-1256 1256 CP1256
43 cp1257 windows-1257 1257 CP1257
44 cp1258 windows-1258 1258 CP1258
45 euc_jp eucjp, ujis, u-jis EUC-JP
46 euc_jis_2004 jisx0213, eucjis2004
47 euc_jisx0213 eucjisx0213
48 euc_kr euckr, korean, ksc5601, ks_c-5601, ks_c-5601-1987, ksx1001, ks_x-1001 51949 EUC-KR
49 gb2312 chinese, csiso58gb231280, euc-cn, euccn, eucgb2312-cn, gb2312-1980, gb2312-80, iso-ir-58
50 gbk 936, cp936, ms936 936 CP936
51 gb18030 gb18030-2000 54936 GB18030
52 hz hzgb, hz-gb, hz-gb-2312 52936 HZ
53 iso2022_jp csiso2022jp, iso2022jp, iso-2022-jp ISO-2022-JP
54 iso2022_jp_1 iso2022jp-1, iso-2022-jp-1 ISO-2022-JP-1
55 iso2022_jp_2 iso2022jp-2, iso-2022-jp-2 ISO-2022-JP-2
56 iso2022_jp_2004 iso2022jp-2004, iso-2022-jp-2004
57 iso2022_jp_3 iso2022jp-3, iso-2022-jp-3
58 iso2022_jp_ext iso2022jp-ext, iso-2022-jp-ext
59 iso2022_kr csiso2022kr, iso2022kr, iso-2022-kr 50225 ISO-2022-KR
60 latin_1 iso-8859-1, iso8859-1, 8859, cp819, latin, latin1, L1 28591 ISO-8859-1
61 iso8859_2 iso-8859-2, latin2, L2 28592 ISO-8859-2
62 iso8859_3 iso-8859-3, latin3, L3 28593 ISO-8859-3
63 iso8859_4 iso-8859-4, latin4, L4 28594 ISO-8859-4
64 iso8859_5 iso-8859-5, cyrillic 28595 ISO-8859-5
65 iso8859_6 iso-8859-6, arabic 28596 ISO-8859-6
66 iso8859_7 iso-8859-7, greek, greek8 28597 ISO-8859-7
67 iso8859_8 iso-8859-8, hebrew 28598 ISO-8859-8
68 iso8859_9 iso-8859-9, latin5, L5 28599 ISO-8859-9
69 iso8859_10 iso-8859-10, latin6, L6 ISO-8859-10
70 iso8859_11 iso-8859-11, thai ISO-8859-11
71 iso8859_13 iso-8859-13, latin7, L7 28603 ISO-8859-13
72 iso8859_14 iso-8859-14, latin8, L8 ISO-8859-14
73 iso8859_15 iso-8859-15, latin9, L9 28605 ISO-8859-15
74 iso8859_16 iso-8859-16, latin10, L10 ISO-8859-16
75 johab cp1361, ms1361 1361 JOHAB
76 koi8_r
77 koi8_t KOI8-T
78 koi8_u
79 kz1048 kz_1048, strk1048_2002, rk1048
80 mac_cyrillic maccyrillic 10007 MacCyrillic
81 mac_greek macgreek 10006 MacGreek
82 mac_iceland maciceland 10079 MacIceland
83 mac_latin2 maclatin2, maccentraleurope, mac_centeuro
84 mac_roman macroman, macintosh MacRoman
85 mac_turkish macturkish 10081 MacTurkish
86 ptcp154 csptcp154, pt154, cp154, cyrillic-asian PT154
87 shift_jis csshiftjis, shiftjis, sjis, s_jis 932 SHIFT_JIS
88 shift_jis_2004 shiftjis2004, sjis_2004, sjis2004
89 shift_jisx0213 shiftjisx0213, sjisx0213, s_jisx0213
90 utf_32 U32, utf32 UTF-32
91 utf_32_be UTF-32BE UTF-32BE
92 utf_32_le UTF-32LE UTF-32LE
93 utf_16 U16, utf16 UTF16
94 utf_16_be UTF-16BE UTF-16BE
95 utf_16_le UTF-16LE UTF-16LE
96 utf_7 U7, unicode-1-1-utf-7 65000 UTF-7
97 utf_8 U8, UTF, utf8, cp65001 65001 UTF-8
98 utf_8_sig

View File

@ -0,0 +1,57 @@
import typing
import io
class LanguageToken:
m_Name: str
m_Alias: tuple[str, ...]
m_CodePage: str | None
m_IconvCode: str | None
def __init__(self, name: str, alias: typing.Iterator[str], code_page: str, iconv_code: str):
self.m_Name = name.lower()
self.m_Alias = tuple(map(lambda x: x.lower(), alias))
self.m_CodePage = None if code_page == '' else code_page
self.m_IconvCode = None if iconv_code == '' else iconv_code
def extract_data(fs: io.TextIOWrapper) -> tuple[str, ...]:
# remove first line to remove table header
return fs.readlines()[1:]
def extract_token(csv_data: tuple[str, ...]) -> tuple[LanguageToken, ...]:
ret: list[LanguageToken] = []
for line in csv_data:
line = line.strip('\n')
line_sp = line.split('\t')
alias_sp = filter(lambda x: x != '', map(lambda x: x.strip(), line_sp[1].split(',')))
ret.append(LanguageToken(line_sp[0], alias_sp, line_sp[2], line_sp[3]))
return tuple(ret)
def write_alias_map(fs: io.TextIOWrapper, data: tuple[LanguageToken, ...]) -> None:
fs.write('static const std::map<std::u8string, std::u8string> c_AliasMap {\n')
for i in data:
for j in i.m_Alias:
fs.write(f'\t{{ u8"{j}", u8"{i.m_Name}" }},\n')
fs.write('};\n')
def write_win_cp_map(fs: io.TextIOWrapper, data: tuple[LanguageToken, ...]) -> None:
fs.write('static const std::map<std::u8string, UINT> c_WinCPMap {\n')
for i in data:
if i.m_CodePage is not None:
fs.write(f'\t{{ u8"{i.m_Name}", static_cast<UINT>({i.m_CodePage}u) }},\n')
fs.write('};\n')
def write_iconv_map(fs: io.TextIOWrapper, data: tuple[LanguageToken, ...]) -> None:
fs.write('static const std::map<std::u8string, std::string> c_IconvMap {\n')
for i in data:
if i.m_IconvCode is not None:
fs.write(f'\t{{ u8"{i.m_Name}", "{i.m_IconvCode}" }},\n')
fs.write('};\n')
if __name__ == '__main__':
with open('EncodingTable.csv', 'r', encoding='utf-8') as fr:
with open('UEncodingTable.cpp', 'w', encoding='utf-8') as fw:
data = extract_data(fr)
token = extract_token(data)
write_alias_map(fw, token)
write_win_cp_map(fw, token)
write_iconv_map(fw, token)

View File

@ -1,3 +1,2 @@
# Result
*.hpp

View File

@ -6,7 +6,7 @@ configure_file(
)
# Add custom target
add_custom_target (LibCmoDocuments
add_custom_target (NeMoDocuments
doxygen ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating LibCmo documentation" VERBATIM

View File

@ -4,7 +4,6 @@ add_library(LibCmo STATIC "")
target_sources(LibCmo
PRIVATE
# Assistant source files
VTUtils.cpp
VTEncoding.cpp
VTImage.cpp
# CK2
@ -132,104 +131,3 @@ install(TARGETS LibCmo
INCLUDES DESTINATION ${NEMO_INSTALL_INCLUDE_PATH}
FILE_SET HEADERS DESTINATION ${NEMO_INSTALL_INCLUDE_PATH}
)
# cmake_minimum_required(VERSION 3.12)
# project(LibCmo LANGUAGES CXX)
# # find packages
# find_package(ZLIB REQUIRED)
# find_package(Iconv REQUIRED)
# # manually check stb image path
# if (NOT STB_IMAGE_PATH)
# message(FATAL_ERROR "You must assign your stb_image library root path to STB_IMAGE_PATH when compiling this project.")
# endif ()
# if ((NOT EXISTS "${STB_IMAGE_PATH}/stb_image.h") OR (NOT EXISTS "${STB_IMAGE_PATH}/stb_image_resize.h") OR (NOT EXISTS "${STB_IMAGE_PATH}/stb_image_write.h"))
# message(FATAL_ERROR "Invalid stb_image library path.")
# endif ()
# # set up file list
# set(libcmo_headers ".")
# set(libcmo_vt_src
# VTUtils.cpp
# VTEncoding.cpp
# VTImage.cpp
# )
# set(libcmo_ck2_src
# CK2/CKBitmapData.cpp
# CK2/CKContext.cpp
# CK2/CKFileOthers.cpp
# CK2/CKFileReader.cpp
# CK2/CKFileWriter.cpp
# CK2/CKGlobals.cpp
# CK2/CKStateChunkOthers.cpp
# CK2/CKStateChunkReader.cpp
# CK2/CKStateChunkWriter.cpp
# )
# set(libcmo_ck2_dh_src
# CK2/DataHandlers/CKBitmapHandler.cpp
# )
# set(libcmo_ck2_mgr_src
# CK2/MgrImpls/CKBaseManager.cpp
# CK2/MgrImpls/CKObjectManager.cpp
# CK2/MgrImpls/CKPathManager.cpp
# )
# set(libcmo_ck2_obj_src
# CK2/ObjImpls/CK3dEntity.cpp
# CK2/ObjImpls/CKBeObject.cpp
# CK2/ObjImpls/CKGroup.cpp
# CK2/ObjImpls/CKMaterial.cpp
# CK2/ObjImpls/CKMesh.cpp
# CK2/ObjImpls/CKObject.cpp
# CK2/ObjImpls/CKTexture.cpp
# )
# set(libcmo_vxmath_src
# VxMath/VxMemoryMappedFile.cpp
# VxMath/VxMath.cpp
# )
# set(libcmo_xcontainer_src
# XContainer/XTypes.cpp
# )
# # create static library
# add_library(LibCmo
# STATIC
# ${libcmo_vt_src}
# ${libcmo_ck2_src}
# ${libcmo_ck2_dh_src}
# ${libcmo_ck2_mgr_src}
# ${libcmo_ck2_obj_src}
# ${libcmo_vxmath_src}
# ${libcmo_xcontainer_src}
# )
# target_link_libraries(LibCmo
# PRIVATE
# ${ZLIB_LIBRARIES}
# ${Iconv_LIBRARIES}
# )
# target_include_directories(LibCmo
# PUBLIC
# ${libcmo_headers}
# PRIVATE
# ${STB_IMAGE_PATH}
# ${ZLIB_INCLUDE_DIRS}
# ${Iconv_INCLUDE_DIRS}
# )
# # set project standard
# set_target_properties(LibCmo
# PROPERTIES
# CXX_STANDARD 20
# CXX_STANDARD_REQUIRED 20
# CXX_EXTENSION OFF
# )
# # add essential build macro and populate them
# target_compile_definitions(LibCmo
# PUBLIC
# $<$<CONFIG:Debug>:LIBCMO_BUILD_DEBUG>
# $<$<CONFIG:Release>:LIBCMO_BUILD_RELEASE>
# $<$<CONFIG:RelWithDebInfo>:LIBCMO_BUILD_RELEASE>
# $<$<CONFIG:MinSizeRel>:LIBCMO_BUILD_RELEASE>
# )

View File

@ -1,93 +1,432 @@
#include "VTEncoding.hpp"
#include <map>
#if YYCC_OS == YYCC_OS_WINDOWS
#include <WinImportPrefix.hpp>
#include <Windows.h>
#include <fileapi.h>
#include <WinImportSuffix.hpp>
#else
#include <iconv.h>
#endif
namespace LibCmo::EncodingHelper {
#pragma region assist functions
#pragma region Constant Map
#if defined(LIBCMO_OS_WIN32)
static const std::map<std::u8string, std::u8string> c_AliasMap {
{ u8"646", u8"ascii" },
{ u8"us-ascii", u8"ascii" },
{ u8"big5-tw", u8"big5" },
{ u8"csbig5", u8"big5" },
{ u8"big5-hkscs", u8"big5hkscs" },
{ u8"hkscs", u8"big5hkscs" },
{ u8"ibm037", u8"cp037" },
{ u8"ibm039", u8"cp037" },
{ u8"273", u8"cp273" },
{ u8"ibm273", u8"cp273" },
{ u8"csibm273", u8"cp273" },
{ u8"ebcdic-cp-he", u8"cp424" },
{ u8"ibm424", u8"cp424" },
{ u8"437", u8"cp437" },
{ u8"ibm437", u8"cp437" },
{ u8"ebcdic-cp-be", u8"cp500" },
{ u8"ebcdic-cp-ch", u8"cp500" },
{ u8"ibm500", u8"cp500" },
{ u8"ibm775", u8"cp775" },
{ u8"850", u8"cp850" },
{ u8"ibm850", u8"cp850" },
{ u8"852", u8"cp852" },
{ u8"ibm852", u8"cp852" },
{ u8"855", u8"cp855" },
{ u8"ibm855", u8"cp855" },
{ u8"857", u8"cp857" },
{ u8"ibm857", u8"cp857" },
{ u8"858", u8"cp858" },
{ u8"ibm858", u8"cp858" },
{ u8"860", u8"cp860" },
{ u8"ibm860", u8"cp860" },
{ u8"861", u8"cp861" },
{ u8"cp-is", u8"cp861" },
{ u8"ibm861", u8"cp861" },
{ u8"862", u8"cp862" },
{ u8"ibm862", u8"cp862" },
{ u8"863", u8"cp863" },
{ u8"ibm863", u8"cp863" },
{ u8"ibm864", u8"cp864" },
{ u8"865", u8"cp865" },
{ u8"ibm865", u8"cp865" },
{ u8"866", u8"cp866" },
{ u8"ibm866", u8"cp866" },
{ u8"869", u8"cp869" },
{ u8"cp-gr", u8"cp869" },
{ u8"ibm869", u8"cp869" },
{ u8"932", u8"cp932" },
{ u8"ms932", u8"cp932" },
{ u8"mskanji", u8"cp932" },
{ u8"ms-kanji", u8"cp932" },
{ u8"windows-31j", u8"cp932" },
{ u8"949", u8"cp949" },
{ u8"ms949", u8"cp949" },
{ u8"uhc", u8"cp949" },
{ u8"950", u8"cp950" },
{ u8"ms950", u8"cp950" },
{ u8"ibm1026", u8"cp1026" },
{ u8"1125", u8"cp1125" },
{ u8"ibm1125", u8"cp1125" },
{ u8"cp866u", u8"cp1125" },
{ u8"ruscii", u8"cp1125" },
{ u8"ibm1140", u8"cp1140" },
{ u8"windows-1250", u8"cp1250" },
{ u8"windows-1251", u8"cp1251" },
{ u8"windows-1252", u8"cp1252" },
{ u8"windows-1253", u8"cp1253" },
{ u8"windows-1254", u8"cp1254" },
{ u8"windows-1255", u8"cp1255" },
{ u8"windows-1256", u8"cp1256" },
{ u8"windows-1257", u8"cp1257" },
{ u8"windows-1258", u8"cp1258" },
{ u8"eucjp", u8"euc_jp" },
{ u8"ujis", u8"euc_jp" },
{ u8"u-jis", u8"euc_jp" },
{ u8"jisx0213", u8"euc_jis_2004" },
{ u8"eucjis2004", u8"euc_jis_2004" },
{ u8"eucjisx0213", u8"euc_jisx0213" },
{ u8"euckr", u8"euc_kr" },
{ u8"korean", u8"euc_kr" },
{ u8"ksc5601", u8"euc_kr" },
{ u8"ks_c-5601", u8"euc_kr" },
{ u8"ks_c-5601-1987", u8"euc_kr" },
{ u8"ksx1001", u8"euc_kr" },
{ u8"ks_x-1001", u8"euc_kr" },
{ u8"chinese", u8"gb2312" },
{ u8"csiso58gb231280", u8"gb2312" },
{ u8"euc-cn", u8"gb2312" },
{ u8"euccn", u8"gb2312" },
{ u8"eucgb2312-cn", u8"gb2312" },
{ u8"gb2312-1980", u8"gb2312" },
{ u8"gb2312-80", u8"gb2312" },
{ u8"iso-ir-58", u8"gb2312" },
{ u8"936", u8"gbk" },
{ u8"cp936", u8"gbk" },
{ u8"ms936", u8"gbk" },
{ u8"gb18030-2000", u8"gb18030" },
{ u8"hzgb", u8"hz" },
{ u8"hz-gb", u8"hz" },
{ u8"hz-gb-2312", u8"hz" },
{ u8"csiso2022jp", u8"iso2022_jp" },
{ u8"iso2022jp", u8"iso2022_jp" },
{ u8"iso-2022-jp", u8"iso2022_jp" },
{ u8"iso2022jp-1", u8"iso2022_jp_1" },
{ u8"iso-2022-jp-1", u8"iso2022_jp_1" },
{ u8"iso2022jp-2", u8"iso2022_jp_2" },
{ u8"iso-2022-jp-2", u8"iso2022_jp_2" },
{ u8"iso2022jp-2004", u8"iso2022_jp_2004" },
{ u8"iso-2022-jp-2004", u8"iso2022_jp_2004" },
{ u8"iso2022jp-3", u8"iso2022_jp_3" },
{ u8"iso-2022-jp-3", u8"iso2022_jp_3" },
{ u8"iso2022jp-ext", u8"iso2022_jp_ext" },
{ u8"iso-2022-jp-ext", u8"iso2022_jp_ext" },
{ u8"csiso2022kr", u8"iso2022_kr" },
{ u8"iso2022kr", u8"iso2022_kr" },
{ u8"iso-2022-kr", u8"iso2022_kr" },
{ u8"iso-8859-1", u8"latin_1" },
{ u8"iso8859-1", u8"latin_1" },
{ u8"8859", u8"latin_1" },
{ u8"cp819", u8"latin_1" },
{ u8"latin", u8"latin_1" },
{ u8"latin1", u8"latin_1" },
{ u8"l1", u8"latin_1" },
{ u8"iso-8859-2", u8"iso8859_2" },
{ u8"latin2", u8"iso8859_2" },
{ u8"l2", u8"iso8859_2" },
{ u8"iso-8859-3", u8"iso8859_3" },
{ u8"latin3", u8"iso8859_3" },
{ u8"l3", u8"iso8859_3" },
{ u8"iso-8859-4", u8"iso8859_4" },
{ u8"latin4", u8"iso8859_4" },
{ u8"l4", u8"iso8859_4" },
{ u8"iso-8859-5", u8"iso8859_5" },
{ u8"cyrillic", u8"iso8859_5" },
{ u8"iso-8859-6", u8"iso8859_6" },
{ u8"arabic", u8"iso8859_6" },
{ u8"iso-8859-7", u8"iso8859_7" },
{ u8"greek", u8"iso8859_7" },
{ u8"greek8", u8"iso8859_7" },
{ u8"iso-8859-8", u8"iso8859_8" },
{ u8"hebrew", u8"iso8859_8" },
{ u8"iso-8859-9", u8"iso8859_9" },
{ u8"latin5", u8"iso8859_9" },
{ u8"l5", u8"iso8859_9" },
{ u8"iso-8859-10", u8"iso8859_10" },
{ u8"latin6", u8"iso8859_10" },
{ u8"l6", u8"iso8859_10" },
{ u8"iso-8859-11", u8"iso8859_11" },
{ u8"thai", u8"iso8859_11" },
{ u8"iso-8859-13", u8"iso8859_13" },
{ u8"latin7", u8"iso8859_13" },
{ u8"l7", u8"iso8859_13" },
{ u8"iso-8859-14", u8"iso8859_14" },
{ u8"latin8", u8"iso8859_14" },
{ u8"l8", u8"iso8859_14" },
{ u8"iso-8859-15", u8"iso8859_15" },
{ u8"latin9", u8"iso8859_15" },
{ u8"l9", u8"iso8859_15" },
{ u8"iso-8859-16", u8"iso8859_16" },
{ u8"latin10", u8"iso8859_16" },
{ u8"l10", u8"iso8859_16" },
{ u8"cp1361", u8"johab" },
{ u8"ms1361", u8"johab" },
{ u8"kz_1048", u8"kz1048" },
{ u8"strk1048_2002", u8"kz1048" },
{ u8"rk1048", u8"kz1048" },
{ u8"maccyrillic", u8"mac_cyrillic" },
{ u8"macgreek", u8"mac_greek" },
{ u8"maciceland", u8"mac_iceland" },
{ u8"maclatin2", u8"mac_latin2" },
{ u8"maccentraleurope", u8"mac_latin2" },
{ u8"mac_centeuro", u8"mac_latin2" },
{ u8"macroman", u8"mac_roman" },
{ u8"macintosh", u8"mac_roman" },
{ u8"macturkish", u8"mac_turkish" },
{ u8"csptcp154", u8"ptcp154" },
{ u8"pt154", u8"ptcp154" },
{ u8"cp154", u8"ptcp154" },
{ u8"cyrillic-asian", u8"ptcp154" },
{ u8"csshiftjis", u8"shift_jis" },
{ u8"shiftjis", u8"shift_jis" },
{ u8"sjis", u8"shift_jis" },
{ u8"s_jis", u8"shift_jis" },
{ u8"shiftjis2004", u8"shift_jis_2004" },
{ u8"sjis_2004", u8"shift_jis_2004" },
{ u8"sjis2004", u8"shift_jis_2004" },
{ u8"shiftjisx0213", u8"shift_jisx0213" },
{ u8"sjisx0213", u8"shift_jisx0213" },
{ u8"s_jisx0213", u8"shift_jisx0213" },
{ u8"u32", u8"utf_32" },
{ u8"utf32", u8"utf_32" },
{ u8"utf-32be", u8"utf_32_be" },
{ u8"utf-32le", u8"utf_32_le" },
{ u8"u16", u8"utf_16" },
{ u8"utf16", u8"utf_16" },
{ u8"utf-16be", u8"utf_16_be" },
{ u8"utf-16le", u8"utf_16_le" },
{ u8"u7", u8"utf_7" },
{ u8"unicode-1-1-utf-7", u8"utf_7" },
{ u8"u8", u8"utf_8" },
{ u8"utf", u8"utf_8" },
{ u8"utf8", u8"utf_8" },
{ u8"cp65001", u8"utf_8" },
};
#define LIBCMO_STR_EQUAL(a, b) strcmp(reinterpret_cast<const char*>(a), reinterpret_cast<const char*>(b)) == 0
bool GetWindowsCodePage(const char* u8_encoding_spec, UINT* result) {
if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_ACP")) *result = CP_ACP;
else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_MACCP")) *result = CP_MACCP;
else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_OEMCP")) *result = CP_OEMCP;
else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_THREAD_ACPP")) *result = CP_THREAD_ACP;
else if (LIBCMO_STR_EQUAL(u8_encoding_spec, u8"CP_UTF8")) *result = CP_UTF8;
else {
char* pend = nullptr;
errno = 0;
uint64_t v = std::strtoull(u8_encoding_spec, &pend, 10);
/**
* @brief Resolve encoding name alias and fetch real encoding name.
* @param[in] lang The encoding name for finding.
* @return
* The given encoding name if given name not present in alias map.
* Otherwise the found encoding name by given name.
*/
static std::u8string ResolveEncodingAlias(const std::u8string_view& enc_name) {
std::u8string name(enc_name);
YYCC::StringHelper::Lower(name);
auto finder = c_AliasMap.find(name);
if (finder == c_AliasMap.end()) return std::u8string(enc_name); // not found, use original encoding name.
else return std::u8string(finder->second); // found, use found encoding name.
}
if (pend == u8_encoding_spec || errno == ERANGE) return false;
*result = static_cast<UINT>(v);
}
#if YYCC_OS == YYCC_OS_WINDOWS
static const std::map<std::u8string, UINT> c_WinCPMap {
{ u8"big5", static_cast<UINT>(950u) },
{ u8"cp037", static_cast<UINT>(037u) },
{ u8"cp437", static_cast<UINT>(437u) },
{ u8"cp500", static_cast<UINT>(500u) },
{ u8"cp720", static_cast<UINT>(720u) },
{ u8"cp737", static_cast<UINT>(737u) },
{ u8"cp775", static_cast<UINT>(775u) },
{ u8"cp850", static_cast<UINT>(850u) },
{ u8"cp852", static_cast<UINT>(852u) },
{ u8"cp855", static_cast<UINT>(855u) },
{ u8"cp857", static_cast<UINT>(857u) },
{ u8"cp858", static_cast<UINT>(858u) },
{ u8"cp860", static_cast<UINT>(860u) },
{ u8"cp861", static_cast<UINT>(861u) },
{ u8"cp862", static_cast<UINT>(862u) },
{ u8"cp863", static_cast<UINT>(863u) },
{ u8"cp864", static_cast<UINT>(864u) },
{ u8"cp865", static_cast<UINT>(865u) },
{ u8"cp866", static_cast<UINT>(866u) },
{ u8"cp869", static_cast<UINT>(869u) },
{ u8"cp874", static_cast<UINT>(874u) },
{ u8"cp875", static_cast<UINT>(875u) },
{ u8"cp932", static_cast<UINT>(932u) },
{ u8"cp949", static_cast<UINT>(949u) },
{ u8"cp950", static_cast<UINT>(950u) },
{ u8"cp1026", static_cast<UINT>(1026u) },
{ u8"cp1140", static_cast<UINT>(1140u) },
{ u8"cp1250", static_cast<UINT>(1250u) },
{ u8"cp1251", static_cast<UINT>(1251u) },
{ u8"cp1252", static_cast<UINT>(1252u) },
{ u8"cp1253", static_cast<UINT>(1253u) },
{ u8"cp1254", static_cast<UINT>(1254u) },
{ u8"cp1255", static_cast<UINT>(1255u) },
{ u8"cp1256", static_cast<UINT>(1256u) },
{ u8"cp1257", static_cast<UINT>(1257u) },
{ u8"cp1258", static_cast<UINT>(1258u) },
{ u8"euc_kr", static_cast<UINT>(51949u) },
{ u8"gbk", static_cast<UINT>(936u) },
{ u8"gb18030", static_cast<UINT>(54936u) },
{ u8"hz", static_cast<UINT>(52936u) },
{ u8"iso2022_kr", static_cast<UINT>(50225u) },
{ u8"latin_1", static_cast<UINT>(28591u) },
{ u8"iso8859_2", static_cast<UINT>(28592u) },
{ u8"iso8859_3", static_cast<UINT>(28593u) },
{ u8"iso8859_4", static_cast<UINT>(28594u) },
{ u8"iso8859_5", static_cast<UINT>(28595u) },
{ u8"iso8859_6", static_cast<UINT>(28596u) },
{ u8"iso8859_7", static_cast<UINT>(28597u) },
{ u8"iso8859_8", static_cast<UINT>(28598u) },
{ u8"iso8859_9", static_cast<UINT>(28599u) },
{ u8"iso8859_13", static_cast<UINT>(28603u) },
{ u8"iso8859_15", static_cast<UINT>(28605u) },
{ u8"johab", static_cast<UINT>(1361u) },
{ u8"mac_cyrillic", static_cast<UINT>(10007u) },
{ u8"mac_greek", static_cast<UINT>(10006u) },
{ u8"mac_iceland", static_cast<UINT>(10079u) },
{ u8"mac_turkish", static_cast<UINT>(10081u) },
{ u8"shift_jis", static_cast<UINT>(932u) },
{ u8"utf_7", static_cast<UINT>(65000u) },
{ u8"utf_8", static_cast<UINT>(65001u) },
};
static bool GetWindowsCodePage(const std::u8string_view& enc_name, UINT& out_cp) {
// resolve alias
std::u8string resolved_name = ResolveEncodingAlias(enc_name);
// find code page
YYCC::StringHelper::Lower(resolved_name);
auto finder = c_WinCPMap.find(resolved_name);
if (finder == c_WinCPMap.end()) return false;
// okey, we found it.
out_cp = finder->second;
return true;
}
#undef LIBCMO_STR_EQUAL
bool WcharToChar(const wchar_t* src, std::string& dest, const UINT codepage) {
int count, write_result;
//converter to CHAR
count = WideCharToMultiByte(codepage, 0, src, -1, NULL, 0, NULL, NULL);
if (count <= 0) return false;
dest.resize(count - 1);
write_result = WideCharToMultiByte(codepage, 0, src, -1, dest.data(), count, NULL, NULL);
if (write_result <= 0) return false;
return true;
}
bool WcharToChar(const std::wstring& src, std::string& dest, const UINT codepage) {
return WcharToChar(src.c_str(), dest, codepage);
}
bool CharToWchar(const char* src, std::wstring& dest, const UINT codepage) {
int wcount, write_result;
// convert to WCHAR
wcount = MultiByteToWideChar(codepage, 0, src, -1, NULL, 0);
if (wcount <= 0) return false;
dest.resize(wcount - 1);
write_result = MultiByteToWideChar(codepage, 0, src, -1, dest.data(), wcount);
if (write_result <= 0) return false;
return true;
}
bool CharToWchar(const std::string& src, std::wstring& dest, const UINT codepage) {
return CharToWchar(src.c_str(), dest, codepage);
}
bool CharToChar(const char* src, std::string& dest, const UINT src_codepage, const UINT dest_codepage) {
std::wstring intermediary;
if (!CharToWchar(src, intermediary, src_codepage)) return false;
if (!WcharToChar(intermediary, dest, dest_codepage)) return false;
return true;
}
bool CharToChar(const std::string& src, std::string& dest, const UINT src_codepage, const UINT dest_codepage) {
return CharToChar(src.c_str(), dest, src_codepage, dest_codepage);
}
#else
static const std::map<std::u8string, std::string> c_IconvMap {
{ u8"ascii", "ASCII" },
{ u8"big5", "BIG5" },
{ u8"big5hkscs", "BIG5-HKSCS" },
{ u8"cp850", "CP850" },
{ u8"cp862", "CP862" },
{ u8"cp866", "CP866" },
{ u8"cp874", "CP874" },
{ u8"cp932", "CP932" },
{ u8"cp949", "CP949" },
{ u8"cp950", "CP950" },
{ u8"cp1250", "CP1250" },
{ u8"cp1251", "CP1251" },
{ u8"cp1252", "CP1252" },
{ u8"cp1253", "CP1253" },
{ u8"cp1254", "CP1254" },
{ u8"cp1255", "CP1255" },
{ u8"cp1256", "CP1256" },
{ u8"cp1257", "CP1257" },
{ u8"cp1258", "CP1258" },
{ u8"euc_jp", "EUC-JP" },
{ u8"euc_kr", "EUC-KR" },
{ u8"gbk", "CP936" },
{ u8"gb18030", "GB18030" },
{ u8"hz", "HZ" },
{ u8"iso2022_jp", "ISO-2022-JP" },
{ u8"iso2022_jp_1", "ISO-2022-JP-1" },
{ u8"iso2022_jp_2", "ISO-2022-JP-2" },
{ u8"iso2022_kr", "ISO-2022-KR" },
{ u8"latin_1", "ISO-8859-1" },
{ u8"iso8859_2", "ISO-8859-2" },
{ u8"iso8859_3", "ISO-8859-3" },
{ u8"iso8859_4", "ISO-8859-4" },
{ u8"iso8859_5", "ISO-8859-5" },
{ u8"iso8859_6", "ISO-8859-6" },
{ u8"iso8859_7", "ISO-8859-7" },
{ u8"iso8859_8", "ISO-8859-8" },
{ u8"iso8859_9", "ISO-8859-9" },
{ u8"iso8859_10", "ISO-8859-10" },
{ u8"iso8859_11", "ISO-8859-11" },
{ u8"iso8859_13", "ISO-8859-13" },
{ u8"iso8859_14", "ISO-8859-14" },
{ u8"iso8859_15", "ISO-8859-15" },
{ u8"iso8859_16", "ISO-8859-16" },
{ u8"johab", "JOHAB" },
{ u8"koi8_t", "KOI8-T" },
{ u8"mac_cyrillic", "MacCyrillic" },
{ u8"mac_greek", "MacGreek" },
{ u8"mac_iceland", "MacIceland" },
{ u8"mac_roman", "MacRoman" },
{ u8"mac_turkish", "MacTurkish" },
{ u8"ptcp154", "PT154" },
{ u8"shift_jis", "SHIFT_JIS" },
{ u8"utf_32", "UTF-32" },
{ u8"utf_32_be", "UTF-32BE" },
{ u8"utf_32_le", "UTF-32LE" },
{ u8"utf_16", "UTF16" },
{ u8"utf_16_be", "UTF-16BE" },
{ u8"utf_16_le", "UTF-16LE" },
{ u8"utf_7", "UTF-7" },
{ u8"utf_8", "UTF-8" },
};
static constexpr const size_t IconvInc = 16;
static const iconv_t InvalidIconvDescriptor = reinterpret_cast<iconv_t>(-1);
bool CreateIconvDescriptor(const char* enc_from, const char* enc_to, iconv_t& val) {
val = iconv_open(enc_to, enc_from);
return val != InvalidIconvDescriptor;
static bool GetIconvCode(const std::u8string_view& enc_name, std::string& out_code) {
// resolve alias
std::u8string resolved_name = ResolveEncodingAlias(enc_name);
// find code page
YYCC::StringHelper::Lower(resolved_name);
auto finder = c_IconvMap.find(resolved_name);
if (finder == c_IconvMap.end()) return false;
// okey, we found it.
out_code = finder->second;
return true;
}
void DestroyIconvDescriptor(iconv_t& val) {
if (val == InvalidIconvDescriptor) return;
iconv_close(val);
val = InvalidIconvDescriptor;
}
#endif
#pragma endregion
#pragma region Internal Functions
#if YYCC_OS == YYCC_OS_WINDOWS
struct WindowsEncodingToken {
UINT m_CodePage;
};
#else
static constexpr const size_t c_IconvIncUnit = 16u;
static const iconv_t c_InvalidIconvType = reinterpret_cast<iconv_t>(-1);
struct IconvEncodingToken {
IconvEncodingToken(const std::string_view& iconv_code) :
m_FromUTF8(c_InvalidIconvType), m_ToUTF8(c_InvalidIconvType) {
// if iconv code is empty, do nothing
if (iconv_code.empty()) return;
// setup iconv_t
this->m_FromUTF8 = iconv_open(code.c_str(), "UTF-8");
this->m_ToUTF8 = iconv_open("UTF-8", code.c_str());
}
~IconvEncodingToken() {
if (this->m_FromUTF8 != c_InvalidIconvType)
iconv_close(token_cast->m_FromUTF8);
if (this->m_ToUTF8 != c_InvalidIconvType)
iconv_close(token_cast->m_ToUTF8);
}
iconv_t m_FromUTF8;
iconv_t m_ToUTF8;
};
// Reference: https://stackoverflow.com/questions/13297458/simple-utf8-utf16-string-conversion-with-iconv
bool DoIconv(iconv_t& cd, const std::string& str_from, std::string& str_to) {
char *inbuf = nullptr, *outbuf = nullptr;
static bool DoIconv(iconv_t& cd, const std::string_view& str_from, std::string& str_to) {
char* inbuf = nullptr, * outbuf = nullptr;
size_t inbytesleft, outbytesleft, nchars, result_len;
// check empty
@ -97,20 +436,20 @@ namespace LibCmo::EncodingHelper {
}
// check iconv descriptor
if (cd == InvalidIconvDescriptor) {
if (cd == c_InvalidIconvType) {
// invalid iconv descriptor
return false;
}
// pre-resize
str_to.resize(str_from.size() + IconvInc);
str_to.resize(str_from.size() + c_IconvIncUnit);
// setup some variables
inbytesleft = str_from.size();
inbuf = const_cast<char*>(str_from.c_str());
inbuf = const_cast<char*>(str_from.data());
outbytesleft = str_to.size();
outbuf = str_to.data();
result_len = str_to.size();
// conv core
@ -120,13 +459,13 @@ namespace LibCmo::EncodingHelper {
size_t len = outbuf - str_to.data();
// resize for variables
result_len += IconvInc;
outbytesleft += IconvInc;
result_len += c_IconvIncUnit;
outbytesleft += c_IconvIncUnit;
// resize for container
str_to.resize(result_len);
// assign new outbuf from failed position
// assign new outbuf from failed position
outbuf = str_to.data() + len;
nchars = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
}
@ -151,118 +490,111 @@ namespace LibCmo::EncodingHelper {
#pragma endregion
#pragma region core functions
#pragma region Encoding Token
#if defined(LIBCMO_OS_WIN32)
ENCODING_TOKEN CreateEncodingToken(const std::string& token_string) {
ENCODING_TOKEN token = new UINT();
if (!GetWindowsCodePage(token_string.c_str(), token)) {
*token = CP_ACP;
}
EncodingToken CreateEncodingToken(const std::u8string_view& enc_name) {
#if YYCC_OS == YYCC_OS_WINDOWS
// get code page first
UINT cp = CP_ACP;
if (!GetWindowsCodePage(enc_name, cp))
return INVALID_ENCODING_TOKEN;
// validate code page
if (!YYCC::WinFctHelper::IsValidCodePage(cp))
return INVALID_ENCODING_TOKEN;
// create token and return
WindowsEncodingToken* token = new WindowsEncodingToken { cp };
return token;
}
void DestroyEncodingToken(const ENCODING_TOKEN& token) {
if (token != ENCODING_TOKEN_DEFAULT) {
delete token;
}
}
bool GetUtf8VirtoolsName(const std::string& native_name, std::string& u8_name, const ENCODING_TOKEN& token) {
if (token == ENCODING_TOKEN_DEFAULT) return false;
return CharToChar(native_name, u8_name, *token, CP_UTF8);
}
bool GetNativeVirtoolsName(const std::string& u8_name, std::string& native_name, const ENCODING_TOKEN& token) {
if (token == ENCODING_TOKEN_DEFAULT) return false;
return CharToChar(u8_name, native_name, CP_UTF8, *token);
}
void U8PathToStdPath(std::filesystem::path& stdpath, const char* u8_path) {
std::wstring intermediary;
if (CharToWchar(u8_path, intermediary, CP_UTF8)) {
stdpath = intermediary.c_str();
} else {
// fallback
stdpath = u8_path;
}
}
void StdPathToU8Path(std::string& u8path, std::filesystem::path& stdpath) {
if (!WcharToChar(stdpath.wstring(), u8path, CP_UTF8)) {
// fallback
u8path = stdpath.string();
}
}
FILE* U8FOpen(const char* u8_filepath, const char* u8_mode) {
std::wstring wmode, wpath;
bool suc = CharToWchar(u8_mode, wmode, CP_UTF8);
suc = suc && CharToWchar(u8_filepath, wpath, CP_UTF8);
if (suc) {
return _wfopen(wpath.c_str(), wmode.c_str());
} else {
// fallback
return std::fopen(u8_filepath, u8_mode);
}
}
#else
IconvPair::IconvPair() :
FromUtf8(InvalidIconvDescriptor), ToUtf8(InvalidIconvDescriptor) {
}
IconvPair::~IconvPair() {
DestroyIconvDescriptor(this->FromUtf8);
DestroyIconvDescriptor(this->ToUtf8);
}
static constexpr const char UTF8_SYMBOL[] = "UTF-8";
ENCODING_TOKEN CreateEncodingToken(const std::string& token_string) {
ENCODING_TOKEN token = new IconvPair();
if (!CreateIconvDescriptor(UTF8_SYMBOL, token_string.c_str(), token->FromUtf8) ||
!CreateIconvDescriptor(token_string.c_str(), UTF8_SYMBOL, token->ToUtf8)) {
delete token;
return ENCODING_TOKEN_DEFAULT;
// get iconv code first
std::string code;
if (!GetIconvCode(enc_name, code))
return INVALID_ENCODING_TOKEN;
// create token and set default value
IconvEncodingToken* token = new IconvEncodingToken(code);
// check whether token has been initialized correctly
if (token->m_FromUTF8 == c_InvalidIconvType || token->m_ToUTF8 == c_InvalidIconvType) {
// failed. free resource and return
delete token_cast;
return INVALID_ENCODING_TOKEN;
}
// okey, return
return token;
}
void DestroyEncodingToken(const ENCODING_TOKEN& token) {
if (token != ENCODING_TOKEN_DEFAULT) {
delete token;
}
}
bool GetUtf8VirtoolsName(const std::string& native_name, std::string& u8_name, const ENCODING_TOKEN& token) {
if (token == ENCODING_TOKEN_DEFAULT) return false;
return DoIconv(token->ToUtf8, native_name, u8_name);
}
bool GetNativeVirtoolsName(const std::string& u8_name, std::string& native_name, const ENCODING_TOKEN& token) {
if (token == ENCODING_TOKEN_DEFAULT) return false;
return DoIconv(token->FromUtf8, u8_name, native_name);
}
void U8PathToStdPath(std::filesystem::path& stdpath, const char* u8_path) {
stdpath = u8_path;
}
void StdPathToU8Path(std::string& u8path, std::filesystem::path& stdpath) {
u8path = stdpath.string();
}
FILE* U8FOpen(const char* u8_filepath, const char* u8_mode) {
return std::fopen(u8_filepath, u8_mode);
}
#endif
}
void DestroyEncodingToken(EncodingToken token) {
// if token is invalid, return directly
if (token == INVALID_ENCODING_TOKEN) return;
#if YYCC_OS == YYCC_OS_WINDOWS
WindowsEncodingToken* token_cast = static_cast<WindowsEncodingToken*>(token);
delete token_cast;
#else
IconvEncodingToken* token_cast = static_cast<IconvEncodingToken*>(token);
delete token_cast;
#endif
}
#pragma endregion
#pragma region Exposed Convertion Functions
bool ToOrdinary(const std::u8string_view& src, std::string& dst, EncodingToken token) {
// if token is invalid, return false
if (token == INVALID_ENCODING_TOKEN) return false;
#if YYCC_OS == YYCC_OS_WINDOWS
WindowsEncodingToken* token_cast = static_cast<WindowsEncodingToken*>(token);
return YYCC::EncodingHelper::UTF8ToChar(src, dst, token_cast->m_CodePage);
#else
IconvEncodingToken* token_cast = static_cast<IconvEncodingToken*>(token);
return DoIconv(token_cast->FromUTF8, YYCC::EncodingHelper::ToOrdinaryView(src), dst);
#endif
}
bool ToOrdinary(const char8_t* src, std::string& dst, EncodingToken token) {
if (src == nullptr) return false;
return ToOrdinary(std::u8string_view(src), dst, token);
}
std::string ToOrdinary(const std::u8string_view& src, EncodingToken token) {
std::string ret;
if (!ToOrdinary(src, ret, token)) ret.clear();
return ret;
}
std::string ToOrdinary(const char8_t* src, EncodingToken token) {
std::string ret;
if (!ToOrdinary(src, ret, token)) ret.clear();
return ret;
}
bool ToUTF8(const std::string_view& src, std::u8string& dst, EncodingToken token) {
// if token is invalid, return false
if (token == INVALID_ENCODING_TOKEN) return false;
#if YYCC_OS == YYCC_OS_WINDOWS
WindowsEncodingToken* token_cast = static_cast<WindowsEncodingToken*>(token);
return YYCC::EncodingHelper::CharToUTF8(src, dst, token_cast->m_CodePage);
#else
IconvEncodingToken* token_cast = static_cast<IconvEncodingToken*>(token);
std::string dst_cache;
bool ret = DoIconv(token_cast->ToUTF8, src, dst_cache);
if (ret) dst = YYCC::EncodingHelper::ToUTF8(dst_cache);
return ret;
#endif
}
bool ToUTF8(const char* src, std::u8string& dst, EncodingToken token) {
if (src == nullptr) return false;
return ToUTF8(std::string_view(src), dst, token);
}
std::u8string ToUTF8(const std::string_view& src, EncodingToken token) {
std::u8string ret;
if (!ToUTF8(src, ret, token)) ret.clear();
return ret;
}
std::u8string ToUTF8(const char* src, EncodingToken token) {
std::u8string ret;
if (!ToUTF8(src, ret, token)) ret.clear();
return ret;
}
#pragma endregion

View File

@ -1,85 +1,24 @@
#pragma once
#include "VTUtils.hpp"
#include <string>
#include <filesystem>
#if defined(LIBCMO_OS_WIN32)
#include <Windows.h>
#include <fileapi.h>
// disable annoy macro at the same time
#undef GetObject
#undef GetClassName
#undef LoadImage
#undef GetTempPath
#else
#include <iconv.h>
#endif
#include <string_view>
namespace LibCmo::EncodingHelper {
#pragma region assist functions
using EncodingToken = void*;
constexpr EncodingToken INVALID_ENCODING_TOKEN = nullptr;
#if defined(LIBCMO_OS_WIN32)
EncodingToken CreateEncodingToken(const std::u8string_view& enc_name);
void DestroyEncodingToken(EncodingToken token);
bool GetWindowsCodePage(const char* u8_encoding_spec, UINT* result);
bool ToOrdinary(const std::u8string_view& src, std::string& dst, EncodingToken token);
bool ToOrdinary(const char8_t* src, std::string& dst, EncodingToken token);
std::string ToOrdinary(const std::u8string_view& src, EncodingToken token);
std::string ToOrdinary(const char8_t* src, EncodingToken token);
bool WcharToChar(const wchar_t* src, std::string& dest, const UINT codepage);
bool WcharToChar(const std::wstring& src, std::string& dest, const UINT codepage);
bool CharToWchar(const char* src, std::wstring& dest, const UINT codepage);
bool CharToWchar(const std::string& src, std::wstring& dest, const UINT codepage);
bool CharToChar(const char* src, std::string& dest, const UINT src_codepage, const UINT dest_codepage);
bool CharToChar(const std::string& src, std::string& dest, const UINT src_codepage, const UINT dest_codepage);
#else
bool CreateIconvDescriptor(const char* enc_from, const char* enc_to, iconv_t& val);
void DestroyIconvDescriptor(iconv_t& val);
bool DoIconv(iconv_t& cd, const std::string& str_from, std::string& str_to);
#endif
#pragma endregion
#pragma region core functions
#if defined(LIBCMO_OS_WIN32)
// Token is the ticket for using encoding functions.
// It should be created by "GenerateEncodingToken" and free by "DestroyEncodingToken".
using ENCODING_TOKEN = UINT*;
constexpr const ENCODING_TOKEN ENCODING_TOKEN_DEFAULT = nullptr;
#else
class IconvPair {
public:
IconvPair();
IconvPair(const IconvPair&) = delete;
IconvPair& operator=(const IconvPair&) = delete;
~IconvPair();
iconv_t FromUtf8;
iconv_t ToUtf8;
};
using ENCODING_TOKEN = IconvPair*;
constexpr const ENCODING_TOKEN ENCODING_TOKEN_DEFAULT = nullptr;
#endif
ENCODING_TOKEN CreateEncodingToken(const std::string& token_string);
void DestroyEncodingToken(const ENCODING_TOKEN& token);
bool GetUtf8VirtoolsName(const std::string& native_name, std::string& u8_name, const ENCODING_TOKEN& token);
bool GetNativeVirtoolsName(const std::string& u8_name, std::string& native_name, const ENCODING_TOKEN& token);
void U8PathToStdPath(std::filesystem::path& stdpath, const char* u8_path);
void StdPathToU8Path(std::string& u8path, std::filesystem::path& stdpath);
FILE* U8FOpen(const char* u8_filepath, const char* u8_mode);
#pragma endregion
bool ToUTF8(const std::string_view& src, std::u8string& dst, EncodingToken token);
bool ToUTF8(const char* src, std::u8string& dst, EncodingToken token);
std::u8string ToUTF8(const std::string_view& src, EncodingToken token);
std::u8string ToUTF8(const char* src, EncodingToken token);
}

View File

@ -2,8 +2,8 @@
// Bad wrapper for stb image library.
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
#include <stb_image.h>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h"
#include <stb_image_write.h>
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include "stb_image_resize.h"
#include <stb_image_resize.h>

View File

@ -1,36 +0,0 @@
#include "VTUtils.hpp"
#if defined(LIBCMO_OS_WIN32)
#include <intrin.h>
// disable annoy macro at the same time
#undef GetObject
#undef GetClassName
#undef LoadImage
#undef GetTempPath
#else
#include <signal.h>
#endif
namespace LibCmo {
void LibPanic(int line, const char* file, const char* errmsg) {
fprintf(stderr, "LIBCMO PANIC:%s (%s:L%d)\n",
errmsg ? errmsg : "", file, line);
std::abort();
}
void LibOrderDebugger() {
#if defined(LIBCMO_BUILD_DEBUG)
#if defined(LIBCMO_OS_WIN32)
// win32 debug break
__debugbreak();
#else
// generic debug break
raise(SIGTRAP);
#endif
#endif
}
}

View File

@ -1,97 +1,69 @@
#pragma once
// Check LibCmo build type first.
#if !(defined(LIBCMO_BUILD_DEBUG) ^ defined(LIBCMO_BUILD_RELEASE))
#error "You must define ONE of LIBCMO_BUILD_DEBUG and LIBCMO_BUILD_RELEASE to indicate build type!"
#endif
// https://stackoverflow.com/questions/2164827/explicitly-exporting-shared-library-functions-in-linux
// generate import export macro.
// these macro is not used by LibCmo because LibCmo is static library
// these macro may used by other project such as BMap.
#if defined(_MSC_VER)
// Microsoft
#define LIBCMO_RAW_EXPORT __declspec(dllexport)
#define LIBCMO_RAW_IMPORT __declspec(dllimport)
#elif defined(__GNUC__)
// GCC
#define LIBCMO_RAW_EXPORT __attribute__((visibility("default")))
#define LIBCMO_RAW_IMPORT
#elif defined(__clang__)
// GCC
#define LIBCMO_RAW_EXPORT __attribute__((visibility("default")))
#define LIBCMO_RAW_IMPORT
#else
// do nothing and hope for the best?
#define LIBCMO_RAW_EXPORT
#define LIBCMO_RAW_IMPORT
#pragma warning "Unknown dynamic link import/export semantics."
#endif
// Include YYCC helper library
#include <YYCCommonplace.hpp>
// choosee proper style
#if defined(LIBCMO_EXPORTING)
#define LIBCMO_NAKED_EXPORT LIBCMO_RAW_EXPORT
#else
#define LIBCMO_NAKED_EXPORT LIBCMO_RAW_IMPORT
#endif
// some work for cpp
#if defined(__cplusplus)
#define LIBCMO_EXPORT extern "C" LIBCMO_NAKED_EXPORT
#else
#define LIBCMO_EXPORT LIBCMO_NAKED_EXPORT
#endif
#if defined(_WIN32)
#define LIBCMO_OS_WIN32
// disable annoy win32 macro
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#endif
#include <cstdio>
#include <type_traits>
#include <cinttypes>
#include <cstdint>
#include <initializer_list>
// Header for this namespace implementation
#include <string>
#pragma region Batch Ctor operator= Operations
#define LIBCMO_DISABLE_COPY_MOVE(CLSNAME) \
CLSNAME(const CLSNAME&) = delete; \
CLSNAME(CLSNAME&&) = delete; \
CLSNAME& operator=(const CLSNAME&) = delete; \
CLSNAME& operator=(CLSNAME&&) = delete;
#define LIBCMO_DEFAULT_COPY_MOVE(CLSNAME) \
CLSNAME(const CLSNAME&) = default; \
CLSNAME(CLSNAME&&) = default; \
CLSNAME& operator=(const CLSNAME&) = default; \
CLSNAME& operator=(CLSNAME&&) = default;
#pragma endregion
#define LIBCMO_UNUSED [[maybe_unused]]
#include <type_traits>
#include <initializer_list>
namespace LibCmo {
[[noreturn]] void LibPanic(int line, const char* file, const char* errmsg);
#define LIBCMO_PANIC(msg) LibCmo::LibPanic(__LINE__, __FILE__, msg);
#pragma region LibCmo Exceptions
void LibOrderDebugger();
#if defined(LIBCMO_BUILD_DEBUG)
/**
This macro only available in Debug mode.
It will order debugger stop.
This macro frequently used when program entering some rarely area.
For example, in CKStateChunk::ReadObjectID, if code run into the calling of Skip, it mean that this file is pretty old and debugger should notice it.
* @brief The exception raised when library entering unreachable scope.
* @details This exception usually used in \c switch syntax.
* It means that program enter the scope which it definitely can not enter.
*/
#define LIBCMO_ORDER_DEBUGGER LibOrderDebugger();
#else
// define a blank one
#define LIBCMO_ORDER_DEBUGGER
#endif
class UnreachableException : public std::exception {
public:
UnreachableException(const char* msg) : message(msg ? msg : "") {}
UnreachableException(const UnreachableException& rhs) : message(rhs.message) {}
virtual ~UnreachableException() {}
[[nodiscard]] virtual const char* what() const override { return message.c_str(); }
private:
std::string message;
};
/**
* @brief The exception raised when library entering logic error.
* @details In theory, this exception can be found by reading code.
* It usually caused by programmer use functions in a wrong way.
* For example, pass invalid argument to function and etc.
*/
class LogicException : public std::exception {
public:
LogicException(const char* msg) : message(msg ? msg : "") {}
LogicException(const LogicException& rhs) : message(rhs.message) {}
virtual ~LogicException() {}
[[nodiscard]] virtual const char* what() const override { return message.c_str(); }
private:
std::string message;
};
/**
* @brief The exception raised when library entering runtime error.
* @details In theory, this exception can not be found by reading code.
* It may caused by user input or anything else.
*/
class RuntimeException : public std::exception {
public:
RuntimeException(const char* msg) : message(msg ? msg : "") {}
RuntimeException(const RuntimeException& rhs) : message(rhs.message) {}
virtual ~RuntimeException() {}
[[nodiscard]] virtual const char* what() const override { return message.c_str(); }
private:
std::string message;
};
#pragma endregion
namespace EnumsHelper {
@ -100,9 +72,10 @@ namespace LibCmo {
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline TEnum Merge(std::initializer_list<TEnum> il) {
std::underlying_type_t<TEnum> result = 0;
using ut = std::underlying_type_t<TEnum>;
ut result = 0;
for (auto it = il.begin(); it != il.end(); ++it) {
result |= static_cast<std::underlying_type_t<TEnum>>(*it);
result |= static_cast<ut>(*it);
}
return static_cast<TEnum>(result);
}
@ -112,7 +85,8 @@ namespace LibCmo {
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline TEnum Inv(TEnum e) {
return static_cast<TEnum>(~(static_cast<std::underlying_type_t<TEnum>>(e)));
using ut = std::underlying_type_t<TEnum>;
return static_cast<TEnum>(~(static_cast<ut>(e)));
}
/**
@ -120,7 +94,8 @@ namespace LibCmo {
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline void Rm(TEnum& e1, TEnum e2) {
e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) & static_cast<std::underlying_type_t<TEnum>>(Inv(e2)));
using ut = std::underlying_type_t<TEnum>;
e1 = static_cast<TEnum>(static_cast<ut>(e1) & static_cast<ut>(Inv(e2)));
}
/**
@ -128,7 +103,8 @@ namespace LibCmo {
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline void Mask(TEnum& e1, TEnum e2) {
e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) & static_cast<std::underlying_type_t<TEnum>>(e2));
using ut = std::underlying_type_t<TEnum>;
e1 = static_cast<TEnum>(static_cast<ut>(e1) & static_cast<ut>(e2));
}
/**
@ -136,7 +112,8 @@ namespace LibCmo {
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline void Add(TEnum& e1, TEnum e2) {
e1 = static_cast<TEnum>(static_cast<std::underlying_type_t<TEnum>>(e1) | static_cast<std::underlying_type_t<TEnum>>(e2));
using ut = std::underlying_type_t<TEnum>;
e1 = static_cast<TEnum>(static_cast<ut>(e1) | static_cast<ut>(e2));
}
/**
@ -144,7 +121,8 @@ namespace LibCmo {
*/
template<typename TEnum, std::enable_if_t<std::is_enum_v<TEnum>, int> = 0>
inline bool Has(TEnum e, TEnum probe) {
return static_cast<bool>(static_cast<std::underlying_type_t<TEnum>>(e) & static_cast<std::underlying_type_t<TEnum>>(probe));
using ut = std::underlying_type_t<TEnum>;
return static_cast<bool>(static_cast<ut>(e) & static_cast<ut>(probe));
}
}

38
Scripts/win_build.bat Normal file
View File

@ -0,0 +1,38 @@
@ECHO OFF
:: Check environment
SET README_PATH=%CD%\README.md
IF EXIST %README_PATH% (
REM DO NOTHING
) ELSE (
ECHO Error: You must run this script at the root folder of this project!
EXIT /b
)
:: Create main binary directory
MKDIR bin
CD bin
:: Create build and install folder
MKDIR build
MKDIR install
:: Check build doc switch
IF NOT "%1"=="NODOC" (
SET BUILD_DOC_SWITCH=ON
) ELSE (
SET BUILD_DOC_SWITCH=OFF
)
:: Build project
CD build
cmake -G "Visual Studio 16 2019" -A x64 -DNEMO_BUILD_UNVIRT=ON -DNEMO_BUILD_BMAP=ON -DNEMO_BUILD_DOC=%BUILD_DOC_SWITCH% -DSTB_IMAGE_PATH="D:\CppLib\stb" -DYYCC_PATH="J:\YYCCommonplace\bin\cpp20\install\x64_Debug" -DZLIB_HEADER_PATH="D:\zlib" -DZLIB_BINARY_PATH="D:\zlib\contrib\vstudio\vc14\x64\ZlibDllRelease" ../..
pause
cmake --build . --config Release
IF NOT "%1"=="NODOC" (
cmake --build . --target NeMoDocuments
)
cmake --install . --prefix=../install --config Release
CD ..
:: Exit to original path
CD ..
ECHO Windows CMake Build Done

48
Scripts/win_build.py Normal file
View File

@ -0,0 +1,48 @@
import subprocess
import os
import shutil
import argparse
def get_root_directory() -> str:
return os.path.dirname(os.path.dirname(__file__))
def execute_cmd(prog: str, args: tuple[str, ...], cwd: str) -> None:
# find program first
found_prog = shutil.which(prog)
if found_prog is None:
raise RuntimeError(f'Fail to find program {prog}')
# run command
subprocess.run(
list((found_prog, ) + args), # program + arguments
stdin=subprocess.PIPE, # redirect
stdout=subprocess.PIPE, # redirect
stderr=subprocess.STDOUT, # stderr use the same output with stdout
cwd=cwd, # work directory
shell=True, # enable shell feature
check=True, # if program failed, raise exception and exit
)
def build(no_doc: bool) -> None:
# create directory
root_dir: str = get_root_directory()
os.makedirs(os.path.join(root_dir, 'Bin', 'build'))
os.makedirs(os.path.join(root_dir, 'Bin', 'install'))
# build project
args = [
''
]
if __name__ == '__main__':
# parse argument
parser = argparse.ArgumentParser(
prog='LibCmo Windows Build Script',
description='LibCmo Windows Build Script'
)
parser.add_argument(
'-d', '--no-doc',
action='store_true', dest='no_doc',
help='Build LibCmo without documentation.'
)
args = parser.parse_args()
build(args.no_doc)

View File

@ -60,48 +60,3 @@ install(TARGETS Unvirt
CONFIGURATIONS Release
RUNTIME DESTINATION ${YYCC_INSTALL_BIN_PATH}
)
# cmake_minimum_required(VERSION 3.12)
# project(Unvirt LANGUAGES CXX)
# # add libcmo if not existed
# if (NOT TARGET LibCmo)
# add_subdirectory("../LibCmo" "LibCmo.out")
# endif ()
# # add ironpad if not existed
# if (NOT TARGET IronPad)
# add_subdirectory("../IronPad" "IronPad.out")
# endif ()
# # setup sources
# set(unvirt_headers ".")
# set(unvirt_sources
# AccessibleValue.cpp
# CmdHelper.cpp
# StringHelper.cpp
# StructFormatter.cpp
# TerminalHelper.cpp
# UnvirtContext.cpp
# Unvirt.cpp
# )
# # generate program
# add_executable(Unvirt ${unvirt_sources})
# target_link_libraries(Unvirt
# PRIVATE
# LibCmo
# IronPad
# )
# target_include_directories(Unvirt
# PRIVATE
# ${unvirt_headers}
# )
# # set project standard
# set_target_properties(Unvirt
# PROPERTIES
# CXX_STANDARD 20
# CXX_STANDARD_REQUIRED 20
# CXX_EXTENSION OFF
# )