improve proj
- remove VTImage.hpp to make sure stb image do not need external project to ref. - finish CKStateChunk write part. add some compatibilty code. - add debugger pause function - add filename getter for CKPathManager.
This commit is contained in:
@ -172,7 +172,7 @@ namespace LibCmo::CK2 {
|
||||
CKFileVisitor& operator=(const CKFileVisitor&);
|
||||
CKFileVisitor& operator=(CKFileVisitor&&);
|
||||
|
||||
const CKFileObject* GetFileObjectByIndex(size_t index);
|
||||
const CKFileObject* GetFileObjectByIndex(CKDWORD index);
|
||||
CKDWORD GetIndexByObjectID(CK_ID objid);
|
||||
protected:
|
||||
bool m_IsReader;
|
||||
|
@ -284,12 +284,12 @@ namespace LibCmo::CK2 {
|
||||
|
||||
CKFileVisitor::CKFileVisitor(CKFileReader* reader) :
|
||||
m_IsReader(true), m_Reader(reader), m_Writer(nullptr), m_Ctx(reader->m_Ctx) {
|
||||
if (reader == nullptr) LIBPANIC("Reader is nullptr.");
|
||||
if (reader == nullptr) LIBCMO_PANIC("Reader is nullptr.");
|
||||
}
|
||||
|
||||
CKFileVisitor::CKFileVisitor(CKFileWriter* writer) :
|
||||
m_IsReader(false), m_Reader(nullptr), m_Writer(writer), m_Ctx(writer->m_Ctx) {
|
||||
if (writer == nullptr) LIBPANIC("Writer is nullptr.");
|
||||
if (writer == nullptr) LIBCMO_PANIC("Writer is nullptr.");
|
||||
}
|
||||
|
||||
CKFileVisitor::CKFileVisitor(const CKFileVisitor& rhs) :
|
||||
@ -316,7 +316,7 @@ namespace LibCmo::CK2 {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const CKFileObject* CKFileVisitor::GetFileObjectByIndex(size_t index) {
|
||||
const CKFileObject* CKFileVisitor::GetFileObjectByIndex(CKDWORD index) {
|
||||
if (m_IsReader) {
|
||||
return &m_Reader->m_FileObjects[index];
|
||||
} else {
|
||||
|
@ -267,7 +267,7 @@ namespace LibCmo::CK2 {
|
||||
|
||||
// find direct parent
|
||||
CKClassDesc& parent = g_CKClassInfo[static_cast<size_t>(desc.Parent)];
|
||||
if (!parent.IsValid) LIBPANIC("No such CK_CLASSID.");
|
||||
if (!parent.IsValid) LIBCMO_PANIC("No such CK_CLASSID.");
|
||||
|
||||
// if it is not self inheritance, call recursively
|
||||
if (desc.Self != desc.Parent) {
|
||||
@ -291,7 +291,7 @@ namespace LibCmo::CK2 {
|
||||
|
||||
// find direct parent
|
||||
CKClassDesc& parent = g_CKClassInfo[static_cast<size_t>(desc.Parent)];
|
||||
if (!parent.IsValid) LIBPANIC("No such CK_CLASSID.");
|
||||
if (!parent.IsValid) LIBCMO_PANIC("No such CK_CLASSID.");
|
||||
|
||||
// if it is not self inheritance, call recursively
|
||||
if (desc.Self != desc.Parent) {
|
||||
|
@ -149,7 +149,7 @@ namespace LibCmo::CK2 {
|
||||
if (id == nullptr) return false;
|
||||
|
||||
// get basic value
|
||||
CKINT gotten_id = 0;
|
||||
CKDWORD gotten_id = 0;
|
||||
if (!this->ReadStruct(gotten_id)) return false;
|
||||
|
||||
// different strategy according to chunk ver
|
||||
@ -162,7 +162,7 @@ namespace LibCmo::CK2 {
|
||||
return true;
|
||||
}
|
||||
// if it is positive, return corresponding value
|
||||
if (gotten_id >= 0) {
|
||||
if ((gotten_id & 0x80000000) == 0) {
|
||||
*id = this->m_BindFile->GetFileObjectByIndex(gotten_id)->CreatedObjectId;
|
||||
return true;
|
||||
}
|
||||
|
@ -3,22 +3,6 @@
|
||||
#include "CKContext.hpp"
|
||||
#include "ObjImpls/CKObject.hpp"
|
||||
|
||||
/*
|
||||
Memorandum:
|
||||
|
||||
No need to write any data in m_ObjectList when writing Object ID.
|
||||
Because m_ObjectList only need to be written in when no bind CKFile
|
||||
according to IDA reversed code.
|
||||
However we assuem all CKStateChunk have bind file so no need to treat it.
|
||||
|
||||
However, m_ManagerList should be filled when writing Manager Int.
|
||||
This is also instructed by IDA revsersed code.
|
||||
|
||||
For m_ChunkList, it is same as m_ManagerList. We need write it.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
namespace LibCmo::CK2 {
|
||||
|
||||
void CKStateChunk::StartWrite() {
|
||||
@ -166,9 +150,21 @@ namespace LibCmo::CK2 {
|
||||
}
|
||||
|
||||
bool CKStateChunk::WriteObjectID(const CK_ID* id) {
|
||||
// MARK: if BindFile is not nullptr, no need to push this obj into obj list according to IDA code.
|
||||
// but we assume BindFile always it not nullptr, so I remove that pushing code.
|
||||
return this->WriteStruct(m_BindFile->GetIndexByObjectID(*id));
|
||||
// if BindFile is not nullptr,
|
||||
// no need to push this obj into obj list according to IDA code.
|
||||
|
||||
if (m_BindFile != nullptr) {
|
||||
this->WriteStruct(m_BindFile->GetIndexByObjectID(id != nullptr ? (*id) : 0));
|
||||
} else {
|
||||
if (id != nullptr) {
|
||||
AddEntry(m_ObjectList, m_Parser.m_CurrentPos);
|
||||
this->WriteStruct(id);
|
||||
} else {
|
||||
this->WriteStruct(static_cast<CKDWORD>(0));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CKStateChunk::WriteObjectPointer(ObjImpls::CKObject* obj) {
|
||||
@ -223,19 +219,25 @@ namespace LibCmo::CK2 {
|
||||
bool CKStateChunk::WriteObjectIDSequence(const XContainer::XObjectArray* ls) {
|
||||
if (ls == nullptr) return false;
|
||||
|
||||
// MARK: there is a recording oper for object list when no bind file.
|
||||
// but we always have bind file, so ignore it
|
||||
// add current pos into manager list if no bind file
|
||||
if (ls->size() != 0 && m_BindFile == nullptr) {
|
||||
AddEntries(m_ObjectList, m_Parser.m_CurrentPos);
|
||||
}
|
||||
|
||||
// write size first
|
||||
CKDWORD objidsize = static_cast<CKDWORD>(ls->size());
|
||||
if (!this->WriteStruct(objidsize)) return false;
|
||||
|
||||
// write each data
|
||||
// write each item
|
||||
for (auto objid : *ls) {
|
||||
// MARK: originally we should not call WriteObjectID like ReadObjectIDSequence.
|
||||
// because we do not write position data in obj list for each item.
|
||||
// even if bind file always is not nullptr.
|
||||
if (!this->WriteStruct(m_BindFile->GetIndexByObjectID(objid))) return false;
|
||||
// because we do not want write position data in obj list for each item.
|
||||
// so we do not call WriteObjectID here.
|
||||
if (m_BindFile != nullptr) {
|
||||
if (!this->WriteStruct(m_BindFile->GetIndexByObjectID(objid))) return false;
|
||||
} else {
|
||||
if (!this->WriteStruct(static_cast<CKDWORD>(objid))) return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -271,6 +273,7 @@ namespace LibCmo::CK2 {
|
||||
bool CKStateChunk::WriteXObjectPointerArray(const XContainer::XObjectPointerArray* ls) {
|
||||
if (ls == nullptr) return false;
|
||||
|
||||
// convert to id list and pass to id writer.
|
||||
XContainer::XObjectArray conv;
|
||||
for (auto obj : *ls) {
|
||||
if (obj == nullptr) conv.emplace_back(0);
|
||||
|
@ -1,4 +1,6 @@
|
||||
#include "CKBitmapHandler.hpp"
|
||||
#include "stb_image.h"
|
||||
#include "stb_image_write.h"
|
||||
|
||||
namespace LibCmo::CK2::DataHandlers {
|
||||
|
||||
|
@ -99,6 +99,14 @@ namespace LibCmo::CK2::MgrImpls {
|
||||
return false;
|
||||
}
|
||||
|
||||
void CKPathManager::GetFileName(XContainer::XString& u8path) {
|
||||
std::filesystem::path filepath;
|
||||
EncodingHelper::U8PathToStdPath(filepath, u8path.c_str());
|
||||
|
||||
auto result = filepath.filename();
|
||||
EncodingHelper::StdPathToU8Path(u8path, result);
|
||||
}
|
||||
|
||||
void CKPathManager::GetExtension(XContainer::XString& u8path) {
|
||||
std::filesystem::path filepath;
|
||||
EncodingHelper::U8PathToStdPath(filepath, u8path.c_str());
|
||||
|
@ -53,9 +53,15 @@ namespace LibCmo::CK2::MgrImpls {
|
||||
*/
|
||||
bool ResolveFileName(XContainer::XString& u8_filename);
|
||||
|
||||
/**
|
||||
* @brief Get file name part of given path.
|
||||
* @param u8path[inout] The given path. overwritten by the gotten file name.
|
||||
*/
|
||||
void GetFileName(XContainer::XString& u8path);
|
||||
|
||||
/**
|
||||
* @brief Returns the file extension including period (.)
|
||||
* @param u8path[inout] The given path. overwritten by the gotten extension. set to blank when failed.
|
||||
* @param u8path[inout] The given path. overwritten by the gotten extension.
|
||||
*/
|
||||
void GetExtension(XContainer::XString& u8path);
|
||||
|
||||
|
Reference in New Issue
Block a user