summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2020-11-07 19:05:43 +0100
committerLéo Lam <leo@leolam.fr>2020-11-07 23:28:09 +0100
commit3f11fdb6d20e2a52581e3f2d829516efe803eb73 (patch)
treece0d2bbb2d4e1d9f1501b9706465b74e734806c2 /src
parentbfa4a2553e188dafba168dd9815b8b773f6a1d96 (diff)
ksys/gdt: Add flag setters (by handle and by name)
Diffstat (limited to 'src')
-rw-r--r--src/KingSystem/GameData/gdtManager.h120
1 files changed, 92 insertions, 28 deletions
diff --git a/src/KingSystem/GameData/gdtManager.h b/src/KingSystem/GameData/gdtManager.h
index eb9098f2..4637c260 100644
--- a/src/KingSystem/GameData/gdtManager.h
+++ b/src/KingSystem/GameData/gdtManager.h
@@ -36,6 +36,8 @@ public:
class Proxy {
public:
TriggerParam* getBuffer() const { return mUseParam1 ? *mRef.mParam1 : *mRef.mParam; }
+ TriggerParam* getBuffer0() const { return *mRef.mParam; }
+ TriggerParam* getBuffer1() const { return *mRef.mParam1; }
// region Value getters
@@ -56,29 +58,47 @@ public:
bool SET_NAME(TYPE const& value, s32 idx, bool bypass_one_trigger_check = false) { \
if (mRef.mChangeOnlyOne) \
return false; \
- return getBuffer()->SET_NAME(value, idx, mRef.mCheckPermissions, \
- bypass_one_trigger_check); \
+ if (!getBuffer1()->SET_NAME(value, idx, mRef.mCheckPermissions, bypass_one_trigger_check)) \
+ return false; \
+ if (mRef.mPropagateParam1Changes) \
+ getBuffer0()->SET_NAME(value, idx, mRef.mCheckPermissions, bypass_one_trigger_check); \
+ return true; \
} \
bool SET_NAME(TYPE const& value, s32 array_idx, s32 idx, \
bool bypass_one_trigger_check = false) { \
if (mRef.mChangeOnlyOne) \
return false; \
- return getBuffer()->SET_NAME(value, array_idx, idx, mRef.mCheckPermissions, \
- bypass_one_trigger_check); \
+ if (!getBuffer1()->SET_NAME(value, array_idx, idx, mRef.mCheckPermissions, \
+ bypass_one_trigger_check)) \
+ return false; \
+ if (mRef.mPropagateParam1Changes) \
+ getBuffer0()->SET_NAME(value, array_idx, idx, mRef.mCheckPermissions, \
+ bypass_one_trigger_check); \
+ return true; \
} \
bool SET_NAME(TYPE const& value, const sead::SafeString& name, \
bool bypass_one_trigger_check = false) { \
if (mRef.mChangeOnlyOne) \
return false; \
- return getBuffer()->SET_NAME(value, name, mRef.mCheckPermissions, true, \
- bypass_one_trigger_check); \
+ if (!getBuffer1()->SET_NAME(value, name, mRef.mCheckPermissions, true, \
+ bypass_one_trigger_check)) \
+ return false; \
+ if (mRef.mPropagateParam1Changes) \
+ getBuffer0()->SET_NAME(value, name, mRef.mCheckPermissions, true, \
+ bypass_one_trigger_check); \
+ return true; \
} \
bool SET_NAME(TYPE const& value, const sead::SafeString& name, s32 idx, \
bool bypass_one_trigger_check = false) { \
if (mRef.mChangeOnlyOne) \
return false; \
- return getBuffer()->SET_NAME(value, name, idx, mRef.mCheckPermissions, true, \
- bypass_one_trigger_check); \
+ if (!getBuffer1()->SET_NAME(value, name, idx, mRef.mCheckPermissions, true, \
+ bypass_one_trigger_check)) \
+ return false; \
+ if (mRef.mPropagateParam1Changes) \
+ getBuffer0()->SET_NAME(value, name, idx, mRef.mCheckPermissions, true, \
+ bypass_one_trigger_check); \
+ return true; \
}
PROXY_GET_SET_IMPL_(getBool, setBool, bool)
@@ -199,8 +219,10 @@ public:
#define GDT_GET_(NAME, T) \
void NAME(FlagHandle handle, T* value, bool debug = false) { \
- unwrapHandle(handle, debug, \
- [&](u32 idx, TriggerParamRef& ref) { ref.get().NAME(value, idx); }); \
+ unwrapHandle<false>(handle, debug, [&](u32 idx, TriggerParamRef& ref) { \
+ ref.get().NAME(value, idx); \
+ return true; \
+ }); \
}
GDT_GET_(getBool, bool)
@@ -215,6 +237,48 @@ public:
#undef GDT_GET_
+#define GDT_SET_(NAME, T) \
+ KSYS_ALWAYS_INLINE bool NAME(T value, FlagHandle handle, bool debug, bool force) { \
+ if (mBitFlags.isOn(BitFlag::_40000)) \
+ return false; \
+ return unwrapHandle<true>(handle, debug, [&](u32 idx, TriggerParamRef& ref) { \
+ return ref.get().NAME(value, idx, force); \
+ }); \
+ } \
+ bool NAME(T value, FlagHandle handle) { return NAME(value, handle, false, false); } \
+ bool NAME##NoCheck(T value, FlagHandle handle) { return NAME(value, handle, true, false); } \
+ bool NAME##NoCheckForce(T value, FlagHandle handle) { \
+ return NAME(value, handle, true, true); \
+ } \
+ \
+ KSYS_ALWAYS_INLINE bool NAME(T value, const sead::SafeString& name, bool debug, bool force) { \
+ if (mBitFlags.isOn(BitFlag::_40000)) \
+ return false; \
+ auto& ref = debug ? getParamBypassPerm() : getParam(); \
+ return ref.get().NAME(value, name, force); \
+ } \
+ [[gnu::noinline]] bool NAME(T value, const sead::SafeString& name) { \
+ return NAME(value, name, false, false); \
+ } \
+ [[gnu::noinline]] bool NAME##NoCheck(T value, const sead::SafeString& name) { \
+ return NAME(value, name, true, false); \
+ } \
+ [[gnu::noinline]] bool NAME##NoCheckForce(T value, const sead::SafeString& name) { \
+ return NAME(value, name, true, true); \
+ }
+
+ GDT_SET_(setBool, bool)
+ GDT_SET_(setS32, s32)
+ GDT_SET_(setF32, f32)
+ GDT_SET_(setStr, char const*)
+ GDT_SET_(setStr64, char const*)
+ GDT_SET_(setStr256, char const*)
+ GDT_SET_(setVec2f, const sead::Vector2f&)
+ GDT_SET_(setVec3f, const sead::Vector3f&)
+ GDT_SET_(setVec4f, const sead::Vector4f&)
+
+#undef GDT_SET_
+
void init(sead::Heap* heap, sead::Framework* framework);
void addReinitCallback(ReinitSignal::Slot& slot);
@@ -237,6 +301,9 @@ private:
_2000 = 0x2000,
_4000 = 0x4000,
_8000 = 0x8000,
+ _10000 = 0x10000,
+ _20000 = 0x20000,
+ _40000 = 0x40000,
};
enum class ResetFlag {
@@ -268,28 +335,25 @@ private:
}
/// Extracts a flag index out of a FlagHandle and passes it to the specified callable.
- /// fn must be callable with a u32
- template <typename Fn>
- void unwrapHandle(FlagHandle handle, const Fn& fn) {
- u32 idx = static_cast<u32>(handle);
- bool is_valid_idx = mBitFlags.isOff(BitFlag::_8000);
- is_valid_idx &= handle != InvalidHandle;
- if (!is_valid_idx) {
- if (idx >> 24 != mCurrentFlagHandlePrefix)
- return;
- idx &= 0xFFFFFF;
- }
- fn(idx);
+ /// fn must be callable with a u32 + TriggerParamRef&
+ template <bool Write, bool BypassPerm, typename Fn>
+ KSYS_ALWAYS_INLINE bool unwrapHandle(FlagHandle handle, const Fn& fn) {
+ const u32 idx = static_cast<u32>(handle);
+ auto& ref = BypassPerm ? getParamBypassPerm() : getParam();
+ const auto check = [&] { return !Write || !ref.shouldChangeOnlyOne(); };
+
+ if (mBitFlags.isOff(BitFlag::_8000) && handle != InvalidHandle)
+ return check() && fn(idx, ref);
+
+ return idx >> 24 == mCurrentFlagHandlePrefix && check() && fn(idx & 0xFFFFFF, ref);
}
/// Extracts a flag index out of a FlagHandle and passes it to the specified callable.
/// fn must be callable with a u32 + TriggerParamRef&
- template <typename Fn>
- void unwrapHandle(FlagHandle handle, bool debug, const Fn& fn) {
- if (debug)
- unwrapHandle(handle, [&](u32 idx) { fn(idx, getParamBypassPerm()); });
- else
- unwrapHandle(handle, [&](u32 idx) { fn(idx, getParam()); });
+ template <bool Write, typename Fn>
+ KSYS_ALWAYS_INLINE bool unwrapHandle(FlagHandle handle, bool debug, const Fn& fn) {
+ return debug ? unwrapHandle<Write, true>(handle, fn) :
+ unwrapHandle<Write, false>(handle, fn);
}
void loadGameData(const sead::SafeString& path);