mirror of
https://github.com/zeldaret/botw
synced 2026-07-27 06:45:02 -04:00
ksys/gdt: Start adding GameDataMgr
This commit is contained in:
@@ -1,7 +1,130 @@
|
||||
#include "KingSystem/GameData/gdtManager.h"
|
||||
#include <devenv/seadEnvUtil.h>
|
||||
#include <framework/seadFramework.h>
|
||||
#include <thread/seadThreadUtil.h>
|
||||
#include <time/seadTickTime.h>
|
||||
#include "KingSystem/GameData/gdtSaveMgr.h"
|
||||
#include "KingSystem/GameData/gdtTriggerParam.h"
|
||||
#include "KingSystem/Resource/resEntryFactory.h"
|
||||
#include "KingSystem/Resource/resResourceGameData.h"
|
||||
#include "KingSystem/Resource/resSystem.h"
|
||||
#include "KingSystem/Utils/HeapUtil.h"
|
||||
#include "KingSystem/Utils/InitTimeInfo.h"
|
||||
|
||||
namespace ksys::gdt {
|
||||
|
||||
SEAD_SINGLETON_DISPOSER_IMPL(Manager)
|
||||
|
||||
static util::InitTimeInfoEx sInitTimeInfo;
|
||||
|
||||
Manager::Manager() {
|
||||
mRetryBuffer = nullptr;
|
||||
mGimmickResetBuffer = nullptr;
|
||||
mFlagBuffer1 = nullptr;
|
||||
mFlagBuffer = nullptr;
|
||||
}
|
||||
|
||||
Manager::~Manager() {
|
||||
mShopGameDataInfoHandle.requestUnload();
|
||||
|
||||
if (mGameDataHeap) {
|
||||
if (mFlagBuffer1) {
|
||||
mFlagBuffer1->destroyHeap();
|
||||
mFlagBuffer1 = nullptr;
|
||||
}
|
||||
|
||||
if (mFlagBuffer) {
|
||||
mFlagBuffer->destroyHeap();
|
||||
mFlagBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (mRetryBuffer) {
|
||||
mRetryBuffer->destroyHeap();
|
||||
mRetryBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (mGimmickResetBuffer) {
|
||||
mGimmickResetBuffer->destroyHeap();
|
||||
mGimmickResetBuffer = nullptr;
|
||||
}
|
||||
|
||||
if (mSaveAreaHeap) {
|
||||
mSaveAreaHeap->destroy();
|
||||
mSaveAreaHeap = nullptr;
|
||||
}
|
||||
|
||||
mGameDataHeap->destroy();
|
||||
mGameDataHeap = nullptr;
|
||||
}
|
||||
|
||||
if (mGameDataComHeap) {
|
||||
mGameDataComHeap->destroy();
|
||||
mGameDataComHeap = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// NON_MATCHING: address differences for the static bgdata_factory that causes different regalloc
|
||||
void Manager::init(sead::Heap* heap, sead::Framework* framework) {
|
||||
sead::TickTime a;
|
||||
sead::TickTime b;
|
||||
|
||||
mGameDataHeap = util::DualHeap::create(0xf00000, "GameDataHeap", heap, nullptr, sizeof(void*),
|
||||
sead::Heap::cHeapDirection_Forward, true);
|
||||
mIncrementLogger = new (mGameDataHeap) IncrementLogger;
|
||||
SaveMgr::createInstance(mGameDataHeap);
|
||||
|
||||
SaveMgr::InitArg arg;
|
||||
arg.heap = mGameDataHeap;
|
||||
arg._8 = 0x300000;
|
||||
arg.buf_size = 0x100000;
|
||||
arg.buf_alignment = 0x200;
|
||||
arg.size2 = 0x10000;
|
||||
arg.thread_priority = sead::ThreadUtil::ConvertPrioritySeadToPlatform(18);
|
||||
arg.thread_affinity = sead::CoreIdMask(sead::CoreId::cSub1);
|
||||
arg._1c = 0x7000;
|
||||
arg.is_demo = sead::EnvUtil::getRomType() == "Show_2017_1st";
|
||||
if (sead::EnvUtil::getRomType() == "RID_Demo") {
|
||||
arg.is_demo = true;
|
||||
arg.save_rid_demo_dir = "Save/RID_Demo/";
|
||||
}
|
||||
|
||||
arg._60 = nullptr;
|
||||
if (util::getDebugHeap2())
|
||||
arg._68 = 0x80000;
|
||||
|
||||
SaveMgr::instance()->init(arg);
|
||||
|
||||
static res::EntryFactory<res::GameData> bgdata_factory{5.0, 0xc0000};
|
||||
res::registerEntryFactory(&bgdata_factory, "bgdata");
|
||||
|
||||
mSaveAreaHeap =
|
||||
util::DualHeap::create(0x500000, "SaveAreaHeap", mGameDataHeap, nullptr, sizeof(void*),
|
||||
sead::Heap::cHeapDirection_Reverse, false);
|
||||
|
||||
SaveMgr::instance()->loadGameSaveData();
|
||||
|
||||
KingEditor::instance()->registerComponent(this);
|
||||
|
||||
sead::FixedSafeString<1024> gamedata_sarc_path;
|
||||
gamedata_sarc_path.format("%s/%s.%s", "GameData", "gamedata", "sarc");
|
||||
loadGameData(gamedata_sarc_path);
|
||||
|
||||
sead::FixedSafeString<1024> shop_gamedata_info_path;
|
||||
shop_gamedata_info_path.format("%s/%s.byml", "GameData", "ShopGameDataInfo");
|
||||
loadShopGameDataInfo(shop_gamedata_info_path);
|
||||
|
||||
mParam.param1 = &mFlagBuffer1;
|
||||
mParam.param = &mFlagBuffer;
|
||||
mParamBypassPerm.param1 = &mFlagBuffer1;
|
||||
mParamBypassPerm.param = &mFlagBuffer;
|
||||
|
||||
mMethodTreeNode.method_tree_mgr = framework->getMethodTreeMgr();
|
||||
mMethodTreeNode.node.setPauseFlag(sead::MethodTreeNode::cPause_None);
|
||||
|
||||
mBitFlags.reset(BitFlag::_1);
|
||||
unloadResources();
|
||||
mBitFlags.set(BitFlag::_1000);
|
||||
mNumFlagsToReset = 0;
|
||||
}
|
||||
|
||||
} // namespace ksys::gdt
|
||||
|
||||
@@ -1,12 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <container/seadRingBuffer.h>
|
||||
#include <container/seadSafeArray.h>
|
||||
#include <filedevice/seadArchiveFileDevice.h>
|
||||
#include <framework/seadMethodTree.h>
|
||||
#include <heap/seadDisposer.h>
|
||||
#include <prim/seadDelegateEventSlot.h>
|
||||
#include <prim/seadTypedBitFlag.h>
|
||||
#include "KingSystem/Resource/resHandle.h"
|
||||
#include "KingSystem/System/KingEditor.h"
|
||||
#include "KingSystem/Utils/Byaml.h"
|
||||
#include "KingSystem/Utils/Types.h"
|
||||
|
||||
namespace sead {
|
||||
class Framework;
|
||||
class MethodTreeMgr;
|
||||
} // namespace sead
|
||||
|
||||
namespace ksys::gdt {
|
||||
|
||||
class TriggerParam;
|
||||
|
||||
class IManager {
|
||||
public:
|
||||
virtual ~IManager() = 0;
|
||||
@@ -15,17 +29,13 @@ public:
|
||||
inline IManager::~IManager() = default;
|
||||
|
||||
/// GameDataMgr communication.
|
||||
class ManagerCom {
|
||||
class ManagerCom : public KingEditorComponent {
|
||||
public:
|
||||
virtual const char* getName() const = 0;
|
||||
virtual void syncData() = 0;
|
||||
|
||||
void* _8 = nullptr;
|
||||
void* _10 = nullptr;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(ManagerCom, 0x18);
|
||||
|
||||
// FIXME: very incomplete. This is only here because res::GameData needs to use the Manager's heaps
|
||||
class Manager : public IManager, public ManagerCom {
|
||||
SEAD_SINGLETON_DISPOSER(Manager)
|
||||
Manager();
|
||||
@@ -34,18 +44,125 @@ class Manager : public IManager, public ManagerCom {
|
||||
void syncData() override;
|
||||
|
||||
public:
|
||||
struct ResetEvent {
|
||||
virtual ~ResetEvent() = default;
|
||||
TriggerParam* param = nullptr;
|
||||
};
|
||||
|
||||
struct ReinitEvent {
|
||||
virtual ~ReinitEvent() = default;
|
||||
};
|
||||
|
||||
struct TriggerParamRef {
|
||||
TriggerParamRef(TriggerParam** param_1, TriggerParam** param, bool check_permissions,
|
||||
bool propagate_param_1_changes, bool change_only_once)
|
||||
: param1(param_1), param(param), check_permissions(check_permissions),
|
||||
propagate_param1_changes(propagate_param_1_changes),
|
||||
change_only_once(change_only_once) {}
|
||||
|
||||
virtual ~TriggerParamRef() = default;
|
||||
|
||||
TriggerParam** param1;
|
||||
TriggerParam** param;
|
||||
bool check_permissions;
|
||||
bool propagate_param1_changes;
|
||||
bool change_only_once;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(TriggerParamRef, 0x20);
|
||||
|
||||
sead::Heap* getGameDataHeap() const { return mGameDataHeap; }
|
||||
sead::Heap* getSaveAreaHeap() const { return mSaveAreaHeap; }
|
||||
sead::Heap* getGameDataComHeap() const { return mGameDataComHeap; }
|
||||
|
||||
void init(sead::Heap* heap, sead::Framework* framework);
|
||||
|
||||
private:
|
||||
enum class BitFlag {
|
||||
_1 = 0x1,
|
||||
_2 = 0x2,
|
||||
_4 = 0x4,
|
||||
_8 = 0x8,
|
||||
_10 = 0x10,
|
||||
_20 = 0x20,
|
||||
_40 = 0x40,
|
||||
_80 = 0x80,
|
||||
_100 = 0x100,
|
||||
_200 = 0x200,
|
||||
_400 = 0x400,
|
||||
_800 = 0x800,
|
||||
_1000 = 0x1000,
|
||||
};
|
||||
|
||||
enum class ResetFlag {
|
||||
|
||||
};
|
||||
|
||||
struct MethodTreeNode {
|
||||
virtual ~MethodTreeNode() = default;
|
||||
sead::MethodTreeNode node{nullptr};
|
||||
sead::MethodTreeMgr* method_tree_mgr = nullptr;
|
||||
};
|
||||
|
||||
struct IncrementLogger {
|
||||
struct Record {
|
||||
u8 _0 = 0;
|
||||
u32 _4 = 0;
|
||||
s32 _8 = -1;
|
||||
u32 _c = 0;
|
||||
};
|
||||
KSYS_CHECK_SIZE_NX150(Record, 0x10);
|
||||
|
||||
u64 _0 = 0;
|
||||
sead::FixedRingBuffer<Record, 64> ring_buffers[6]{};
|
||||
sead::SafeArray<Record, 0xc0> arrays[2]{};
|
||||
};
|
||||
|
||||
void loadGameData(const sead::SafeString& path);
|
||||
void loadShopGameDataInfo(const sead::SafeString& path);
|
||||
void unloadResources();
|
||||
|
||||
sead::Heap* mGameDataHeap = nullptr;
|
||||
sead::Heap* mSaveAreaHeap = nullptr;
|
||||
sead::Heap* mGameDataComHeap = nullptr;
|
||||
res::Handle mGameDataArcHandle;
|
||||
sead::SafeArray<res::Handle, 31> mBgdataHandles;
|
||||
sead::SafeArray<res::Handle, 32> mBgdataHandles;
|
||||
sead::ArchiveFileDevice mGameDataArc{nullptr};
|
||||
|
||||
res::Handle mShopGameDataInfoHandle;
|
||||
al::ByamlIter mShopAreaInfoValues;
|
||||
const u8* mShopAreaInfoHashes = nullptr;
|
||||
al::ByamlIter mShopSoldOutInfoValues;
|
||||
const u8* mShopSoldOutInfoHashes = nullptr;
|
||||
|
||||
TriggerParamRef mParamBypassPerm{&mFlagBuffer1, &mFlagBuffer, false, false, false};
|
||||
TriggerParamRef mParam{&mFlagBuffer1, &mFlagBuffer, true, false, false};
|
||||
|
||||
IncrementLogger* mIncrementLogger = nullptr;
|
||||
|
||||
TriggerParam* mFlagBuffer1;
|
||||
TriggerParam* mFlagBuffer;
|
||||
TriggerParam* mRetryBuffer;
|
||||
TriggerParam* mGimmickResetBuffer;
|
||||
|
||||
sead::TypedBitFlag<BitFlag> mBitFlags;
|
||||
sead::TypedBitFlag<ResetFlag> mResetFlags;
|
||||
u32 _c20 = 0;
|
||||
u32 mNumFlagsToReset = 0;
|
||||
u32 mParam1Flag = 0;
|
||||
|
||||
sead::DelegateEvent<ReinitEvent*> mReinitEvent;
|
||||
sead::DelegateEvent<ResetEvent*> mResetEvent;
|
||||
|
||||
MethodTreeNode mMethodTreeNode;
|
||||
|
||||
void* mDelegate1 = nullptr; // FIXME: figure out what this is
|
||||
sead::IDelegateR<const sead::SafeString&>* mGetMapNameDelegate = nullptr;
|
||||
|
||||
sead::FixedSafeString<64> mStr; // TODO: rename
|
||||
u32 mTrackerBlockSaveNumberFlagCrc32 = 0;
|
||||
u32 mSyncStep = 0;
|
||||
sead::CriticalSection mCriticalSection;
|
||||
};
|
||||
// FIXME: the size should be 0xDC8
|
||||
KSYS_CHECK_SIZE_NX150(Manager, 0xa58);
|
||||
KSYS_CHECK_SIZE_NX150(Manager, 0xdc8);
|
||||
|
||||
} // namespace ksys::gdt
|
||||
|
||||
Reference in New Issue
Block a user