summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLéo Lam <leo@leolam.fr>2021-12-16 19:43:07 +0100
committerLéo Lam <leo@leolam.fr>2021-12-18 12:28:20 +0100
commit03993b26fe2a695285a61a7e54f84eabba0b8317 (patch)
tree85d7b578ac62259f3633294340890dd9cb4d959f /lib
parent406a5c06d142ca1ff1465ae6c9173859f4e002ee (diff)
Havok: Add MemoryRouter, TLS and base object classes
Diffstat (limited to 'lib')
-rw-r--r--lib/hkStubs/CMakeLists.txt18
-rw-r--r--lib/hkStubs/Havok/Common/Base/Memory/Allocator/Lifo/hkLifoAllocator.h57
-rw-r--r--lib/hkStubs/Havok/Common/Base/Memory/Allocator/hkMemoryAllocator.h102
-rw-r--r--lib/hkStubs/Havok/Common/Base/Memory/Router/hkMemoryRouter.h98
-rw-r--r--lib/hkStubs/Havok/Common/Base/Object/hkBaseObject.h3
-rw-r--r--lib/hkStubs/Havok/Common/Base/Object/hkReferencedObject.cpp9
-rw-r--r--lib/hkStubs/Havok/Common/Base/Object/hkReferencedObject.h90
-rw-r--r--lib/hkStubs/Havok/Common/Base/Thread/Atomic/hkAtomicPrimitives.h25
-rw-r--r--lib/hkStubs/Havok/Common/Base/Thread/Thread/hkThreadLocalData.h20
-rw-r--r--lib/hkStubs/Havok/Common/Base/Types/hkBaseTypes.h56
-rw-r--r--lib/hkStubs/Havok/Common/Base/hkBase.h2
m---------lib/sead0
12 files changed, 470 insertions, 10 deletions
diff --git a/lib/hkStubs/CMakeLists.txt b/lib/hkStubs/CMakeLists.txt
index cb26f6a7..3ec0a122 100644
--- a/lib/hkStubs/CMakeLists.txt
+++ b/lib/hkStubs/CMakeLists.txt
@@ -2,11 +2,23 @@ project(hkStubs CXX ASM)
add_library(hkStubs OBJECT
Havok/Common/Base/hkBase.h
+
Havok/Common/Base/Container/String/hkStringPtr.h
+
Havok/Common/Base/Math/hkMath.h
Havok/Common/Base/Math/Vector/hkVector4.h
+
+ Havok/Common/Base/Memory/Allocator/hkMemoryAllocator.h
+ Havok/Common/Base/Memory/Allocator/Lifo/hkLifoAllocator.h
+ Havok/Common/Base/Memory/Router/hkMemoryRouter.h
+
Havok/Common/Base/Object/hkBaseObject.h
+ Havok/Common/Base/Object/hkReferencedObject.cpp
Havok/Common/Base/Object/hkReferencedObject.h
+
+ Havok/Common/Base/Thread/Atomic/hkAtomicPrimitives.h
+ Havok/Common/Base/Thread/Thread/hkThreadLocalData.h
+
Havok/Common/Base/Types/hkBaseDefs.h
Havok/Common/Base/Types/hkBaseTypes.h
@@ -14,6 +26,7 @@ add_library(hkStubs OBJECT
Havok/Physics/Collide/Shape/Convex/hkpConvexShape.h
Havok/Physics/Collide/Shape/Convex/Capsule/hkpCapsuleShape.h
Havok/Physics/Collide/Shape/HeightField/hkpSphereRepShape.h
+
Havok/Physics/Dynamics/Entity/hkpEntity.h
Havok/Physics/Dynamics/Entity/hkpRigidBody.h
Havok/Physics/Dynamics/World/hkpWorld.cpp
@@ -25,3 +38,8 @@ target_compile_options(hkStubs PRIVATE -fno-exceptions)
target_compile_options(hkStubs PRIVATE -fno-strict-aliasing)
target_compile_options(hkStubs PRIVATE -Wno-invalid-offsetof)
target_include_directories(hkStubs PUBLIC ./)
+
+if(NOT TARGET NintendoSDK)
+ add_subdirectory(../NintendoSDK)
+endif()
+target_link_libraries(hkStubs PUBLIC NintendoSDK)
diff --git a/lib/hkStubs/Havok/Common/Base/Memory/Allocator/Lifo/hkLifoAllocator.h b/lib/hkStubs/Havok/Common/Base/Memory/Allocator/Lifo/hkLifoAllocator.h
new file mode 100644
index 00000000..2305dbf8
--- /dev/null
+++ b/lib/hkStubs/Havok/Common/Base/Memory/Allocator/Lifo/hkLifoAllocator.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include <Havok/Common/Base/Memory/Allocator/hkMemoryAllocator.h>
+
+class hkLifoAllocator : public hkMemoryAllocator {
+public:
+ explicit hkLifoAllocator(int slabSize = 32 * 1024);
+
+ void init(hkMemoryAllocator* slabAllocator, hkMemoryAllocator* largeAllocator,
+ hkMemoryAllocator* internalAllocator);
+ /// Optional: [slabAllocator, largeAllocator, internalAllocator]
+ void quit(hkMemoryAllocator* allocators[3] = nullptr);
+
+ void* blockAlloc(int numBytes) override;
+
+ /// Inline equivalent of blockAlloc
+ // TODO: add this if this is actually used by BotW
+ HK_FORCE_INLINE void* fastBlockAlloc(int numBytes);
+
+ void blockFree(void* p, int numBytes) override;
+
+ /// Inline equivalent of blockFree
+ // TODO: add this if this is actually used by BotW
+ HK_FORCE_INLINE void fastBlockFree(void* p, int numBytes);
+
+ void* bufAlloc(int& reqNumBytesInOut) override;
+ void bufFree(void* p, int numBytes) override;
+ void* bufRealloc(void* pold, int oldNumBytes, int& reqNumBytesInOut) override;
+
+ void getMemoryStatistics(MemoryStatistics& u) const override {}
+ int getAllocatedSize(const void* obj, int nbytes) const override { return nbytes; }
+
+ bool isEmpty() const;
+ int numExternalAllocations() const;
+
+protected:
+ void* allocateFromNewSlab(int nbytes);
+ void popNonLifoFrees();
+ void slowBlockFree(void*, int numBytesIn);
+ void insertNonLifoFree(void* p, int nbytes);
+
+ class Implementation;
+
+ Implementation* m_impl;
+
+ const int m_slabSize;
+
+ void* m_cur;
+ void* m_end;
+ void* m_firstNonLifoEnd;
+
+ void* m_cachedEmptySlab;
+
+ hkMemoryAllocator* m_slabAllocator;
+ hkMemoryAllocator* m_largeAllocator;
+ hkMemoryAllocator* m_internalAllocator;
+};
diff --git a/lib/hkStubs/Havok/Common/Base/Memory/Allocator/hkMemoryAllocator.h b/lib/hkStubs/Havok/Common/Base/Memory/Allocator/hkMemoryAllocator.h
new file mode 100644
index 00000000..b024b565
--- /dev/null
+++ b/lib/hkStubs/Havok/Common/Base/Memory/Allocator/hkMemoryAllocator.h
@@ -0,0 +1,102 @@
+#pragma once
+
+#include <Havok/Common/Base/Types/hkBaseTypes.h>
+
+class hkMemorySnapshot;
+
+template <typename T>
+struct hkSizeOfTypeOrVoid {
+ enum { val = sizeof(T) };
+};
+
+template <>
+struct hkSizeOfTypeOrVoid<void> {
+ enum { val = 1 };
+};
+
+class hkMemoryAllocator {
+public:
+ using MemoryWalkCallback = void (*)(void* start, hk_size_t size, bool allocated, int pool,
+ void* param);
+
+ struct MemoryStatistics {
+ static const hkLong INFINITE_SIZE = -1;
+
+ hkLong m_allocated = -1;
+ hkLong m_inUse = -1;
+ hkLong m_peakInUse = -1;
+ hkLong m_available = -1;
+ hkLong m_totalAvailable = -1;
+ hkLong m_largestBlock = -1;
+ };
+
+ struct ExtendedInterface {
+ virtual ~ExtendedInterface() = default;
+
+ virtual void garbageCollect() = 0;
+ virtual void incrementalGarbageCollect(int numBlocks) = 0;
+ virtual hkResult setMemorySoftLimit(hk_size_t maxMemory) = 0;
+ virtual hk_size_t getMemorySoftLimit() const = 0;
+ virtual bool canAllocTotal(int numBytes) = 0;
+ virtual hkResult walkMemory(MemoryWalkCallback callback, void* param) = 0;
+ virtual hk_size_t getApproxTotalAllocated() const = 0;
+ virtual void setScrubValues(hkUint32 allocValue, hkUint32 freeValue) = 0;
+ virtual int addToSnapshot(hkMemorySnapshot& snap, int parentId) = 0;
+ };
+
+ virtual ~hkMemoryAllocator();
+
+ virtual void* blockAlloc(int numBytes) = 0;
+ virtual void blockFree(void* p, int numBytes) = 0;
+ virtual void* bufAlloc(int& reqNumBytesInOut);
+ virtual void bufFree(void* p, int numBytes);
+ virtual void* bufRealloc(void* pold, int oldNumBytes, int& reqNumBytesInOut);
+
+ virtual void blockAllocBatch(void** ptrsOut, int numPtrs, int blockSize);
+ virtual void blockFreeBatch(void** ptrsIn, int numPtrs, int blockSize);
+
+ virtual void getMemoryStatistics(MemoryStatistics& u) const = 0;
+ virtual int getAllocatedSize(const void* obj, int nbytes) const = 0;
+ virtual void resetPeakMemoryStatistics() {}
+
+ virtual ExtendedInterface* getExtendedInterface() { return nullptr; }
+
+ template <typename TYPE>
+ inline TYPE* _bufAlloc(int& reqNumInOut) {
+ const int SIZE_ELEM = hkSizeOfTypeOrVoid<TYPE>::val;
+ int n = reqNumInOut * SIZE_ELEM;
+ void* p = bufAlloc(n);
+ reqNumInOut = n / SIZE_ELEM;
+ return static_cast<TYPE*>(p);
+ }
+
+ template <typename TYPE>
+ inline void _bufFree(void* p, int numElem) {
+ const int SIZE_ELEM = hkSizeOfTypeOrVoid<TYPE>::val;
+ bufFree(p, numElem * SIZE_ELEM);
+ }
+
+ template <typename TYPE>
+ inline TYPE* _bufRealloc(void* pold, int oldNum, int& reqNumInOut) {
+ const int SIZE_ELEM = hkSizeOfTypeOrVoid<TYPE>::val;
+ int n = reqNumInOut * SIZE_ELEM;
+ void* p = bufRealloc(pold, oldNum * SIZE_ELEM, n);
+ reqNumInOut = n / SIZE_ELEM;
+ return static_cast<TYPE*>(p);
+ }
+
+ template <typename TYPE>
+ inline TYPE* _blockAlloc(int n) {
+ return static_cast<TYPE*>(blockAlloc(n * hkSizeOfTypeOrVoid<TYPE>::val));
+ }
+
+ template <typename TYPE>
+ inline void _blockFree(TYPE* p, int n) {
+ blockFree(p, n * hkSizeOfTypeOrVoid<TYPE>::val);
+ }
+
+ enum MemoryState {
+ MEMORY_STATE_OK,
+ MEMORY_STATE_OUT_OF_MEMORY,
+ };
+};
diff --git a/lib/hkStubs/Havok/Common/Base/Memory/Router/hkMemoryRouter.h b/lib/hkStubs/Havok/Common/Base/Memory/Router/hkMemoryRouter.h
new file mode 100644
index 00000000..d8be9046
--- /dev/null
+++ b/lib/hkStubs/Havok/Common/Base/Memory/Router/hkMemoryRouter.h
@@ -0,0 +1,98 @@
+#pragma once
+
+#include <Havok/Common/Base/Memory/Allocator/Lifo/hkLifoAllocator.h>
+#include <Havok/Common/Base/Memory/Allocator/hkMemoryAllocator.h>
+#include <Havok/Common/Base/Thread/Thread/hkThreadLocalData.h>
+#include <type_traits>
+
+class hkLifoAllocator;
+
+class hkOstream;
+
+class hkMemoryRouter {
+public:
+ using Stack = hkLifoAllocator;
+ using Allocator = hkMemoryAllocator;
+
+ static void replaceInstance(hkMemoryRouter* m);
+
+ static inline hkMemoryRouter& getInstance() { return *getInstancePtr(); }
+ static inline hkMemoryRouter* getInstancePtr() { return HK_THREAD_LOCAL_GET(s_memoryRouter); }
+
+ hkMemoryRouter();
+
+ void resetPeakMemoryStatistics();
+
+ /// Small thread local allocation in a stack pattern.
+ inline Stack& stack() { return m_stack; }
+
+ /// Temporary allocation, thread local. Often but not always in a stack pattern.
+ inline Allocator& temp() { return *m_temp; }
+ inline void setTemp(Allocator* a) { m_temp = a; }
+
+ /// Allocation which is likely to persist. Not thread local.
+ inline Allocator& heap() { return *m_heap; }
+ inline void setHeap(Allocator* a) { m_heap = a; }
+
+ /// Allocation which may break the rules. Not thread local.
+ inline Allocator& debug() { return *m_debug; }
+ inline void setDebug(Allocator* a) { m_debug = a; }
+
+ inline Allocator& solver() { return *m_solver; }
+ inline void setSolver(Allocator* a) { m_solver = a; }
+
+ inline void* getUserData() const { return m_userData; }
+ inline void setUserData(void* p) { m_userData = p; }
+
+ inline const hkUint32* getRefObjectLocalStore() const { return &m_refObjLocalStore; }
+ inline hkUint32* getRefObjectLocalStore() { return &m_refObjLocalStore; }
+
+ static void* alignedAlloc(Allocator& b, int nbytes, int align);
+ static void alignedFree(Allocator& b, void* p);
+
+ static void* easyAlloc(Allocator& b, int nbytes);
+ static hk_size_t getEasyAllocSize(Allocator& b, const void* ptr);
+ static const void* getEasyAllocStartAddress(Allocator& b, const void* ptr);
+ static void easyFree(Allocator& b, void* p);
+
+protected:
+ Stack m_stack;
+
+ Allocator* m_temp;
+ Allocator* m_heap;
+ Allocator* m_debug;
+ Allocator* m_solver;
+
+ void* m_userData;
+ hkUint32 m_refObjLocalStore;
+
+ static HK_THREAD_LOCAL(hkMemoryRouter*) s_memoryRouter;
+};
+
+#define HK_DECLARE_CLASS_ALLOCATOR_IMPL(CLASS_TYPE, ALLOCATOR) \
+ HK_FORCE_INLINE void* operator new(hk_size_t nbytes) { \
+ if constexpr (std::is_base_of_v<hkReferencedObject, CLASS_TYPE>) { \
+ return hkMemoryRouter::getInstance().ALLOCATOR().blockAlloc(static_cast<int>(nbytes)); \
+ } else { \
+ return hkMemoryRouter::getInstance().ALLOCATOR().blockAlloc(sizeof(CLASS_TYPE)); \
+ } \
+ } \
+ HK_FORCE_INLINE void operator delete(void* p, hk_size_t nbytes) { \
+ if constexpr (std::is_base_of_v<hkReferencedObject, CLASS_TYPE>) { \
+ auto* b = static_cast<hkReferencedObject*>(p); \
+ hkMemoryRouter::getInstance().ALLOCATOR().blockFree( \
+ p, (b->getMemorySizeAndFlags() == 0xffff) ? static_cast<int>(nbytes) : \
+ b->getMemorySizeAndFlags()); \
+ } else { \
+ hkMemoryRouter::getInstance().ALLOCATOR().blockFree(p, sizeof(CLASS_TYPE)); \
+ } \
+ } \
+ HK_FORCE_INLINE void* operator new(hk_size_t, void* p) { return p; } \
+ HK_FORCE_INLINE void* operator new[](hk_size_t, void* p) { return p; } \
+ HK_FORCE_INLINE void operator delete(void*, void*) {} \
+ HK_FORCE_INLINE void operator delete[](void*, void*) {}
+
+#define HK_DECLARE_CLASS_ALLOCATOR(CLASS_TYPE) HK_DECLARE_CLASS_ALLOCATOR_IMPL(CLASS_TYPE, heap)
+
+#define HK_DECLARE_CLASS_DEBUG_ALLOCATOR(CLASS_TYPE) \
+ HK_DECLARE_CLASS_ALLOCATOR_IMPL(CLASS_TYPE, debug)
diff --git a/lib/hkStubs/Havok/Common/Base/Object/hkBaseObject.h b/lib/hkStubs/Havok/Common/Base/Object/hkBaseObject.h
index 072425f7..feb8f474 100644
--- a/lib/hkStubs/Havok/Common/Base/Object/hkBaseObject.h
+++ b/lib/hkStubs/Havok/Common/Base/Object/hkBaseObject.h
@@ -4,5 +4,6 @@
class hkBaseObject {
public:
- virtual ~hkBaseObject() {}
+ virtual ~hkBaseObject() = default;
+ virtual void __first_virtual_table_function__() {} // NOLINT(bugprone-reserved-identifier)
};
diff --git a/lib/hkStubs/Havok/Common/Base/Object/hkReferencedObject.cpp b/lib/hkStubs/Havok/Common/Base/Object/hkReferencedObject.cpp
new file mode 100644
index 00000000..b67324b2
--- /dev/null
+++ b/lib/hkStubs/Havok/Common/Base/Object/hkReferencedObject.cpp
@@ -0,0 +1,9 @@
+#include <Havok/Common/Base/Object/hkReferencedObject.h>
+
+const void* hkReferencedObject::getClassType() const {
+ return nullptr;
+}
+
+void hkReferencedObject::deleteThisReferencedObject() const {
+ delete this;
+}
diff --git a/lib/hkStubs/Havok/Common/Base/Object/hkReferencedObject.h b/lib/hkStubs/Havok/Common/Base/Object/hkReferencedObject.h
index aacc1c8e..8fbf51c4 100644
--- a/lib/hkStubs/Havok/Common/Base/Object/hkReferencedObject.h
+++ b/lib/hkStubs/Havok/Common/Base/Object/hkReferencedObject.h
@@ -1,10 +1,98 @@
#pragma once
+#include <Havok/Common/Base/Memory/Router/hkMemoryRouter.h>
#include <Havok/Common/Base/Object/hkBaseObject.h>
+#include <Havok/Common/Base/Types/hkBaseDefs.h>
+#include <Havok/Common/Base/Types/hkBaseTypes.h>
+#include "Havok/Common/Base/Thread/Atomic/hkAtomicPrimitives.h"
class hkReferencedObject : public hkBaseObject {
public:
- virtual ~hkReferencedObject() {}
+ inline hkReferencedObject();
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
+ explicit hkReferencedObject(hkFinishLoadedObjectFlag flag) {}
+
+ /// Dummy copy constructor and copy assignment operator.
+ inline hkReferencedObject(const hkReferencedObject& other);
+ inline hkReferencedObject& operator=(const hkReferencedObject& other);
+
+ ~hkReferencedObject() override = default;
virtual const void* getClassType() const;
+
+ inline int getReferenceCount() const;
+ inline void setReferenceCount(int newRefCount);
+ inline void addReference() const;
+ inline void removeReference() const;
+
+ inline int getAllocatedSize() const;
+ inline int getMemorySizeAndFlags() const;
+ inline void setMemorySizeAndFlags(int newMemSizeAndFlags);
+ inline void setMemorySizeFlagsAndReferenceCount(int newMemSizeAndFlags, int newRefCount);
+
+protected:
+ virtual void deleteThisReferencedObject() const;
+
+private:
+ mutable hkUint32 m_memSizeAndRefCount;
};
+
+inline hkReferencedObject::hkReferencedObject() : m_memSizeAndRefCount(0xFFFF0001) {}
+
+inline hkReferencedObject::hkReferencedObject(const hkReferencedObject& other)
+ : m_memSizeAndRefCount(0xFFFF0001) {}
+
+inline hkReferencedObject& hkReferencedObject::operator=(const hkReferencedObject& other) {
+ return *this;
+}
+
+inline int hkReferencedObject::getReferenceCount() const {
+ return int(m_memSizeAndRefCount & 0xFFFF);
+}
+
+inline void hkReferencedObject::setReferenceCount(int newRefCount) {
+ hkAtomic::readModifyWrite(&m_memSizeAndRefCount, [newRefCount](hkUint32 oldVal) {
+ return (oldVal & 0xFFFF0000) | (newRefCount & 0xFFFF);
+ });
+}
+
+inline void hkReferencedObject::addReference() const {
+ if (getMemorySizeAndFlags() == 0)
+ return;
+
+ hkAtomic::readModifyWrite(&m_memSizeAndRefCount, [](hkUint32 oldVal) {
+ return (oldVal & 0xFFFF0000) | (((oldVal & 0xFFFF) + 1) & 0xFFFF);
+ });
+}
+
+inline void hkReferencedObject::removeReference() const {
+ if (getMemorySizeAndFlags() == 0)
+ return;
+
+ auto newVal = hkAtomic::readModifyWrite(&m_memSizeAndRefCount, [](hkUint32 oldVal) {
+ return (oldVal & 0xFFFF0000) | (((oldVal & 0xFFFF) - 1) & 0xFFFF);
+ });
+
+ if ((newVal & 0xFFFF) == 0)
+ deleteThisReferencedObject();
+}
+
+inline int hkReferencedObject::getAllocatedSize() const {
+ return getMemorySizeAndFlags() & 0x7FFF;
+}
+
+inline int hkReferencedObject::getMemorySizeAndFlags() const {
+ return int((m_memSizeAndRefCount >> 16) & 0xFFFF);
+}
+
+inline void hkReferencedObject::setMemorySizeAndFlags(int newMemSizeAndFlags) {
+ hkAtomic::readModifyWrite(&m_memSizeAndRefCount, [=](hkUint32 oldVal) {
+ return (newMemSizeAndFlags << 16) | (oldVal & 0xFFFF);
+ });
+}
+
+inline void hkReferencedObject::setMemorySizeFlagsAndReferenceCount(int newMemSizeAndFlags,
+ int newRefCount) {
+ const hkUint32 newVal = (newMemSizeAndFlags << 16) | (newRefCount & 0xFFFF);
+ hkAtomic::readModifyWrite(&m_memSizeAndRefCount, [=](auto) { return newVal; });
+}
diff --git a/lib/hkStubs/Havok/Common/Base/Thread/Atomic/hkAtomicPrimitives.h b/lib/hkStubs/Havok/Common/Base/Thread/Atomic/hkAtomicPrimitives.h
new file mode 100644
index 00000000..ba81e7c7
--- /dev/null
+++ b/lib/hkStubs/Havok/Common/Base/Thread/Atomic/hkAtomicPrimitives.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <Havok/Common/Base/hkBase.h>
+
+namespace hkAtomic {
+
+/// Weak compare-and-swap.
+template <typename T>
+HK_FORCE_INLINE bool compareAndSwap(volatile T* address, const T& oldValue, const T& newValue) {
+ T expected = oldValue;
+ return __atomic_compare_exchange_n(address, &expected, newValue, false, __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+}
+
+template <typename T, typename Fn>
+HK_FORCE_INLINE T readModifyWrite(volatile T* address, const Fn& getNewValue) {
+ T oldVal, newVal;
+ do {
+ oldVal = *address;
+ newVal = getNewValue(oldVal);
+ } while (!hkAtomic::compareAndSwap(address, oldVal, newVal));
+ return newVal;
+}
+
+} // namespace hkAtomic
diff --git a/lib/hkStubs/Havok/Common/Base/Thread/Thread/hkThreadLocalData.h b/lib/hkStubs/Havok/Common/Base/Thread/Thread/hkThreadLocalData.h
new file mode 100644
index 00000000..30dfa527
--- /dev/null
+++ b/lib/hkStubs/Havok/Common/Base/Thread/Thread/hkThreadLocalData.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#include <nn/os.h>
+
+template <typename T>
+class hkThreadLocalData {
+public:
+ hkThreadLocalData() { nn::os::AllocateTlsSlot(&m_tls_slot, nullptr); }
+ ~hkThreadLocalData() { nn::os::FreeTlsSlot(m_tls_slot); }
+
+ T getData() const { return reinterpret_cast<T>(nn::os::GetTlsValue(m_tls_slot)); }
+ void setData(T p) { nn::os::SetTlsValue(m_tls_slot, reinterpret_cast<unsigned long>(p)); }
+
+private:
+ nn::os::TlsSlot m_tls_slot{};
+};
+
+#define HK_THREAD_LOCAL(TYPE) hkThreadLocalData<TYPE>
+#define HK_THREAD_LOCAL_SET(var, value) var.setData(value)
+#define HK_THREAD_LOCAL_GET(var) var.getData()
diff --git a/lib/hkStubs/Havok/Common/Base/Types/hkBaseTypes.h b/lib/hkStubs/Havok/Common/Base/Types/hkBaseTypes.h
index 5a7018b8..318cb31c 100644
--- a/lib/hkStubs/Havok/Common/Base/Types/hkBaseTypes.h
+++ b/lib/hkStubs/Havok/Common/Base/Types/hkBaseTypes.h
@@ -1,20 +1,27 @@
#pragma once
+#include <Havok/Common/Base/Types/hkBaseDefs.h>
+#include <cstdint>
+
using hkFloat32 = float;
using hkDouble64 = double;
using hkReal = hkFloat32;
-using hkChar = signed char;
-using hkInt8 = signed char;
-using hkInt16 = signed short;
-using hkInt32 = signed int;
+using hkChar = char;
+using hkInt8 = std::int8_t;
+using hkInt16 = std::int16_t;
+using hkInt32 = std::int32_t;
+using hkInt64 = std::int64_t;
using hkUchar = unsigned char;
-using hkUint8 = unsigned char;
-using hkUint16 = unsigned short;
-using hkUint32 = unsigned int;
+using hkUint8 = std::uint8_t;
+using hkUint16 = std::uint16_t;
+using hkUint32 = std::uint32_t;
+using hkUint64 = std::uint64_t;
+using hk_size_t = hkUint64;
+using hkLong = long;
+using hkUlong = unsigned long;
-using hkUint64 = unsigned long long;
using m128 = __attribute((vector_size(16))) float;
class hkHalf {
@@ -118,3 +125,36 @@ public:
private:
Storage m_storage;
};
+
+enum hkResultEnum {
+ HK_SUCCESS = 0,
+ HK_FAILURE = 1,
+};
+
+struct hkResult {
+ HK_FORCE_INLINE hkResult() {}
+ HK_FORCE_INLINE hkResult(hkResultEnum b) { m_enum = b; }
+
+ HK_FORCE_INLINE hkResult& operator=(hkResultEnum e) {
+ m_enum = e;
+ return *this;
+ }
+
+ HK_FORCE_INLINE bool operator==(hkResultEnum e) const { return m_enum == e; }
+ HK_FORCE_INLINE bool operator!=(hkResultEnum e) const { return m_enum != e; }
+
+ HK_FORCE_INLINE bool isSuccess() const { return m_enum ^ HK_FAILURE; }
+
+ hkResultEnum m_enum;
+};
+
+inline bool operator==(hkResultEnum e, hkResult r) {
+ return r.m_enum == e;
+}
+inline bool operator!=(hkResultEnum e, hkResult r) {
+ return r.m_enum != e;
+}
+
+struct hkFinishLoadedObjectFlag {
+ int m_finishing = 0;
+};
diff --git a/lib/hkStubs/Havok/Common/Base/hkBase.h b/lib/hkStubs/Havok/Common/Base/hkBase.h
index c79c768a..47c37691 100644
--- a/lib/hkStubs/Havok/Common/Base/hkBase.h
+++ b/lib/hkStubs/Havok/Common/Base/hkBase.h
@@ -7,4 +7,6 @@
#include <Havok/Common/Base/Math/hkMath.h>
+#include <Havok/Common/Base/Memory/Router/hkMemoryRouter.h>
+
#include <Havok/Common/Base/Container/String/hkStringPtr.h>
diff --git a/lib/sead b/lib/sead
-Subproject bc92bd8d9adb6791feef492643ddaf08b99985e
+Subproject ca3982b344be82ac3578f545c64403ae4158911