diff --git a/include/Kyoto/Alloc/CMediumAllocPool.hpp b/include/Kyoto/Alloc/CMediumAllocPool.hpp index 54037f97..21411f65 100644 --- a/include/Kyoto/Alloc/CMediumAllocPool.hpp +++ b/include/Kyoto/Alloc/CMediumAllocPool.hpp @@ -9,15 +9,15 @@ struct SMediumAllocPuddle { ~SMediumAllocPuddle(); void* FindFree(uint blockCount); void* FindFreeEntry(uint blockCount); - bool Free(const void* ptr); + void Free(const void* ptr); - uint GetUnkx10() const { return x10_; } - uint GetNumBlocks() const { return x14_numBlocks; } - uint GetNumAllocs() const { return x18_numAllocs; } - uint GetNumEntries() const { return x1c_numEntries; } - bool GetUnk2() const { return x20_unk2; } - - static uint GetBlockOffset(const void* ptrA, const void* ptrB); + const uint GetUnkx10() const { return x10_; } + const uint GetNumBlocks() const { return x14_numBlocks; } + const uint GetNumAllocs() const { return x18_numAllocs; } + const uint GetNumEntries() const { return x1c_numEntries; } + const bool GetUnk2() const { return x20_unk2; } + const uint GetPtrOffset(const void* ptr) const { return (uchar*)ptr - x0_mainData.get(); } + static ushort GetBlockOffset(const void* ptrA, const void* ptrB); static void InitBookKeeping(uchar* bookKeepingPtr, const ushort blockCount); private: @@ -38,7 +38,7 @@ public: CMediumAllocPool(); void* Alloc(uint size); bool HasPuddles() const; - void AddPuddle(uint, void*, bool); + void AddPuddle(const uint, void*, const bool); void ClearPuddles(); int Free(const void* ptr); diff --git a/include/rstl/list.hpp b/include/rstl/list.hpp index 6ce0c716..643aa0d1 100644 --- a/include/rstl/list.hpp +++ b/include/rstl/list.hpp @@ -12,7 +12,7 @@ class list { public: class iterator; class const_iterator; - iterator erase(const iterator& item); + iterator erase(const iterator& item) { return do_erase(item.get_node()); } private: struct node; @@ -33,9 +33,7 @@ public: size_t size() const { return x14_count; } bool empty() const { return x14_count == 0; } - void pop_front() { - erase(x4_start); - } + void pop_front() { erase(x4_start); } iterator begin() { return iterator(x4_start); } const_iterator begin() const { return const_iterator(x4_start); } @@ -45,15 +43,15 @@ public: iterator erase(const iterator& start, const iterator& end) { node* last = end.get_node(); node* it = start.get_node(); - for(node* t = it; t != last; t = t->get_next()) { + for (node* t = it; t != last; t = t->get_next()) { } - + while (it != last) { it = do_erase(it); } return iterator(it); } - + struct node { node* x0_prev; node* x4_next; @@ -72,7 +70,7 @@ public: node* create_node(node* prev, node* next, const T& val) { node* n; x0_allocator.allocate(n, 1); - new(n) node(prev, next); + new (n) node(prev, next); construct(n->get_value(), val); return n; } @@ -166,7 +164,6 @@ list< T, Alloc >::~list() { } } - template < typename T, typename Alloc > typename list< T, Alloc >::node* list< T, Alloc >::do_erase(node* node) { typename list< T, Alloc >::node* result = node->get_next(); diff --git a/src/Kyoto/Alloc/CMediumAllocPool.cpp b/src/Kyoto/Alloc/CMediumAllocPool.cpp index edaffe29..71995421 100644 --- a/src/Kyoto/Alloc/CMediumAllocPool.cpp +++ b/src/Kyoto/Alloc/CMediumAllocPool.cpp @@ -43,7 +43,25 @@ void* CMediumAllocPool::Alloc(uint len) { return ret; } -int CMediumAllocPool::Free(const void* ptr) {} +int CMediumAllocPool::Free(const void* ptr) { + rstl::list::node* node = x0_list.begin().get_node(); + for (; node != x0_list.end().get_node(); node = node->get_next()) { + SMediumAllocPuddle* puddle = node->get_value(); + if (puddle->GetPtrOffset(ptr) < puddle->GetNumEntries() * 32) { + puddle->Free(ptr); + if (node->get_value()->GetNumAllocs() == 0 && node->get_value()->GetUnk2()) { + if (x18_lastNodePrev == node ) { + x18_lastNodePrev = x0_list.begin().get_node(); + } + + x0_list.erase(node); + } + + return 2; + } + } + return 1; +} uint CMediumAllocPool::GetNumAllocs() { uint ret = 0; @@ -72,7 +90,7 @@ uint CMediumAllocPool::GetNumBlocksAvailable() { } /* this is such a hack... */ -#pragma inline_max_size(250) +#pragma inline_max_size(325) void CMediumAllocPool::AddPuddle(uint len, void* data, const bool unk) { x0_list.push_back(SMediumAllocPuddle(len, data, unk)); x18_lastNodePrev = x0_list.end().get_node(); @@ -115,9 +133,17 @@ void* SMediumAllocPuddle::FindFree(uint blockCount) { void* SMediumAllocPuddle::FindFreeEntry(uint numBlocks) { return nullptr; } -bool SMediumAllocPuddle::Free(const void* ptr) {} +void SMediumAllocPuddle::Free(const void* ptr) {} -uint SMediumAllocPuddle::GetBlockOffset(const void* ptrA, const void* ptrB) { return 0; } +ushort SMediumAllocPuddle::GetBlockOffset(const void* ptr1, const void* ptr2) { + unsigned char tmp = (uchar*)ptr2 - (uchar*)ptr1 > 1 ? ((uchar*)ptr1)[1] : 0; + + ushort x = tmp + (*(uchar*)(ptr1) & 0x7f) * 0x100; + if ((x & 0x6000) == 0) { + return x; + } + return (x & 0x6000u) == 0x6000u ? 3 : (((x & 0x6000u) != 0x4000) ? 0 : 1) + 1; +} void SMediumAllocPuddle::InitBookKeeping(uchar* bookKeepingPtr, ushort blockCount) { if (blockCount < 4) {