mirror of https://github.com/AxioDL/metaforce.git
63 lines
2.1 KiB
C++
63 lines
2.1 KiB
C++
|
#pragma once
|
||
|
#include "GCNTypes.hpp"
|
||
|
|
||
|
namespace metaforce {
|
||
|
class CSmallAllocPool {
|
||
|
void* x0_mainData;
|
||
|
void* x4_bookKeeping;
|
||
|
uint32_t x8_numBlocks;
|
||
|
void* xc_cachedBookKeepingOffset = nullptr;
|
||
|
int32_t x10_ = -1;
|
||
|
uint32_t x14_ = -1;
|
||
|
uint32_t x18_numBlocksAvailable = 0;
|
||
|
uint32_t x1c_numAllocs = 0;
|
||
|
|
||
|
[[nodiscard]] void* FindFree(uint32_t len);
|
||
|
public:
|
||
|
CSmallAllocPool(uint32_t len, void* mainData, void* bookKeeping);
|
||
|
|
||
|
[[nodiscard]] void* Alloc(uint32_t size);
|
||
|
[[nodiscard]] bool Free(void* buf);
|
||
|
|
||
|
[[nodiscard]] uint32_t GetNumUsedBlocks() const {
|
||
|
uint32_t usedBlocks = 0;
|
||
|
for (uint32_t i = 0; i < x8_numBlocks / 2;) {
|
||
|
uint8_t p = static_cast<uint8_t*>(x4_bookKeeping)[i];
|
||
|
// Don't check the header directly, make sure we extract the block count, as it's actually possible to allocate a
|
||
|
// 0 block buffer, Retro worked around this in retail by not allowing CGameAllocator to allocate buffers >= 0x39
|
||
|
// bytes
|
||
|
if (((p >> 4) & 0xf) != 0) {
|
||
|
uint32_t numBlocks = (p >> 4) & 0xf;
|
||
|
usedBlocks += numBlocks;
|
||
|
// skip over blocks used by this allocation
|
||
|
i += numBlocks / 2;
|
||
|
} else {
|
||
|
++i;
|
||
|
}
|
||
|
}
|
||
|
return usedBlocks;
|
||
|
}
|
||
|
|
||
|
[[nodiscard]] uint32_t GetNumUnusedBlocks() const {
|
||
|
uint32_t unusedBlocks = 0;
|
||
|
for (uint32_t i = 0; i < x8_numBlocks / 2;) {
|
||
|
uint8_t p = static_cast<uint8_t*>(x4_bookKeeping)[i];
|
||
|
// Don't check the header directly, make sure we extract the block count, as it's actually possible to allocate a
|
||
|
// 0 block buffer, Retro worked around this in retail by not allowing CGameAllocator to allocate buffers >= 0x39
|
||
|
// bytes
|
||
|
if (((p >> 4) & 0xf) != 0) {
|
||
|
// skip over blocks used by this allocation
|
||
|
i += ((p >> 4) & 0xf) / 2;
|
||
|
} else {
|
||
|
++i;
|
||
|
unusedBlocks += 2;
|
||
|
}
|
||
|
}
|
||
|
return unusedBlocks;
|
||
|
}
|
||
|
|
||
|
[[nodiscard]] u32 GetNumBlocksAvailable() const { return x18_numBlocksAvailable; }
|
||
|
[[nodiscard]] u32 GetTotalEntries() const { return x8_numBlocks - x18_numBlocksAvailable; }
|
||
|
[[nodiscard]] u32 GetNumAllocs() const { return x1c_numAllocs; }
|
||
|
};
|
||
|
} // namespace metaforce
|