From a2fecf4846a257d7827df908b151a455bf3d866f Mon Sep 17 00:00:00 2001 From: RunnerScrab Date: Mon, 27 Oct 2025 14:16:37 -0500 Subject: [PATCH 1/3] Update the Address Library IDs for BarterMenu* and Activation --- include/RE/IDs.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/RE/IDs.h b/include/RE/IDs.h index 2827634..2e7dfbb 100644 --- a/include/RE/IDs.h +++ b/include/RE/IDs.h @@ -4,12 +4,12 @@ namespace RE::ID { namespace Activation::Event { - inline constexpr REL::ID GetEventSource{ 0 }; // 106834 + inline constexpr REL::ID GetEventSource{ 63133 }; // 106834 } namespace ActivityEvents::ActivityCompletedEvent { - inline constexpr REL::ID GetEventSource{ 0 }; // 86737 + inline constexpr REL::ID GetEventSource{ 47920 }; // 86737 } namespace Actor @@ -64,37 +64,37 @@ namespace RE::ID namespace BarterMenu_BuyItem { - inline constexpr REL::ID GetEventSource{ 0 }; // 138993 + inline constexpr REL::ID GetEventSource{ 91373 }; // 138993 } namespace BarterMenu_CloseMenu { - inline constexpr REL::ID GetEventSource{ 0 }; // 138994 + inline constexpr REL::ID GetEventSource{ 91378 }; // 138994 } namespace BarterMenu_HideModel { - inline constexpr REL::ID GetEventSource{ 0 }; // 138995 + inline constexpr REL::ID GetEventSource{ 91376 }; // 138995 } namespace BarterMenu_LoadModel { - inline constexpr REL::ID GetEventSource{ 0 }; // 138996 + inline constexpr REL::ID GetEventSource{ 91377 }; // 138996 } namespace BarterMenu_SellItem { - inline constexpr REL::ID GetEventSource{ 0 }; // 138997 + inline constexpr REL::ID GetEventSource{ 91372 }; // 138997 } namespace BarterMenu_SetMouseOverModel { - inline constexpr REL::ID GetEventSource{ 0 }; // 138998 + inline constexpr REL::ID GetEventSource{ 91371 }; // 138998 } namespace BarterMenu_ViewedItem { - inline constexpr REL::ID GetEventSource{ 0 }; // 139000 + inline constexpr REL::ID GetEventSource{ 91374 }; // 139000 } namespace BaseExtraList From d3e3b73f5952e574ffca033571747d11dec8be83 Mon Sep 17 00:00:00 2001 From: RunnerScrab Date: Tue, 28 Oct 2025 17:09:19 -0500 Subject: [PATCH 2/3] Reimplement Object::IncRef(), Object::DecRef(), Object::GetHandle() Move new Object member functions definitions into a .cpp file Add TODO for BSScript::~Object() --- include/RE/IDs.h | 8 +-- include/RE/O/Object.h | 27 ++------- src/RE/O/Object.cpp | 131 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 25 deletions(-) create mode 100644 src/RE/O/Object.cpp diff --git a/include/RE/IDs.h b/include/RE/IDs.h index 2e7dfbb..19e5701 100644 --- a/include/RE/IDs.h +++ b/include/RE/IDs.h @@ -4,7 +4,7 @@ namespace RE::ID { namespace Activation::Event { - inline constexpr REL::ID GetEventSource{ 63133 }; // 106834 + inline constexpr REL::ID GetEventSource{ 63133 }; // 106834 } namespace ActivityEvents::ActivityCompletedEvent @@ -274,9 +274,9 @@ namespace RE::ID namespace Object { - inline constexpr REL::ID ctor{ 0 }; // 196025 - inline constexpr REL::ID dtor{ 0 }; // 196032 - inline constexpr REL::ID GetHandle{ 0 }; // 196069 + inline constexpr REL::ID ctor{ 137778 }; // 196025 + inline constexpr REL::ID dtor{ 0 }; // 196032 - inlined + inline constexpr REL::ID GetHandle{ 0 }; // 196069 - inlined inline constexpr REL::ID SetHandle{ 0 }; // 196079 inline constexpr REL::ID IncRef{ 0 }; // 37879 inline constexpr REL::ID DecRef{ 0 }; // 196057 diff --git a/include/RE/O/Object.h b/include/RE/O/Object.h index dafa6a9..c55b58d 100644 --- a/include/RE/O/Object.h +++ b/include/RE/O/Object.h @@ -23,6 +23,8 @@ namespace RE::BSScript ~Object() { + // TODO: The destructor was inlined in version Starfield 1.15 and still needs to be + // pieced together or reimplemented dtor(); } @@ -44,26 +46,9 @@ namespace RE::BSScript [[nodiscard]] constexpr bool IsInitialized() const noexcept { return static_cast(initialized); } [[nodiscard]] constexpr bool IsValid() const noexcept { return static_cast(valid); } - [[nodiscard]] std::uint32_t DecRef() const - { - using func_t = decltype(&Object::DecRef); - static REL::Relocation func{ ID::BSScript::Object::DecRef }; - return func(this); - } - - [[nodiscard]] std::size_t GetHandle() const - { - using func_t = decltype(&Object::GetHandle); - static REL::Relocation func{ ID::BSScript::Object::GetHandle }; - return func(this); - } - - void IncRef() const - { - using func_t = decltype(&Object::IncRef); - static REL::Relocation func{ ID::BSScript::Object::IncRef }; - return func(this); - } + [[nodiscard]] std::uint32_t DecRef(); + [[nodiscard]] std::size_t GetHandle(); + void IncRef(); SF_HEAP_REDEFINE_NEW(); @@ -84,7 +69,7 @@ namespace RE::BSScript void* lockStructure; // 30 IObjectHandlePolicy* handlePolicy; // 38 std::size_t handle; // 40 - std::uint32_t refCountAndHandleLock; // 48 + volatile std::uint32_t refCountAndHandleLock; // 48 }; static_assert(sizeof(Object) == 0x50); } diff --git a/src/RE/O/Object.cpp b/src/RE/O/Object.cpp new file mode 100644 index 0000000..3434906 --- /dev/null +++ b/src/RE/O/Object.cpp @@ -0,0 +1,131 @@ +#include "RE/O/Object.h" + +namespace RE::BSScript +{ + [[nodiscard]] std::uint32_t Object::DecRef() + { + std::int32_t iVar1; + std::uint32_t uVar2; + bool bVar3; + + uVar2 = 0; + do { + while (true) { + while (iVar1 = this->refCountAndHandleLock, iVar1 < 0) { + if (uVar2 == 0) { + _mm_pause(); + uVar2 = 1; + } else { + bVar3 = 9999 < uVar2; + if (!bVar3) { + uVar2 = uVar2 + 1; + } + REX::W32::Sleep(static_cast(bVar3)); + } + } + + if (iVar1 != 2) + break; + + bVar3 = _InterlockedCompareExchange(reinterpret_cast(&(this->refCountAndHandleLock)), + -0x7ffffffe, 2) == 2; + if (bVar3) { + _mm_mfence(); + this->handlePolicy->ReleaseHandle(this->handle); + _mm_mfence(); + this->refCountAndHandleLock = 1; + return 1; + } + } + bVar3 = _InterlockedCompareExchange(reinterpret_cast(&(this->refCountAndHandleLock)), + iVar1 - 1, iVar1) == iVar1; + + } while (!bVar3); + return iVar1 - 1; + } + + [[nodiscard]] std::size_t Object::GetHandle() + { + std::uint32_t uVar1; + std::uint32_t uVar2; + bool bVar3; + //The hexadecimal numbers next to the member functions in + // IObjectHandlePolicy are vtable indices, NOT byte offsets + this->handlePolicy->EmptyHandle(); + uVar2 = 0; + do { + while (uVar1 = this->refCountAndHandleLock, (int)uVar1 < 0) { + if (uVar2 == 0) { + _mm_pause(); + uVar2 = 1; + } else { + bVar3 = 9999 < uVar2; + if (!bVar3) { + uVar2 = uVar2 + 1; + } + REX::W32::Sleep(static_cast(bVar3)); + } + } + + bVar3 = _InterlockedCompareExchange(reinterpret_cast(&(this->refCountAndHandleLock)), + uVar1 | 0x80000000, uVar1) == uVar1; + + } while (!bVar3); + _mm_mfence(); + this->refCountAndHandleLock = uVar1; + _mm_mfence(); + return this->handle; + } + + void Object::IncRef() + { + std::uint32_t uVar1; + std::uint32_t uVar2; + std::uint64_t uVar3; + std::uint32_t uVar4; + bool bVar5; + + uVar4 = 0; + do { + while (true) { + _mm_mfence(); + while (uVar2 = this->refCountAndHandleLock, (int)uVar2 < 0) { + if (uVar4 == 0) { + _mm_pause(); + uVar4 = 1; + } else { + bVar5 = 9999 < uVar4; + if (!bVar5) { + uVar4 = uVar4 + 1; + } + REX::W32::Sleep(static_cast(bVar5)); + } + } + if (uVar2 != 1) + break; + + bVar5 = _InterlockedCompareExchange(reinterpret_cast(&(this->refCountAndHandleLock)), + -0x7fffffff, 1) == 1; + if (bVar5) { + _mm_mfence(); + this->handlePolicy->PersistHandle(this->handle); + _mm_mfence(); + this->refCountAndHandleLock = 2; + return; + } + } + + bVar5 = _InterlockedCompareExchange(reinterpret_cast(&(this->refCountAndHandleLock)), + uVar2 + 1, uVar2) == uVar2; + if (bVar5) { + uVar1 = uVar2; + return; + } + + } while (!bVar5); + + this->refCountAndHandleLock = uVar1; + return; + } +} + From 9f2e6d1cfb78d4666ccb3c640dd3a85f2bbfea3c Mon Sep 17 00:00:00 2001 From: RunnerScrab <45054749+RunnerScrab@users.noreply.github.com> Date: Wed, 29 Oct 2025 02:24:35 +0000 Subject: [PATCH 3/3] maintenance --- src/RE/O/Object.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/RE/O/Object.cpp b/src/RE/O/Object.cpp index 3434906..d9affb7 100644 --- a/src/RE/O/Object.cpp +++ b/src/RE/O/Object.cpp @@ -128,4 +128,3 @@ namespace RE::BSScript return; } } -