diff --git a/include/Kyoto/Alloc/CCircularBuffer.hpp b/include/Kyoto/Alloc/CCircularBuffer.hpp new file mode 100644 index 00000000..3f624c6d --- /dev/null +++ b/include/Kyoto/Alloc/CCircularBuffer.hpp @@ -0,0 +1,27 @@ +#ifndef __CCIRCULARBUFFER_HPP__ +#define __CCIRCULARBUFFER_HPP__ + + +#include + +class CCircularBuffer { +public: + enum EOwnership { + kOS_Owned, + kOS_NotOwned + }; + + CCircularBuffer(void* buf, int len, EOwnership owned = kOS_NotOwned); + bool IsWrappedMemory(int offset, int len); + void* Alloc(int len); + void Free(void* ptr, int len); + int GetAllocatedAmount() const; +private: + u8 x0_owned; + void* x4_ptr; + s32 x8_bufferLen; + s32 xc_; + s32 x10_nextFreeAddr; + s32 x14_; +}; +#endif // __CCIRCULARBUFFER_HPP__ diff --git a/obj_files.mk b/obj_files.mk index 06662f67..ce91ea1b 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -526,7 +526,7 @@ KYOTO_1 :=\ $(BUILD_DIR)/asm/Kyoto/Math/CVector3f.o\ $(BUILD_DIR)/asm/Kyoto/Math/RMathUtils.o\ $(BUILD_DIR)/src/Kyoto/CCrc32.o\ - $(BUILD_DIR)/asm/Kyoto/Alloc/CCircularBuffer.o\ + $(BUILD_DIR)/src/Kyoto/Alloc/CCircularBuffer.o\ $(BUILD_DIR)/asm/Kyoto/Alloc/CMemory.o\ $(BUILD_DIR)/src/Kyoto/Alloc/IAllocator.o\ $(BUILD_DIR)/asm/Kyoto/PVS/CPVSVisOctree.o\ diff --git a/src/Kyoto/Alloc/CCircularBuffer.cpp b/src/Kyoto/Alloc/CCircularBuffer.cpp new file mode 100644 index 00000000..76fe20cb --- /dev/null +++ b/src/Kyoto/Alloc/CCircularBuffer.cpp @@ -0,0 +1,61 @@ +#include "Kyoto/Alloc/CCircularBuffer.hpp" + +CCircularBuffer::CCircularBuffer(void* buf, int len, CCircularBuffer::EOwnership ownership) +: x0_owned(buf != NULL), x4_ptr(buf), x8_bufferLen(len), xc_(0), x10_nextFreeAddr(0), x14_(-1) { + if (ownership == kOS_NotOwned) + x0_owned = false; +} + +bool CCircularBuffer::IsWrappedMemory(int offset, int len) { + if (x14_ > -1 && x14_ >= offset && x14_ < (offset + len)) { + return true; + } + + return false; +} + +void* CCircularBuffer::Alloc(int len) { + u8* ret; + if ((x8_bufferLen - x10_nextFreeAddr) >= len && !IsWrappedMemory(x10_nextFreeAddr, len)) { + s32 offset = x10_nextFreeAddr; + u8* ptr = (u8*)x4_ptr; + x10_nextFreeAddr = offset + len; + return ptr + offset; + } else if (xc_ >= len && !IsWrappedMemory(0, len)) { + u32 r3 = xc_; + xc_ = 0; + x10_nextFreeAddr = len; + x14_ = r3; + return x4_ptr; + } + + return nullptr; +} + +void CCircularBuffer::Free(void* ptr, int len) { + if (x14_ > -1) { + if (ptr == x4_ptr) { + x14_ = -1; + xc_ = len; + } else { + x14_ += len; + } + } else { + xc_ += len; + } + + if (x14_ == -1 && xc_ == x10_nextFreeAddr) { + x10_nextFreeAddr = 0; + xc_ = 0; + } +} + +int CCircularBuffer::GetAllocatedAmount() const { + int tmp = x14_; + int res = x10_nextFreeAddr - xc_; + if (tmp != -1) { + res += x8_bufferLen - tmp; + } + + return res; +}