now can read CKMesh without memory issue
This commit is contained in:
		@ -17,7 +17,7 @@ namespace LibCmo::CK2 {
 | 
				
			|||||||
		// get ext and guid to find correct guid
 | 
							// get ext and guid to find correct guid
 | 
				
			||||||
		CKCHAR filerawext[4];
 | 
							CKCHAR filerawext[4];
 | 
				
			||||||
		CKGUID fileguid;
 | 
							CKGUID fileguid;
 | 
				
			||||||
		chk->ReadNoSizeBuffer(CKSizeof(filerawext), filerawext);
 | 
							chk->ReadAndFillBuffer(filerawext, CKSizeof(filerawext));
 | 
				
			||||||
		chk->ReadStruct(fileguid);
 | 
							chk->ReadStruct(fileguid);
 | 
				
			||||||
		CKFileExtension fileext(filerawext);
 | 
							CKFileExtension fileext(filerawext);
 | 
				
			||||||
		auto reader = DataHandlers::CKBitmapHandler::GetBitmapHandlerWrapper(fileext, fileguid);
 | 
							auto reader = DataHandlers::CKBitmapHandler::GetBitmapHandlerWrapper(fileext, fileguid);
 | 
				
			||||||
@ -56,7 +56,7 @@ namespace LibCmo::CK2 {
 | 
				
			|||||||
					VxMath::VxDoAlphaBlit(slot, static_cast<CKBYTE>(globalalpha));
 | 
										VxMath::VxDoAlphaBlit(slot, static_cast<CKBYTE>(globalalpha));
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					auto alphabuf = chk->ReadBufferWrapper();
 | 
										auto alphabuf = chk->ReadBufferWrapper();
 | 
				
			||||||
					VxMath::VxDoAlphaBlit(slot, reinterpret_cast<CKBYTE*>(alphabuf.get()));
 | 
										VxMath::VxDoAlphaBlit(slot, reinterpret_cast<const CKBYTE*>(alphabuf.get()));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -79,7 +79,6 @@ namespace LibCmo::CK2 {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		// read RGBA buffer
 | 
							// read RGBA buffer
 | 
				
			||||||
		CKStateChunk::Buffer_t redBuffer, greenBuffer, blueBuffer, alphaBuffer;
 | 
							CKStateChunk::Buffer_t redBuffer, greenBuffer, blueBuffer, alphaBuffer;
 | 
				
			||||||
		CKDWORD bufsize;
 | 
					 | 
				
			||||||
		CKDWORD bufopt;
 | 
							CKDWORD bufopt;
 | 
				
			||||||
		chk->ReadStruct(bufopt);
 | 
							chk->ReadStruct(bufopt);
 | 
				
			||||||
		bufopt &= 0xFu;
 | 
							bufopt &= 0xFu;
 | 
				
			||||||
 | 
				
			|||||||
@ -19,6 +19,7 @@
 | 
				
			|||||||
#include "ObjImpls/CK3dObject.hpp"
 | 
					#include "ObjImpls/CK3dObject.hpp"
 | 
				
			||||||
#include "ObjImpls/CKTexture.hpp"
 | 
					#include "ObjImpls/CKTexture.hpp"
 | 
				
			||||||
#include "ObjImpls/CKMaterial.hpp"
 | 
					#include "ObjImpls/CKMaterial.hpp"
 | 
				
			||||||
 | 
					#include "ObjImpls/CKMesh.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace LibCmo::CK2 {
 | 
					namespace LibCmo::CK2 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -414,6 +415,7 @@ CKClassRegister(cid, parentCid, \
 | 
				
			|||||||
		EasyClassReg(ObjImpls::CK3dObject, CK_CLASSID::CKCID_3DOBJECT, CK_CLASSID::CKCID_3DENTITY, "3D Object");
 | 
							EasyClassReg(ObjImpls::CK3dObject, CK_CLASSID::CKCID_3DOBJECT, CK_CLASSID::CKCID_3DENTITY, "3D Object");
 | 
				
			||||||
		EasyClassReg(ObjImpls::CKTexture, CK_CLASSID::CKCID_TEXTURE, CK_CLASSID::CKCID_BEOBJECT, "Texture");
 | 
							EasyClassReg(ObjImpls::CKTexture, CK_CLASSID::CKCID_TEXTURE, CK_CLASSID::CKCID_BEOBJECT, "Texture");
 | 
				
			||||||
		EasyClassReg(ObjImpls::CKMaterial, CK_CLASSID::CKCID_MATERIAL, CK_CLASSID::CKCID_BEOBJECT, "Material");
 | 
							EasyClassReg(ObjImpls::CKMaterial, CK_CLASSID::CKCID_MATERIAL, CK_CLASSID::CKCID_BEOBJECT, "Material");
 | 
				
			||||||
 | 
							EasyClassReg(ObjImpls::CKMesh, CK_CLASSID::CKCID_MESH, CK_CLASSID::CKCID_BEOBJECT, "Mesh");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef EasyClassReg
 | 
					#undef EasyClassReg
 | 
				
			||||||
#undef EasyClassRegWithNotify
 | 
					#undef EasyClassRegWithNotify
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,7 @@ namespace LibCmo::CK2 {
 | 
				
			|||||||
			CKStateChunk* m_Host;
 | 
								CKStateChunk* m_Host;
 | 
				
			||||||
			CKDWORD m_ConsumedSize;
 | 
								CKDWORD m_ConsumedSize;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		class BufferDeleter {
 | 
							class BufferDeleter {
 | 
				
			||||||
		public:
 | 
							public:
 | 
				
			||||||
			BufferDeleter() : m_Host(nullptr), m_BufSize(0) {}
 | 
								BufferDeleter() : m_Host(nullptr), m_BufSize(0) {}
 | 
				
			||||||
@ -333,73 +333,89 @@ namespace LibCmo::CK2 {
 | 
				
			|||||||
		/*
 | 
							/*
 | 
				
			||||||
		Buffer related function implements:
 | 
							Buffer related function implements:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ReadBuffer(void**)						Read Byte based size.		-> ReadBuffer
 | 
							ReadBuffer(void**)						Read Byte based size.		-> ReadAndCopyBuffer(void**, CKDWORD*)
 | 
				
			||||||
		ReadAndFillBuffer(int, void*)			User give Byte based size.	-> ReadNoSizeBuffer
 | 
							ReadAndFillBuffer(int, void*)			User give Byte based size.	-> ReadBuffer(const void**, CKDWORD)
 | 
				
			||||||
		ReadAndFillBuffer(void*)				Read Byte based size.		-> ReadBuffer
 | 
							ReadAndFillBuffer(void*)				Read Byte based size.		-> ReadBuffer(const void**, CKDWORD*)
 | 
				
			||||||
		ReadAndFillBuffer_LEndian(int, void*)	User give Byte based size.	-> ReadNoSizeBuffer
 | 
							ReadAndFillBuffer_LEndian(int, void*)	User give Byte based size.	-> ReadBuffer(const void**, CKDWORD)
 | 
				
			||||||
		ReadAndFillBuffer_LEndian(void*)		Read Byte based size.		-> ReadBuffer
 | 
							ReadAndFillBuffer_LEndian(void*)		Read Byte based size.		-> ReadBuffer(const void**, CKDWORD*)
 | 
				
			||||||
		ReadAndFillBuffer_LEndian16(int, void*)	User give Byte based size.	-> ReadNoSizeBuffer
 | 
							ReadAndFillBuffer_LEndian16(int, void*)	User give Byte based size.	-> ReadBuffer(const void**, CKDWORD)
 | 
				
			||||||
		ReadAndFillBuffer_LEndian16(void*)		Read Byte based size.		-> ReadBuffer
 | 
							ReadAndFillBuffer_LEndian16(void*)		Read Byte based size.		-> ReadBuffer(const void**, CKDWORD*)
 | 
				
			||||||
		*/
 | 
							*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/**
 | 
							/**
 | 
				
			||||||
		 * @brief Read a buffer with unknow size (order user specific it).
 | 
							 * @brief Read buffer and copy it.
 | 
				
			||||||
		 * @param size_in_byte[in] The size of buffer.
 | 
							 * The copied buffer and the size of buffer will be returned to caller.
 | 
				
			||||||
		 * @param allocatedBuf[out] Buffer for filling.
 | 
							 * Caller should free the buffer by calling CKStateChunk::DeleteBuffer(void*).
 | 
				
			||||||
		 * @return true if success.
 | 
							 * @param ppData[out] The pointer to pointer holding the new copied data.
 | 
				
			||||||
		 * @remark
 | 
							 * @param size_in_byte[out] Set to the size of buffer when success.
 | 
				
			||||||
		 * + Following original Virtools functions can use this function to implement:
 | 
							 * @return True if success.
 | 
				
			||||||
		 *   - ReadAndFillBuffer(int, void*)
 | 
					 | 
				
			||||||
		 *   - ReadAndFillBuffer_LEndian(int, void*)
 | 
					 | 
				
			||||||
		 *   - ReadAndFillBuffer_LEndian16(int, void*)
 | 
					 | 
				
			||||||
		*/
 | 
					 | 
				
			||||||
		bool ReadNoSizeBuffer(CKDWORD size_in_byte, void* allocatedBuf);
 | 
					 | 
				
			||||||
		/**
 | 
					 | 
				
			||||||
		 * @brief Read a buffer with knowen size stored in chunk.
 | 
					 | 
				
			||||||
		 * @param buf[out] a pointer to the pointer receiving data start address.
 | 
					 | 
				
			||||||
		 * @param len_in_byte[out] a pointer to the variable receiving the length of gotten buffer.
 | 
					 | 
				
			||||||
		 * @return true if success.
 | 
					 | 
				
			||||||
		 * @remark
 | 
							 * @remark
 | 
				
			||||||
		 * + Following original Virtools functions can use this function to implement:
 | 
							 * + Following original Virtools functions can use this function to implement:
 | 
				
			||||||
		 *   - ReadBuffer(void**)
 | 
							 *   - ReadBuffer(void**)
 | 
				
			||||||
		 *   - ReadAndFillBuffer(void*)
 | 
					 | 
				
			||||||
		 *   - ReadAndFillBuffer_LEndian(void*)
 | 
					 | 
				
			||||||
		 *   - ReadAndFillBuffer_LEndian16(void*)
 | 
					 | 
				
			||||||
		 * + The created buffer should be freed by DeleteBuffer().
 | 
					 | 
				
			||||||
		*/
 | 
							*/
 | 
				
			||||||
		bool ReadBuffer(void** buf, CKDWORD* len_in_byte);
 | 
							bool ReadBuffer(void** ppData, CKDWORD* size_in_byte);
 | 
				
			||||||
 | 
					 | 
				
			||||||
		/**
 | 
							/**
 | 
				
			||||||
		 * @brief Free the buffer allocated by CKStateChunk reading functions.
 | 
							 * @brief Free the buffer allocated by CKStateChunk reading functions.
 | 
				
			||||||
		 * @param buf[in] The buffer need to be free.
 | 
							 * @param buf[in] The buffer need to be free.
 | 
				
			||||||
		 * @see ReadBuffer
 | 
							 * @see ReadBuffer
 | 
				
			||||||
		*/
 | 
							*/
 | 
				
			||||||
		void DeleteBuffer(const void* buf);
 | 
							void DeleteBuffer(const void* buf);
 | 
				
			||||||
 | 
					 | 
				
			||||||
		/**
 | 
							/**
 | 
				
			||||||
		 * @brief A RAII wrapper for ReadBuffer and DeleteBuffer
 | 
							 * @brief A wrapper for ReadAndCopyBuffer(void**, CKDWORD*)
 | 
				
			||||||
		 * @param uptr The pointer to unique_ptr receiving data.
 | 
							 * @return 
 | 
				
			||||||
		 * @param len_in_byte The size of gotten buffer.
 | 
					 | 
				
			||||||
		 * @return A buffer with RAII feature (more like std::unique_ptr).
 | 
					 | 
				
			||||||
		 * @remark
 | 
					 | 
				
			||||||
		 * + The return value is more like std::unique_ptr but it have more features.
 | 
					 | 
				
			||||||
		 * + If Buffer_t::GetPtr return nullptr, it mean this function is failed.
 | 
					 | 
				
			||||||
		 * + Use Buffer_t::GetSize to get the size of buffer.
 | 
					 | 
				
			||||||
		 * + You can use Buffer_t::Reset to force free the return value.
 | 
					 | 
				
			||||||
		 * @example
 | 
					 | 
				
			||||||
		 * ```
 | 
					 | 
				
			||||||
		 * Buffer_t buf = ReadBufferWrapper(1919810);
 | 
					 | 
				
			||||||
		 * if (buf.GetPtr() == nullptr) { 
 | 
					 | 
				
			||||||
		 *     // failed
 | 
					 | 
				
			||||||
		 * } else {
 | 
					 | 
				
			||||||
		 *     stuff(buf); // do some operation...
 | 
					 | 
				
			||||||
		 *     buf.SetSize(114514); // i only consume these bytes.
 | 
					 | 
				
			||||||
		 *     buf.Reset(); // immediately free it.
 | 
					 | 
				
			||||||
		 * }
 | 
					 | 
				
			||||||
		 * ```
 | 
					 | 
				
			||||||
		*/
 | 
							*/
 | 
				
			||||||
		Buffer_t ReadBufferWrapper();
 | 
							Buffer_t ReadBufferWrapper();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * @brief Read buffer and fill user struct.
 | 
				
			||||||
 | 
							 * The size of buffer will be read from CKStateChunk internally and return to caller.
 | 
				
			||||||
 | 
							 * @param pData[out] The pointer holding the data.
 | 
				
			||||||
 | 
							 * @return True if success.
 | 
				
			||||||
 | 
							 * @remark
 | 
				
			||||||
 | 
							 * + Following original Virtools functions can use this function to implement:
 | 
				
			||||||
 | 
							 *   - ReadAndFillBuffer(void*)
 | 
				
			||||||
 | 
							 *   - ReadAndFillBuffer_LEndian(void*)
 | 
				
			||||||
 | 
							 *   - ReadAndFillBuffer_LEndian16(void*)
 | 
				
			||||||
 | 
							*/
 | 
				
			||||||
 | 
							bool ReadAndFillBuffer(void* pData);
 | 
				
			||||||
 | 
							/**
 | 
				
			||||||
 | 
							 * @brief Read buffer and fill user struct.
 | 
				
			||||||
 | 
							 * The size of buffer is provided by user.
 | 
				
			||||||
 | 
							 * @param pData[out] The pointer holding the data.
 | 
				
			||||||
 | 
							 * @param size_in_byte[in] The size of data which you want to read in byte unit
 | 
				
			||||||
 | 
							 * @return True if success.
 | 
				
			||||||
 | 
							 * @remark
 | 
				
			||||||
 | 
							 * + Following original Virtools functions can use this function to implement:
 | 
				
			||||||
 | 
							 *   - ReadAndFillBuffer(int, void*)
 | 
				
			||||||
 | 
							 *   - ReadAndFillBuffer_LEndian(int, void*)
 | 
				
			||||||
 | 
							 *   - ReadAndFillBuffer_LEndian16(int, void*)
 | 
				
			||||||
 | 
							*/
 | 
				
			||||||
 | 
							bool ReadAndFillBuffer(void* pData, CKDWORD size_in_byte);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							///**
 | 
				
			||||||
 | 
							// * @brief A RAII wrapper for ReadBuffer and DeleteBuffer
 | 
				
			||||||
 | 
							// * @param uptr The pointer to unique_ptr receiving data.
 | 
				
			||||||
 | 
							// * @param len_in_byte The size of gotten buffer.
 | 
				
			||||||
 | 
							// * @return A buffer with RAII feature (more like std::unique_ptr).
 | 
				
			||||||
 | 
							// * @remark
 | 
				
			||||||
 | 
							// * + The return value is more like std::unique_ptr but it have more features.
 | 
				
			||||||
 | 
							// * + If Buffer_t::GetPtr return nullptr, it mean this function is failed.
 | 
				
			||||||
 | 
							// * + Use Buffer_t::GetSize to get the size of buffer.
 | 
				
			||||||
 | 
							// * + You can use Buffer_t::Reset to force free the return value.
 | 
				
			||||||
 | 
							// * @example
 | 
				
			||||||
 | 
							// * ```
 | 
				
			||||||
 | 
							// * Buffer_t buf = ReadBufferWrapper(1919810);
 | 
				
			||||||
 | 
							// * if (buf.GetPtr() == nullptr) { 
 | 
				
			||||||
 | 
							// *     // failed
 | 
				
			||||||
 | 
							// * } else {
 | 
				
			||||||
 | 
							// *     stuff(buf); // do some operation...
 | 
				
			||||||
 | 
							// *     buf.SetSize(114514); // i only consume these bytes.
 | 
				
			||||||
 | 
							// *     buf.Reset(); // immediately free it.
 | 
				
			||||||
 | 
							// * }
 | 
				
			||||||
 | 
							// * ```
 | 
				
			||||||
 | 
							//*/
 | 
				
			||||||
 | 
							//Buffer_t ReadBufferWrapper();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* ========== Sequence Functions ==========*/
 | 
							/* ========== Sequence Functions ==========*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
 | 
				
			|||||||
@ -289,57 +289,87 @@ namespace LibCmo::CK2 {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/* ========== Buffer Functions ==========*/
 | 
						/* ========== Buffer Functions ==========*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool CKStateChunk::ReadNoSizeBuffer(CKDWORD size_in_byte, void* allocatedBuf) {
 | 
						bool CKStateChunk::ReadBuffer(void** ppData, CKDWORD* size_in_byte) {
 | 
				
			||||||
		if (allocatedBuf == nullptr) return false;
 | 
							if (ppData == nullptr || size_in_byte == nullptr) return false;
 | 
				
			||||||
		return this->ReadByteData(allocatedBuf, size_in_byte);
 | 
							*ppData = nullptr;
 | 
				
			||||||
	}
 | 
							*size_in_byte = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool CKStateChunk::ReadBuffer(void** buf, CKDWORD* len_in_byte) {
 | 
							// read size first
 | 
				
			||||||
		if (buf == nullptr || len_in_byte == nullptr) return false;
 | 
							if (!this->ReadStruct(size_in_byte)) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
		// get buffer size.
 | 
					 | 
				
			||||||
		CKDWORD bufByteSize = 0u;
 | 
					 | 
				
			||||||
		if (!this->ReadStruct(bufByteSize)) {
 | 
					 | 
				
			||||||
			*buf = nullptr;
 | 
					 | 
				
			||||||
			*len_in_byte = 0;
 | 
					 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		*len_in_byte = bufByteSize;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// special treat for zero length buffer
 | 
							// if it is empty buffer, create a fake buffer
 | 
				
			||||||
		if (bufByteSize == 0) {
 | 
							// and simply return it.
 | 
				
			||||||
			*buf = nullptr;
 | 
							if (*size_in_byte == 0) {
 | 
				
			||||||
 | 
								*ppData = new CKBYTE[1];
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// create buffer
 | 
							// use LockReadBuffer to get pointer
 | 
				
			||||||
		*buf = new CKBYTE[bufByteSize];
 | 
							auto locker = LockReadBufferWrapper(*size_in_byte);
 | 
				
			||||||
 | 
							if (locker == nullptr) {
 | 
				
			||||||
		// read data
 | 
								*size_in_byte = 0;
 | 
				
			||||||
		if (!this->ReadByteData(*buf, bufByteSize)) {
 | 
					 | 
				
			||||||
			this->DeleteBuffer(*buf);
 | 
					 | 
				
			||||||
			*buf = nullptr;
 | 
					 | 
				
			||||||
			*len_in_byte = 0;
 | 
					 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// copy data and unlock buffer
 | 
				
			||||||
 | 
							*ppData = new CKBYTE[*size_in_byte];
 | 
				
			||||||
 | 
							std::memcpy(*ppData, locker.get(), *size_in_byte);
 | 
				
			||||||
 | 
							locker.reset();
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	void CKStateChunk::DeleteBuffer(const void* buf) {
 | 
						void CKStateChunk::DeleteBuffer(const void* buf) {
 | 
				
			||||||
		if (buf == nullptr) return;
 | 
							if (buf == nullptr) return;
 | 
				
			||||||
		delete[] reinterpret_cast<const CKBYTE*>(buf);
 | 
							delete[] reinterpret_cast<const CKBYTE*>(buf);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	CKStateChunk::Buffer_t CKStateChunk::ReadBufferWrapper() {
 | 
						CKStateChunk::Buffer_t CKStateChunk::ReadBufferWrapper() {
 | 
				
			||||||
		void* bufcache = nullptr;
 | 
							void* cache;
 | 
				
			||||||
		CKDWORD len_in_byte;
 | 
							CKDWORD size;
 | 
				
			||||||
		bool ret = ReadBuffer(&bufcache, &len_in_byte);
 | 
							if (!ReadBuffer(&cache, &size)) {
 | 
				
			||||||
		if (ret) {
 | 
					 | 
				
			||||||
			return Buffer_t(bufcache, BufferDeleter(this, len_in_byte));
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			return Buffer_t();
 | 
								return Buffer_t();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							return Buffer_t(cache, BufferDeleter(this, size));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool CKStateChunk::ReadAndFillBuffer(void* pData) {
 | 
				
			||||||
 | 
							if (pData == nullptr) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// get buffer size.
 | 
				
			||||||
 | 
							CKDWORD size_in_byte;
 | 
				
			||||||
 | 
							if (!this->ReadStruct(size_in_byte)) {
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// use LockReadBuffer to get pointer
 | 
				
			||||||
 | 
							// this step can process zero length buffer
 | 
				
			||||||
 | 
							// so we do not treat it specially
 | 
				
			||||||
 | 
							auto locker = LockReadBufferWrapper(size_in_byte);
 | 
				
			||||||
 | 
							if (locker == nullptr) {
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// then copy the data
 | 
				
			||||||
 | 
							std::memcpy(pData, locker.get(), size_in_byte);
 | 
				
			||||||
 | 
							locker.reset();
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool CKStateChunk::ReadAndFillBuffer(void* pData, CKDWORD size_in_byte) {
 | 
				
			||||||
 | 
							if (pData == nullptr) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// directly use LockReadBuffer to get pointer
 | 
				
			||||||
 | 
							auto locker = LockReadBufferWrapper(size_in_byte);
 | 
				
			||||||
 | 
							if (locker == nullptr) {
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// then copy the data
 | 
				
			||||||
 | 
							std::memcpy(pData, locker.get(), size_in_byte);
 | 
				
			||||||
 | 
							locker.reset();
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* ========== Sequence Functions ==========*/
 | 
						/* ========== Sequence Functions ==========*/
 | 
				
			||||||
 | 
				
			|||||||
@ -79,14 +79,16 @@ namespace LibCmo::CK2::ObjImpls {
 | 
				
			|||||||
			// read and set vertex count
 | 
								// read and set vertex count
 | 
				
			||||||
			CKDWORD vertexCount;
 | 
								CKDWORD vertexCount;
 | 
				
			||||||
			chunk->ReadStruct(vertexCount);
 | 
								chunk->ReadStruct(vertexCount);
 | 
				
			||||||
 | 
								SetVertexCount(vertexCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (vertexCount != 0) {
 | 
								if (vertexCount != 0) {
 | 
				
			||||||
				// read save flags
 | 
									// read save flags
 | 
				
			||||||
				chunk->ReadStruct(saveflags);
 | 
									chunk->ReadStruct(saveflags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// read size in dword
 | 
									// read size in dword (including it self)
 | 
				
			||||||
				CKDWORD sizeInDword;
 | 
									CKDWORD sizeInDword;
 | 
				
			||||||
				chunk->ReadStruct(sizeInDword);
 | 
									chunk->ReadStruct(sizeInDword);
 | 
				
			||||||
 | 
									--sizeInDword; // remove self.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// lock read buffer
 | 
									// lock read buffer
 | 
				
			||||||
				auto buf = chunk->LockReadBufferWrapper(sizeInDword * CKSizeof(CKDWORD));
 | 
									auto buf = chunk->LockReadBufferWrapper(sizeInDword * CKSizeof(CKDWORD));
 | 
				
			||||||
@ -211,7 +213,14 @@ namespace LibCmo::CK2::ObjImpls {
 | 
				
			|||||||
			chunk->ReadStruct(lineCount);
 | 
								chunk->ReadStruct(lineCount);
 | 
				
			||||||
			SetLineCount(lineCount);
 | 
								SetLineCount(lineCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			chunk->ReadNoSizeBuffer(lineCount * 2 )
 | 
								chunk->ReadAndFillBuffer(m_LineIndices.data(), CKSizeof(CKWORD) * lineCount * 2);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// build normals
 | 
				
			||||||
 | 
							if (EnumsHelper::Has(saveflags, VertexSaveFlags::NoNormal)) {
 | 
				
			||||||
 | 
								BuildNormals();
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								BuildFaceNormals();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
@ -227,6 +236,10 @@ namespace LibCmo::CK2::ObjImpls {
 | 
				
			|||||||
		SetLineCount(0);
 | 
							SetLineCount(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void CKMesh::BuildNormals() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void CKMesh::BuildFaceNormals() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma region Vertex Section
 | 
					#pragma region Vertex Section
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	CKDWORD CKMesh::GetVertexCount() {
 | 
						CKDWORD CKMesh::GetVertexCount() {
 | 
				
			||||||
 | 
				
			|||||||
@ -109,7 +109,7 @@ namespace LibCmo::VxMath {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void VxDoAlphaBlit(VxImageDescEx* dst_desc, CKBYTE* AlphaValues) {
 | 
						void VxDoAlphaBlit(VxImageDescEx* dst_desc, const CKBYTE* AlphaValues) {
 | 
				
			||||||
		if (dst_desc == nullptr) return;
 | 
							if (dst_desc == nullptr) return;
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		CKDWORD* pixels = dst_desc->GetMutablePixels();
 | 
							CKDWORD* pixels = dst_desc->GetMutablePixels();
 | 
				
			||||||
 | 
				
			|||||||
@ -81,7 +81,7 @@ namespace LibCmo::VxMath {
 | 
				
			|||||||
	 * @param AlphaValues[in] A BYTE array containing the alpha values for each pixel. This array should be allocated to Width*Height bytes.
 | 
						 * @param AlphaValues[in] A BYTE array containing the alpha values for each pixel. This array should be allocated to Width*Height bytes.
 | 
				
			||||||
	 * @remark If the destination image does not have alpha information the function returns immediatly.
 | 
						 * @remark If the destination image does not have alpha information the function returns immediatly.
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
	void VxDoAlphaBlit(VxImageDescEx* dst_desc, CKBYTE* AlphaValues);
 | 
						void VxDoAlphaBlit(VxImageDescEx* dst_desc, const CKBYTE* AlphaValues);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user