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:
parent
6870fca911
commit
b2d0b743cb
|
@ -172,7 +172,7 @@ namespace LibCmo::CK2 {
|
||||||
CKFileVisitor& operator=(const CKFileVisitor&);
|
CKFileVisitor& operator=(const CKFileVisitor&);
|
||||||
CKFileVisitor& operator=(CKFileVisitor&&);
|
CKFileVisitor& operator=(CKFileVisitor&&);
|
||||||
|
|
||||||
const CKFileObject* GetFileObjectByIndex(size_t index);
|
const CKFileObject* GetFileObjectByIndex(CKDWORD index);
|
||||||
CKDWORD GetIndexByObjectID(CK_ID objid);
|
CKDWORD GetIndexByObjectID(CK_ID objid);
|
||||||
protected:
|
protected:
|
||||||
bool m_IsReader;
|
bool m_IsReader;
|
||||||
|
|
|
@ -284,12 +284,12 @@ namespace LibCmo::CK2 {
|
||||||
|
|
||||||
CKFileVisitor::CKFileVisitor(CKFileReader* reader) :
|
CKFileVisitor::CKFileVisitor(CKFileReader* reader) :
|
||||||
m_IsReader(true), m_Reader(reader), m_Writer(nullptr), m_Ctx(reader->m_Ctx) {
|
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) :
|
CKFileVisitor::CKFileVisitor(CKFileWriter* writer) :
|
||||||
m_IsReader(false), m_Reader(nullptr), m_Writer(writer), m_Ctx(writer->m_Ctx) {
|
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) :
|
CKFileVisitor::CKFileVisitor(const CKFileVisitor& rhs) :
|
||||||
|
@ -316,7 +316,7 @@ namespace LibCmo::CK2 {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CKFileObject* CKFileVisitor::GetFileObjectByIndex(size_t index) {
|
const CKFileObject* CKFileVisitor::GetFileObjectByIndex(CKDWORD index) {
|
||||||
if (m_IsReader) {
|
if (m_IsReader) {
|
||||||
return &m_Reader->m_FileObjects[index];
|
return &m_Reader->m_FileObjects[index];
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -267,7 +267,7 @@ namespace LibCmo::CK2 {
|
||||||
|
|
||||||
// find direct parent
|
// find direct parent
|
||||||
CKClassDesc& parent = g_CKClassInfo[static_cast<size_t>(desc.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 it is not self inheritance, call recursively
|
||||||
if (desc.Self != desc.Parent) {
|
if (desc.Self != desc.Parent) {
|
||||||
|
@ -291,7 +291,7 @@ namespace LibCmo::CK2 {
|
||||||
|
|
||||||
// find direct parent
|
// find direct parent
|
||||||
CKClassDesc& parent = g_CKClassInfo[static_cast<size_t>(desc.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 it is not self inheritance, call recursively
|
||||||
if (desc.Self != desc.Parent) {
|
if (desc.Self != desc.Parent) {
|
||||||
|
|
|
@ -149,7 +149,7 @@ namespace LibCmo::CK2 {
|
||||||
if (id == nullptr) return false;
|
if (id == nullptr) return false;
|
||||||
|
|
||||||
// get basic value
|
// get basic value
|
||||||
CKINT gotten_id = 0;
|
CKDWORD gotten_id = 0;
|
||||||
if (!this->ReadStruct(gotten_id)) return false;
|
if (!this->ReadStruct(gotten_id)) return false;
|
||||||
|
|
||||||
// different strategy according to chunk ver
|
// different strategy according to chunk ver
|
||||||
|
@ -162,7 +162,7 @@ namespace LibCmo::CK2 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// if it is positive, return corresponding value
|
// if it is positive, return corresponding value
|
||||||
if (gotten_id >= 0) {
|
if ((gotten_id & 0x80000000) == 0) {
|
||||||
*id = this->m_BindFile->GetFileObjectByIndex(gotten_id)->CreatedObjectId;
|
*id = this->m_BindFile->GetFileObjectByIndex(gotten_id)->CreatedObjectId;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,22 +3,6 @@
|
||||||
#include "CKContext.hpp"
|
#include "CKContext.hpp"
|
||||||
#include "ObjImpls/CKObject.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 {
|
namespace LibCmo::CK2 {
|
||||||
|
|
||||||
void CKStateChunk::StartWrite() {
|
void CKStateChunk::StartWrite() {
|
||||||
|
@ -166,9 +150,21 @@ namespace LibCmo::CK2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CKStateChunk::WriteObjectID(const CK_ID* id) {
|
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.
|
// if BindFile is not nullptr,
|
||||||
// but we assume BindFile always it not nullptr, so I remove that pushing code.
|
// no need to push this obj into obj list according to IDA code.
|
||||||
return this->WriteStruct(m_BindFile->GetIndexByObjectID(*id));
|
|
||||||
|
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) {
|
bool CKStateChunk::WriteObjectPointer(ObjImpls::CKObject* obj) {
|
||||||
|
@ -223,19 +219,25 @@ namespace LibCmo::CK2 {
|
||||||
bool CKStateChunk::WriteObjectIDSequence(const XContainer::XObjectArray* ls) {
|
bool CKStateChunk::WriteObjectIDSequence(const XContainer::XObjectArray* ls) {
|
||||||
if (ls == nullptr) return false;
|
if (ls == nullptr) return false;
|
||||||
|
|
||||||
// MARK: there is a recording oper for object list when no bind file.
|
// add current pos into manager list if no bind file
|
||||||
// but we always have bind file, so ignore it
|
if (ls->size() != 0 && m_BindFile == nullptr) {
|
||||||
|
AddEntries(m_ObjectList, m_Parser.m_CurrentPos);
|
||||||
|
}
|
||||||
|
|
||||||
// write size first
|
// write size first
|
||||||
CKDWORD objidsize = static_cast<CKDWORD>(ls->size());
|
CKDWORD objidsize = static_cast<CKDWORD>(ls->size());
|
||||||
if (!this->WriteStruct(objidsize)) return false;
|
if (!this->WriteStruct(objidsize)) return false;
|
||||||
|
|
||||||
// write each data
|
// write each item
|
||||||
for (auto objid : *ls) {
|
for (auto objid : *ls) {
|
||||||
// MARK: originally we should not call WriteObjectID like ReadObjectIDSequence.
|
// because we do not want write position data in obj list for each item.
|
||||||
// because we do not write position data in obj list for each item.
|
// so we do not call WriteObjectID here.
|
||||||
// even if bind file always is not nullptr.
|
if (m_BindFile != nullptr) {
|
||||||
if (!this->WriteStruct(m_BindFile->GetIndexByObjectID(objid))) return false;
|
if (!this->WriteStruct(m_BindFile->GetIndexByObjectID(objid))) return false;
|
||||||
|
} else {
|
||||||
|
if (!this->WriteStruct(static_cast<CKDWORD>(objid))) return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -271,6 +273,7 @@ namespace LibCmo::CK2 {
|
||||||
bool CKStateChunk::WriteXObjectPointerArray(const XContainer::XObjectPointerArray* ls) {
|
bool CKStateChunk::WriteXObjectPointerArray(const XContainer::XObjectPointerArray* ls) {
|
||||||
if (ls == nullptr) return false;
|
if (ls == nullptr) return false;
|
||||||
|
|
||||||
|
// convert to id list and pass to id writer.
|
||||||
XContainer::XObjectArray conv;
|
XContainer::XObjectArray conv;
|
||||||
for (auto obj : *ls) {
|
for (auto obj : *ls) {
|
||||||
if (obj == nullptr) conv.emplace_back(0);
|
if (obj == nullptr) conv.emplace_back(0);
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#include "CKBitmapHandler.hpp"
|
#include "CKBitmapHandler.hpp"
|
||||||
|
#include "stb_image.h"
|
||||||
|
#include "stb_image_write.h"
|
||||||
|
|
||||||
namespace LibCmo::CK2::DataHandlers {
|
namespace LibCmo::CK2::DataHandlers {
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,14 @@ namespace LibCmo::CK2::MgrImpls {
|
||||||
return false;
|
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) {
|
void CKPathManager::GetExtension(XContainer::XString& u8path) {
|
||||||
std::filesystem::path filepath;
|
std::filesystem::path filepath;
|
||||||
EncodingHelper::U8PathToStdPath(filepath, u8path.c_str());
|
EncodingHelper::U8PathToStdPath(filepath, u8path.c_str());
|
||||||
|
|
|
@ -53,9 +53,15 @@ namespace LibCmo::CK2::MgrImpls {
|
||||||
*/
|
*/
|
||||||
bool ResolveFileName(XContainer::XString& u8_filename);
|
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 (.)
|
* @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);
|
void GetExtension(XContainer::XString& u8path);
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,6 @@
|
||||||
<ClInclude Include="VTAll.hpp" />
|
<ClInclude Include="VTAll.hpp" />
|
||||||
<ClInclude Include="VTEncoding.hpp" />
|
<ClInclude Include="VTEncoding.hpp" />
|
||||||
<ClInclude Include="CK2\ObjImpls\CKObject.hpp" />
|
<ClInclude Include="CK2\ObjImpls\CKObject.hpp" />
|
||||||
<ClInclude Include="VTImage.hpp" />
|
|
||||||
<ClInclude Include="VTUserAll.hpp" />
|
<ClInclude Include="VTUserAll.hpp" />
|
||||||
<ClInclude Include="VTUtils.hpp" />
|
<ClInclude Include="VTUtils.hpp" />
|
||||||
<ClInclude Include="VxMath\VxEnums.hpp" />
|
<ClInclude Include="VxMath\VxEnums.hpp" />
|
||||||
|
|
|
@ -224,9 +224,6 @@
|
||||||
<ClInclude Include="CK2\ObjImpls\CKMesh.hpp">
|
<ClInclude Include="CK2\ObjImpls\CKMesh.hpp">
|
||||||
<Filter>Headers\CK2\ObjImpls</Filter>
|
<Filter>Headers\CK2\ObjImpls</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="VTImage.hpp">
|
|
||||||
<Filter>Headers</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="VTUserAll.hpp">
|
<ClInclude Include="VTUserAll.hpp">
|
||||||
<Filter>Headers</Filter>
|
<Filter>Headers</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -38,10 +38,6 @@ Use native Win32 function in Windows.
|
||||||
And use iconv under other OS.
|
And use iconv under other OS.
|
||||||
*/
|
*/
|
||||||
#include "VTEncoding.hpp"
|
#include "VTEncoding.hpp"
|
||||||
/*
|
|
||||||
System independent image loader / saver
|
|
||||||
*/
|
|
||||||
#include "VTImage.hpp"
|
|
||||||
|
|
||||||
// Define the basic type of CK2.
|
// Define the basic type of CK2.
|
||||||
#include "CK2/CKTypes.hpp"
|
#include "CK2/CKTypes.hpp"
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
// Bad wrapper for stb image library.
|
|
||||||
|
|
||||||
#include "stb_image.h"
|
|
||||||
#include "stb_image_write.h"
|
|
||||||
#include "stb_image_resize.h"
|
|
|
@ -1,5 +1,16 @@
|
||||||
#include "VTUtils.hpp"
|
#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 {
|
namespace LibCmo {
|
||||||
|
|
||||||
void LibPanic(int line, const char* file, const char* errmsg) {
|
void LibPanic(int line, const char* file, const char* errmsg) {
|
||||||
|
@ -8,4 +19,18 @@ namespace LibCmo {
|
||||||
std::abort();
|
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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,7 +77,21 @@
|
||||||
namespace LibCmo {
|
namespace LibCmo {
|
||||||
|
|
||||||
[[noreturn]] void LibPanic(int line, const char* file, const char* errmsg);
|
[[noreturn]] void LibPanic(int line, const char* file, const char* errmsg);
|
||||||
#define LIBPANIC(msg) LibCmo::LibPanic(__LINE__, __FILE__, msg);
|
#define LIBCMO_PANIC(msg) LibCmo::LibPanic(__LINE__, __FILE__, msg);
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
#define LIBCMO_ORDER_DEBUGGER LibOrderDebugger();
|
||||||
|
#else
|
||||||
|
// define a blank one
|
||||||
|
#define LIBCMO_ORDER_DEBUGGER
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace EnumsHelper {
|
namespace EnumsHelper {
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "../VTImage.hpp"
|
|
||||||
#include "VxMath.hpp"
|
#include "VxMath.hpp"
|
||||||
|
#include "stb_image_resize.h"
|
||||||
|
|
||||||
|
|
||||||
namespace LibCmo::VxMath {
|
namespace LibCmo::VxMath {
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user