add transparent column fixer code and finish bmap load/save

This commit is contained in:
yyc12345 2023-10-29 10:27:35 +08:00
parent c7af11702f
commit b402e8db8e
5 changed files with 111 additions and 5 deletions

View File

@ -242,8 +242,11 @@ namespace BMap {
cache.emplace_back(encodings[i]); cache.emplace_back(encodings[i]);
} }
m_Context->SetEncoding(cache); m_Context->SetEncoding(cache);
// set default texture save mode is external // set default texture save mode is external
m_Context->SetGlobalImagesSaveOptions(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_EXTERNAL); m_Context->SetGlobalImagesSaveOptions(LibCmo::CK2::CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_EXTERNAL);
// set default file write mode is whole compressed
m_Context->SetFileWriteMode(LibCmo::CK2::CK_FILE_WRITEMODE::CKFILE_WHOLECOMPRESSED);
} }
BMFile::~BMFile() { BMFile::~BMFile() {
@ -257,16 +260,83 @@ namespace BMap {
bool BMFile::Load(LibCmo::CKSTRING filename) { bool BMFile::Load(LibCmo::CKSTRING filename) {
if (m_IsFreezed || !m_IsReader) return false; if (m_IsFreezed || !m_IsReader) return false;
// create temp ckfile and load
LibCmo::CK2::CKFileReader reader(m_Context);
LibCmo::CK2::CKERROR err = reader.DeepLoad(filename);
// detect error
if (err != LibCmo::CK2::CKERROR::CKERR_OK) {
// failed. clear document and return false
m_Context->ClearAll();
return false;
}
// sync data list to our list
m_ObjGroups.clear();
m_Obj3dObjects.clear();
m_ObjMeshs.clear();
m_ObjMaterials.clear();
m_ObjTextures.clear();
for (const auto& fileobj : reader.GetFileObjects()) {
if (fileobj.ObjPtr == nullptr) continue;
switch (fileobj.ObjectCid) {
case LibCmo::CK2::CK_CLASSID::CKCID_GROUP:
m_ObjGroups.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_3DOBJECT:
m_Obj3dObjects.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_MESH:
m_ObjMeshs.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_MATERIAL:
m_ObjMaterials.emplace_back(fileobj.CreatedObjectId);
break;
case LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE:
m_ObjTextures.emplace_back(fileobj.CreatedObjectId);
break;
}
}
return true; return true;
} }
bool BMFile::Save(LibCmo::CKSTRING filename, LibCmo::CKINT compress_level) { bool BMFile::Save(LibCmo::CKSTRING filename, LibCmo::CKINT compress_level) {
if (m_IsFreezed || m_IsReader) return false; if (m_IsFreezed || m_IsReader) return false;
// create temp writer
LibCmo::CK2::CKFileWriter writer(m_Context);
// fill object data
for (const auto& id : m_ObjGroups) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_Obj3dObjects) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_ObjMeshs) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_ObjMaterials) {
writer.AddSavedObject(m_Context->GetObject(id));
}
for (const auto& id : m_ObjTextures) {
writer.AddSavedObject(m_Context->GetObject(id));
}
// set compress level
m_Context->SetCompressionLevel(compress_level);
// save to file and detect error
LibCmo::CK2::CKERROR err = writer.Save(filename);
// set freezed to stop any change again. // set freezed to stop any change again.
// aka, only allow save once. // aka, only allow save once.
m_IsFreezed = true; m_IsFreezed = true;
return true;
// return with error detect.
return err == LibCmo::CK2::CKERROR::CKERR_OK;
} }
LibCmo::CK2::ObjImpls::CKObject* BMFile::GetObjectPtr(LibCmo::CK2::CK_ID objid) { LibCmo::CK2::ObjImpls::CKObject* BMFile::GetObjectPtr(LibCmo::CK2::CK_ID objid) {

View File

@ -9,6 +9,7 @@ Use VTAll.hpp for project internal including.
#include "VTAll.hpp" #include "VTAll.hpp"
#include "CK2/CKContext.hpp" #include "CK2/CKContext.hpp"
#include "CK2/CKStateChunk.hpp" #include "CK2/CKStateChunk.hpp"
#include "CK2/CKFile.hpp"
// Data handlers // Data handlers
#include "CK2/DataHandlers/CKBitmapHandler.hpp" #include "CK2/DataHandlers/CKBitmapHandler.hpp"

View File

@ -122,7 +122,7 @@ namespace Unvirt::StructFormatter {
LibCmo::CKDWORD count = obj->GetObjectCount(); LibCmo::CKDWORD count = obj->GetObjectCount();
fprintf(stdout, "Group Object Count: %" PRIuCKDWORD "\n", count); fprintf(stdout, "Group Object Count: %" PRIuCKDWORD "\n", count);
fputs("Id\tType\tObject Pointer\tName\n", stdout); fputs("CKID\tType\tObject\tName\n", stdout);
for (LibCmo::CKDWORD i = 0; i < count; ++i) { for (LibCmo::CKDWORD i = 0; i < count; ++i) {
LibCmo::CK2::ObjImpls::CKBeObject* beobj = obj->GetObject(i); LibCmo::CK2::ObjImpls::CKBeObject* beobj = obj->GetObject(i);

View File

@ -618,6 +618,43 @@ namespace Unvirt::Context {
#if defined(LIBCMO_BUILD_DEBUG) #if defined(LIBCMO_BUILD_DEBUG)
// MARK: Add the debug code here. // MARK: Add the debug code here.
// todo: temporaryly write Transparent Column Fixer code.
// move to independent app in future.
// check pre-requirement
if (!HasOpenedFile()) {
PrintCommonError("No loaded file.");
return;
}
if (!m_IsShallowRead) {
PrintCommonError("Transparent Column Fixer only accept shallow loaded file.");
return;
}
// iterate objects
LibCmo::CKDWORD expcode = static_cast<LibCmo::CKDWORD>(LibCmo::CK2::CK_STATESAVEFLAGS_TEXTURE::CK_STATESAVE_TEXONLY);
LibCmo::CKDWORD modcode = static_cast<LibCmo::CKDWORD>(LibCmo::CK2::CK_STATESAVEFLAGS_TEXTURE::CK_STATESAVE_OLDTEXONLY);
for (const auto& cobj : m_FileReader->GetFileObjects()) {
if (cobj.ObjectCid == LibCmo::CK2::CK_CLASSID::CKCID_TEXTURE && cobj.Data != nullptr) {
LibCmo::CK2::CKFileObject& obj = const_cast<LibCmo::CK2::CKFileObject&>(cobj);
obj.Data->StartRead();
auto chunkinfo = obj.Data->GetIdentifiersProfile();
obj.Data->StopRead();
// find CK_STATESAVE_TEXONLY and change it to CK_STATESAVE_OLDTEXONLY
for (const auto& entry : chunkinfo) {
if (entry.m_Identifier == expcode) {
LibCmo::CKDWORD* p = static_cast<LibCmo::CKDWORD*>(entry.m_DataPtr);
p -= 2;
if (*p == expcode) {
*p = modcode;
}
}
}
}
}
#else #else
PrintCommonError("Test command only available in Debug mode."); PrintCommonError("Test command only available in Debug mode.");
#endif #endif

View File

@ -4,9 +4,7 @@
#include "StructFormatter.hpp" #include "StructFormatter.hpp"
#include "CmdHelper.hpp" #include "CmdHelper.hpp"
#include <VTAll.hpp> #include <VTUserAll.hpp>
#include <CK2/CKContext.hpp>
#include <CK2/CKFile.hpp>
#include <cstdio> #include <cstdio>
#include <iostream> #include <iostream>