mirror of
https://github.com/zeldaret/botw
synced 2026-05-25 07:22:56 -04:00
174 lines
4.4 KiB
C++
174 lines
4.4 KiB
C++
#include "KingSystem/System/OverlayArena.h"
|
|
#include <heap/seadExpHeap.h>
|
|
#include "KingSystem/Resource/resResourceMgrTask.h"
|
|
#include "KingSystem/Resource/resSystem.h"
|
|
#include "KingSystem/Resource/resUnit.h"
|
|
#include "KingSystem/Utils/HeapUtil.h"
|
|
|
|
namespace ksys {
|
|
|
|
OverlayArena::OverlayArena() {
|
|
mUnits.initOffset(res::ResourceUnit::getArenaUnitListNodeOffset());
|
|
mUnits2.initOffset(res::ResourceUnit::getArenaUnitListNode2Offset());
|
|
}
|
|
|
|
OverlayArena::~OverlayArena() {
|
|
destroy();
|
|
}
|
|
|
|
// branching at the end (csel instead of a branch)
|
|
#ifdef NON_MATCHING
|
|
bool OverlayArena::init(const OverlayArena::InitArg& arg) {
|
|
if (!arg.heap) {
|
|
res::stubbedLogFunction();
|
|
return false;
|
|
}
|
|
|
|
if (arg.size == 0)
|
|
res::stubbedLogFunction();
|
|
|
|
mFlags.change(Flag::_1, arg.set_flag_1);
|
|
|
|
mHeap = sead::ExpHeap::create(arg.size, arg.name, arg.heap, arg.alignment,
|
|
sead::Heap::cHeapDirection_Forward, true);
|
|
|
|
if (arg.use_best_fit_alloc_mode)
|
|
mHeap->setAllocMode(sead::ExpHeap::AllocMode::BestFit);
|
|
|
|
mHeapSize = mHeap->getSize();
|
|
_cc = 0;
|
|
mHeapFreeSize = mHeap->getFreeSize();
|
|
mHeapName = mHeap->getName();
|
|
mUsagePercentage = 0.0;
|
|
_c8 = 0;
|
|
mMinFreePercentage = arg.min_free_percentage;
|
|
|
|
if (res::ResourceMgrTask::instance())
|
|
res::ResourceMgrTask::instance()->insertOverlayArena(this);
|
|
|
|
mFlags.change(Flag::_20, arg.set_flag_20);
|
|
mFlags.change(Flag::_10, arg.set_flag_10);
|
|
|
|
struct UnusedTemp {
|
|
sead::SafeString str;
|
|
void* _10 = nullptr;
|
|
};
|
|
[[maybe_unused]] UnusedTemp temp;
|
|
temp.str = arg.name;
|
|
|
|
mFlags.change(Flag::_8, arg.set_flag_8);
|
|
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
void OverlayArena::stubbed() {}
|
|
|
|
void OverlayArena::updateFlag8(bool on) {
|
|
if (on != mFlags.isOn(Flag::_8) && mHeap)
|
|
mFlags.change(Flag::_8, on);
|
|
}
|
|
|
|
void OverlayArena::clearUnits() {
|
|
if (!mHeap)
|
|
return;
|
|
|
|
res::stubbedLogFunction();
|
|
auto lock = sead::makeScopedLock(mCS);
|
|
for (auto it = mUnits.robustBegin(), end = mUnits.robustEnd(); it != end; ++it) {
|
|
res::ResourceUnit* unit = std::addressof(*it);
|
|
res::stubbedLogFunction();
|
|
res::ResourceMgrTask::instance()->deregisterUnit(unit);
|
|
res::ResourceMgrTask::instance()->requestClearCacheForSync(&unit, true, false);
|
|
}
|
|
res::stubbedLogFunction();
|
|
}
|
|
|
|
bool OverlayArena::isFlag1Set() const {
|
|
return mFlags.isOn(Flag::_1);
|
|
}
|
|
|
|
bool OverlayArena::hasNoUnits() const {
|
|
return mUnits.isEmpty();
|
|
}
|
|
|
|
s32 OverlayArena::getNumUnits() const {
|
|
return mUnits.size();
|
|
}
|
|
|
|
bool OverlayArena::isFlag10Set() const {
|
|
return mFlags.isOn(Flag::_10);
|
|
}
|
|
|
|
bool OverlayArena::isFlag8Set() const {
|
|
return mFlags.isOn(Flag::_8);
|
|
}
|
|
|
|
bool OverlayArena::checkIsOom() const {
|
|
if (!mHeap)
|
|
return false;
|
|
|
|
const f32 used_size = mUsage1 + mUsage2;
|
|
const size_t heap_size = mHeap->getSize();
|
|
const f32 free_percentage =
|
|
100.0f *
|
|
std::max<f32>(1.0 - used_size / (heap_size - sead::ExpHeap::getManagementAreaSize(8)), 0);
|
|
|
|
if (free_percentage < mMinFreePercentage) {
|
|
if (res::returnFalse())
|
|
res::stubbedLogFunction();
|
|
|
|
setBloodyMoonReasonForOom_();
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// FIXME: figure out what sead function this is
|
|
bool seadCheckPointer(void* ptr);
|
|
|
|
// branching
|
|
#ifdef NON_MATCHING
|
|
util::DualHeap* OverlayArena::makeDualHeap(u32 size, const sead::SafeString& name,
|
|
sead::Heap::HeapDirection direction,
|
|
res::ResourceUnit* unit, bool) {
|
|
if (!mHeap)
|
|
return nullptr;
|
|
|
|
const auto alignment = res::getDefaultAlignment();
|
|
const auto lock = sead::makeScopedLock(mCS);
|
|
|
|
auto* heap = util::DualHeap::tryCreate(size, name, mHeap, mHeap2, alignment, direction, false);
|
|
if (!heap) {
|
|
if (res::returnFalse())
|
|
res::stubbedLogFunction();
|
|
|
|
if (!x_1(size))
|
|
return nullptr;
|
|
|
|
heap = util::DualHeap::tryCreate(size, name, mHeap, mHeap2, alignment, direction, false);
|
|
if (!heap)
|
|
return nullptr;
|
|
}
|
|
|
|
if (unit && !seadCheckPointer(unit)) {
|
|
mUnits.pushBack(unit);
|
|
mFlags.set(Flag::_2);
|
|
}
|
|
|
|
mFlags.set(Flag::_4);
|
|
return heap;
|
|
}
|
|
#endif
|
|
|
|
void OverlayArena::addSize(s32 size) {
|
|
mSize += size;
|
|
}
|
|
|
|
void OverlayArena::addSize2(s32 size) {
|
|
mUsage1 += size;
|
|
}
|
|
|
|
} // namespace ksys
|