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:
yyc12345 2023-09-24 20:56:23 +08:00
parent 6870fca911
commit b2d0b743cb
15 changed files with 96 additions and 52 deletions

View File

@ -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;

View File

@ -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 {

View File

@ -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) {

View File

@ -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;
}

View File

@ -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);

View File

@ -1,4 +1,6 @@
#include "CKBitmapHandler.hpp"
#include "stb_image.h"
#include "stb_image_write.h"
namespace LibCmo::CK2::DataHandlers {

View File

@ -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());

View File

@ -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);

View File

@ -228,7 +228,6 @@
<ClInclude Include="VTAll.hpp" />
<ClInclude Include="VTEncoding.hpp" />
<ClInclude Include="CK2\ObjImpls\CKObject.hpp" />
<ClInclude Include="VTImage.hpp" />
<ClInclude Include="VTUserAll.hpp" />
<ClInclude Include="VTUtils.hpp" />
<ClInclude Include="VxMath\VxEnums.hpp" />

View File

@ -224,9 +224,6 @@
<ClInclude Include="CK2\ObjImpls\CKMesh.hpp">
<Filter>Headers\CK2\ObjImpls</Filter>
</ClInclude>
<ClInclude Include="VTImage.hpp">
<Filter>Headers</Filter>
</ClInclude>
<ClInclude Include="VTUserAll.hpp">
<Filter>Headers</Filter>
</ClInclude>

View File

@ -38,10 +38,6 @@ Use native Win32 function in Windows.
And use iconv under other OS.
*/
#include "VTEncoding.hpp"
/*
System independent image loader / saver
*/
#include "VTImage.hpp"
// Define the basic type of CK2.
#include "CK2/CKTypes.hpp"

View File

@ -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"

View File

@ -1,5 +1,16 @@
#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) {
@ -8,4 +19,18 @@ namespace LibCmo {
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

@ -77,7 +77,21 @@
namespace LibCmo {
[[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 {

View File

@ -1,5 +1,6 @@
#include "../VTImage.hpp"
#include "VxMath.hpp"
#include "stb_image_resize.h"
namespace LibCmo::VxMath {