From 3e2ee68fd66b984071f5ae9826d590ae342509b3 Mon Sep 17 00:00:00 2001 From: powerof3 <32599957+powerof3@users.noreply.github.com> Date: Wed, 15 May 2024 07:53:59 +0530 Subject: [PATCH 1/5] update --- CommonLibF4/cmake/sourcelist.cmake | 5 + CommonLibF4/include/F4SE/F4SE.h | 1 + CommonLibF4/include/F4SE/Impl/PCH.h | 56 ++--- CommonLibF4/include/F4SE/Impl/ScePadAPI.h | 30 +++ CommonLibF4/include/F4SE/Impl/XInputAPI.h | 77 +++++++ CommonLibF4/include/F4SE/InputMap.h | 51 +++++ .../RE/Bethesda/BSInputEnableManager.h | 145 +++++++++++++ CommonLibF4/include/RE/Bethesda/ControlMap.h | 25 +++ CommonLibF4/include/RE/Bethesda/IMenu.h | 27 +++ CommonLibF4/include/RE/Bethesda/InputEvent.h | 12 +- CommonLibF4/include/RE/Bethesda/Sky.h | 5 +- CommonLibF4/include/RE/Bethesda/UserEvents.h | 2 + CommonLibF4/include/RE/Fallout.h | 1 + CommonLibF4/src/F4SE/InputMap.cpp | 192 ++++++++++++++++++ 14 files changed, 601 insertions(+), 28 deletions(-) create mode 100644 CommonLibF4/include/F4SE/Impl/ScePadAPI.h create mode 100644 CommonLibF4/include/F4SE/Impl/XInputAPI.h create mode 100644 CommonLibF4/include/F4SE/InputMap.h create mode 100644 CommonLibF4/include/RE/Bethesda/BSInputEnableManager.h create mode 100644 CommonLibF4/src/F4SE/InputMap.cpp diff --git a/CommonLibF4/cmake/sourcelist.cmake b/CommonLibF4/cmake/sourcelist.cmake index d9187a76..da72e224 100644 --- a/CommonLibF4/cmake/sourcelist.cmake +++ b/CommonLibF4/cmake/sourcelist.cmake @@ -2,7 +2,10 @@ set(SOURCES include/F4SE/API.h include/F4SE/F4SE.h include/F4SE/Impl/PCH.h + include/F4SE/Impl/ScePadAPI.h include/F4SE/Impl/WinAPI.h + include/F4SE/Impl/XInputAPI.h + include/F4SE/InputMap.h include/F4SE/Interfaces.h include/F4SE/Logger.h include/F4SE/Trampoline.h @@ -45,6 +48,7 @@ set(SOURCES include/RE/Bethesda/BSGraphics.h include/RE/Bethesda/BSHavok.h include/RE/Bethesda/BSInputDeviceManager.h + include/RE/Bethesda/BSInputEnableManager.h include/RE/Bethesda/BSInputEventReceiver.h include/RE/Bethesda/BSInputEventSingleUser.h include/RE/Bethesda/BSInputEventUser.h @@ -346,6 +350,7 @@ set(SOURCES src/F4SE/API.cpp src/F4SE/Impl/PCH.cpp src/F4SE/Impl/WinAPI.cpp + src/F4SE/InputMap.cpp src/F4SE/Interfaces.cpp src/F4SE/Logger.cpp src/F4SE/Trampoline.cpp diff --git a/CommonLibF4/include/F4SE/F4SE.h b/CommonLibF4/include/F4SE/F4SE.h index f59a15a0..fc60949a 100644 --- a/CommonLibF4/include/F4SE/F4SE.h +++ b/CommonLibF4/include/F4SE/F4SE.h @@ -3,6 +3,7 @@ #include "F4SE/Impl/PCH.h" #include "F4SE/API.h" +#include "F4SE/InputMap.h" #include "F4SE/Interfaces.h" #include "F4SE/Logger.h" #include "F4SE/Trampoline.h" diff --git a/CommonLibF4/include/F4SE/Impl/PCH.h b/CommonLibF4/include/F4SE/Impl/PCH.h index 97d27948..e3ae961b 100644 --- a/CommonLibF4/include/F4SE/Impl/PCH.h +++ b/CommonLibF4/include/F4SE/Impl/PCH.h @@ -96,14 +96,13 @@ namespace F4SE requires( const K& a_transparent, const typename C::key_type& a_key, - typename C::key_compare& a_compare) - { - typename C::key_compare::is_transparent; - // clang-format off + typename C::key_compare& a_compare) { + typename C::key_compare::is_transparent; + // clang-format off { a_compare(a_transparent, a_key) } -> std::convertible_to; { a_compare(a_key, a_transparent) } -> std::convertible_to; - // clang-format on - }; + // clang-format on + }; namespace nttp { @@ -143,9 +142,9 @@ namespace F4SE string(const CharT (&)[N]) -> string; } - template // - requires(std::invocable>) // - class scope_exit + template // + requires(std::invocable>) // + class scope_exit { public: // 1) @@ -289,7 +288,8 @@ namespace F4SE template constexpr enumeration(Args... a_values) noexcept // - requires(std::same_as&&...) : + requires(std::same_as && ...) + : _impl((static_cast(a_values) | ...)) {} @@ -318,7 +318,7 @@ namespace F4SE template constexpr enumeration& set(Args... a_args) noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { _impl |= (static_cast(a_args) | ...); return *this; @@ -326,29 +326,35 @@ namespace F4SE template constexpr enumeration& reset(Args... a_args) noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { _impl &= ~(static_cast(a_args) | ...); return *this; } + constexpr enumeration& reset() noexcept + { + _impl = 0; + return *this; + } + template [[nodiscard]] constexpr bool any(Args... a_args) const noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { return (_impl & (static_cast(a_args) | ...)) != static_cast(0); } template [[nodiscard]] constexpr bool all(Args... a_args) const noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { return (_impl & (static_cast(a_args) | ...)) == (static_cast(a_args) | ...); } template [[nodiscard]] constexpr bool none(Args... a_args) const noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { return (_impl & (static_cast(a_args) | ...)) == static_cast(0); } @@ -381,14 +387,14 @@ namespace F4SE #define F4SE_MAKE_ARITHMETIC_OP(a_op) \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_enum, U a_shift) noexcept \ - ->enumeration \ + -> enumeration \ { \ return static_cast(static_cast(a_enum.get()) a_op a_shift); \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_enum, U a_shift) noexcept \ - ->enumeration& \ + -> enumeration& \ { \ return a_enum = a_enum a_op a_shift; \ } @@ -396,42 +402,42 @@ namespace F4SE #define F4SE_MAKE_ENUMERATION_OP(a_op) \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_lhs, enumeration a_rhs) noexcept \ - ->enumeration> \ + -> enumeration> \ { \ return static_cast(static_cast(a_lhs.get()) a_op static_cast(a_rhs.get())); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_lhs, E a_rhs) noexcept \ - ->enumeration \ + -> enumeration \ { \ return static_cast(static_cast(a_lhs.get()) a_op static_cast(a_rhs)); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op(E a_lhs, enumeration a_rhs) noexcept \ - ->enumeration \ + -> enumeration \ { \ return static_cast(static_cast(a_lhs) a_op static_cast(a_rhs.get())); \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_lhs, enumeration a_rhs) noexcept \ - ->enumeration& \ + -> enumeration& \ { \ return a_lhs = a_lhs a_op a_rhs; \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_lhs, E a_rhs) noexcept \ - ->enumeration& \ + -> enumeration& \ { \ return a_lhs = a_lhs a_op a_rhs; \ } \ \ template \ constexpr auto operator a_op##=(E& a_lhs, enumeration a_rhs) noexcept \ - ->E& \ + -> E& \ { \ return a_lhs = *(a_lhs a_op a_rhs); \ } @@ -439,14 +445,14 @@ namespace F4SE #define F4SE_MAKE_INCREMENTER_OP(a_op) \ template \ constexpr auto operator a_op##a_op(enumeration& a_lhs) noexcept \ - ->enumeration& \ + -> enumeration& \ { \ return a_lhs a_op## = static_cast(1); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op##a_op(enumeration& a_lhs, int) noexcept \ - ->enumeration \ + -> enumeration \ { \ const auto tmp = a_lhs; \ a_op##a_op a_lhs; \ diff --git a/CommonLibF4/include/F4SE/Impl/ScePadAPI.h b/CommonLibF4/include/F4SE/Impl/ScePadAPI.h new file mode 100644 index 00000000..c7991870 --- /dev/null +++ b/CommonLibF4/include/F4SE/Impl/ScePadAPI.h @@ -0,0 +1,30 @@ +#pragma once + +namespace RE +{ + namespace ScePad + { + enum ScePadButton : std::uint32_t + { + SCE_PAD_BUTTON_SHARE = 0x00000001, + SCE_PAD_BUTTON_L3 = 0x00000002, + SCE_PAD_BUTTON_R3 = 0x00000004, + SCE_PAD_BUTTON_OPTIONS = 0x00000008, + SCE_PAD_BUTTON_UP = 0x00000010, + SCE_PAD_BUTTON_RIGHT = 0x00000020, + SCE_PAD_BUTTON_DOWN = 0x00000040, + SCE_PAD_BUTTON_LEFT = 0x00000080, + SCE_PAD_BUTTON_L2 = 0x00000100, + SCE_PAD_BUTTON_R2 = 0x00000200, + SCE_PAD_BUTTON_L1 = 0x00000400, + SCE_PAD_BUTTON_R1 = 0x00000800, + SCE_PAD_BUTTON_TRIANGLE = 0x00001000, + SCE_PAD_BUTTON_CIRCLE = 0x00002000, + SCE_PAD_BUTTON_CROSS = 0x00004000, + SCE_PAD_BUTTON_SQUARE = 0x00008000, + SCE_PAD_BUTTON_PLAYSTATION = 0x0010000, + SCE_PAD_BUTTON_TOUCH_PAD = 0x00100000, + SCE_PAD_BUTTON_INTERCEPTED = 0x80000000, + }; + } +} diff --git a/CommonLibF4/include/F4SE/Impl/XInputAPI.h b/CommonLibF4/include/F4SE/Impl/XInputAPI.h new file mode 100644 index 00000000..8f0b50af --- /dev/null +++ b/CommonLibF4/include/F4SE/Impl/XInputAPI.h @@ -0,0 +1,77 @@ +#pragma once + +namespace RE +{ + namespace XInput + { + struct __XINPUT_GAMEPAD + { + std::uint16_t wButtons; + std::byte bLeftTrigger; + std::byte bRightTrigger; + std::int16_t sThumbLX; + std::int16_t sThumbLY; + std::int16_t sThumbRX; + std::int16_t sThumbRY; + }; + using XINPUT_GAMEPAD = __XINPUT_GAMEPAD; + + struct __XINPUT_STATE + { + std::uint32_t dwPacketNumber; + __XINPUT_GAMEPAD Gamepad; + }; + using XINPUT_STATE = __XINPUT_STATE; + + struct __XINPUT_KEYSTROKE + { + std::uint16_t VirtualKey; + std::uint16_t Unicode; + std::uint16_t Flags; + std::uint8_t UserIndex; + std::uint8_t HidCode; + }; + using XINPUT_KEYSTROKE = __XINPUT_KEYSTROKE; + + struct __XINPUT_VIBRATION + { + std::uint16_t wLeftMotorSpeed; + std::uint16_t wRightMotorSpeed; + }; + using XINPUT_VIBRATION = __XINPUT_VIBRATION; + + struct __XINPUT_CAPABILITIES + { + std::uint8_t Type; + std::uint8_t SubType; + std::uint16_t Flags; + XINPUT_GAMEPAD Gamepad; + XINPUT_VIBRATION Vibration; + }; + using XINPUT_CAPABILITIES = __XINPUT_CAPABILITIES; + + enum XInputButton : std::uint16_t + { + XINPUT_GAMEPAD_DPAD_UP = 0x0001, + XINPUT_GAMEPAD_DPAD_DOWN = 0x0002, + XINPUT_GAMEPAD_DPAD_LEFT = 0x0004, + XINPUT_GAMEPAD_DPAD_RIGHT = 0x0008, + XINPUT_GAMEPAD_START = 0x0010, + XINPUT_GAMEPAD_BACK = 0x0020, + XINPUT_GAMEPAD_LEFT_THUMB = 0x0040, + XINPUT_GAMEPAD_RIGHT_THUMB = 0x0080, + XINPUT_GAMEPAD_LEFT_SHOULDER = 0x0100, + XINPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200, + XINPUT_GAMEPAD_A = 0x1000, + XINPUT_GAMEPAD_B = 0x2000, + XINPUT_GAMEPAD_X = 0x4000, + XINPUT_GAMEPAD_Y = 0x8000 + }; + + static constexpr std::uint16_t XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE = 7849; + static constexpr std::uint16_t XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE = 8689; + static constexpr std::uint8_t XINPUT_GAMEPAD_TRIGGER_THRESHOLD = 30; + + static constexpr std::uint16_t XINPUT_BUTTON_MASK = XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_START | XINPUT_GAMEPAD_BACK | XINPUT_GAMEPAD_LEFT_THUMB | XINPUT_GAMEPAD_RIGHT_THUMB | XINPUT_GAMEPAD_LEFT_SHOULDER | XINPUT_GAMEPAD_RIGHT_SHOULDER | XINPUT_GAMEPAD_A | XINPUT_GAMEPAD_B | XINPUT_GAMEPAD_X | XINPUT_GAMEPAD_Y; + } +} diff --git a/CommonLibF4/include/F4SE/InputMap.h b/CommonLibF4/include/F4SE/InputMap.h new file mode 100644 index 00000000..840ca120 --- /dev/null +++ b/CommonLibF4/include/F4SE/InputMap.h @@ -0,0 +1,51 @@ +#pragma once + +namespace F4SE +{ + namespace InputMap + { + enum + { + // first 256 for keyboard, then 8 mouse buttons, then mouse wheel up, wheel down, then 16 gamepad buttons + kMacro_KeyboardOffset = 0, // not actually used, just for self-documentation + kMacro_NumKeyboardKeys = 256, + + kMacro_MouseButtonOffset = kMacro_NumKeyboardKeys, // 256 + kMacro_NumMouseButtons = 8, + + kMacro_MouseWheelOffset = kMacro_MouseButtonOffset + kMacro_NumMouseButtons, // 264 + kMacro_MouseWheelDirections = 2, + + kMacro_GamepadOffset = kMacro_MouseWheelOffset + kMacro_MouseWheelDirections, // 266 + kMacro_NumGamepadButtons = 16, + + kMaxMacros = kMacro_GamepadOffset + kMacro_NumGamepadButtons // 282 + }; + + enum + { + kGamepadButtonOffset_DPAD_UP = kMacro_GamepadOffset, // 266 + kGamepadButtonOffset_DPAD_DOWN, + kGamepadButtonOffset_DPAD_LEFT, + kGamepadButtonOffset_DPAD_RIGHT, + kGamepadButtonOffset_START, + kGamepadButtonOffset_BACK, + kGamepadButtonOffset_LEFT_THUMB, + kGamepadButtonOffset_RIGHT_THUMB, + kGamepadButtonOffset_LEFT_SHOULDER, + kGamepadButtonOffset_RIGHT_SHOULDER, + kGamepadButtonOffset_A, + kGamepadButtonOffset_B, + kGamepadButtonOffset_X, + kGamepadButtonOffset_Y, + kGamepadButtonOffset_LT, + kGamepadButtonOffset_RT // 281 + }; + + std::uint32_t XInputToScePadOffset(std::uint32_t keyMask); + std::uint32_t ScePadOffsetToXInput(std::uint32_t keyMask); + + std::uint32_t GamepadMaskToKeycode(std::uint32_t keyMask); + std::uint32_t GamepadKeycodeToMask(std::uint32_t keyCode); + } +} diff --git a/CommonLibF4/include/RE/Bethesda/BSInputEnableManager.h b/CommonLibF4/include/RE/Bethesda/BSInputEnableManager.h new file mode 100644 index 00000000..1fa05f0d --- /dev/null +++ b/CommonLibF4/include/RE/Bethesda/BSInputEnableManager.h @@ -0,0 +1,145 @@ +#pragma once + +#include "RE/Bethesda/BSFixedString.h" +#include "RE/Bethesda/BSLock.h" +#include "RE/Bethesda/BSTArray.h" +#include "RE/Bethesda/BSTSingleton.h" +#include "RE/Bethesda/BSTSmartPointer.h" +#include "RE/Bethesda/UserEvents.h" + +namespace RE +{ + class InputEnableLayerDestroyedEvent; + class OtherEventEnabledEvent; + class UserEventEnabledEvent; + + namespace OtherInputEvents + { + enum class OTHER_EVENT_FLAG + { + kAll = static_cast>(-1), + + kJournalTabs = 1 << 0, + kActivation = 1 << 1, + kFastTravel = 1 << 2, + kPOVChange = 1 << 3, + kVATS = 1 << 4, + kFavorites = 1 << 5, + kPipboyLight = 1 << 6, + kZKey = 1 << 7, + kRunning = 1 << 8, + kCursor = 1 << 9, + kSprinting = 1 << 10, + }; + } + + using OEFlag = OtherInputEvents::OTHER_EVENT_FLAG; + + class BSInputEnableLayer + { + public: + constexpr BSInputEnableLayer() noexcept {} // NOLINT(modernize-use-equals-default) + + [[nodiscard]] std::uint32_t DecRef() const + { + using func_t = decltype(&BSInputEnableLayer::DecRef); + REL::Relocation func{ REL::ID(659989) }; + return func(this); + } + + std::uint32_t IncRef() const + { + stl::atomic_ref myRefCount{ refCount }; + return ++myRefCount; + } + + // members + std::uint32_t layerID; // 00 + mutable std::uint32_t refCount; // 04 + }; + static_assert(sizeof(BSInputEnableLayer) == 0x08); + + class BSInputEnableManager : + public BSTEventSource, // 000 + public BSTEventSource, // 058 + public BSTEventSource, // 0B0 + public BSTSingletonSDM // 108 + { + public: + struct EnableLayer + { + public: + // members + stl::enumeration inputUserEvents; // 00 + stl::enumeration otherInputEvents; // 04 + }; + static_assert(sizeof(EnableLayer) == 0x08); + + [[nodiscard]] static BSInputEnableManager* GetSingleton() + { + REL::Relocation singleton{ REL::ID(781703) }; + return *singleton; + } + + bool AllocateNewLayer(BSTSmartPointer& a_layer, const char* a_debugName) + { + using func_t = decltype(&BSInputEnableManager::AllocateNewLayer); + REL::Relocation func{ REL::ID(537494) }; + return func(this, a_layer, a_debugName); + } + + void ClearForcedState() + { + BSAutoLock locker(cacheLock); + forceEnableInputUserEventsFlags.reset(); + forceOtherInputEventsFlags.reset(); + } + + bool EnableUserEvent(std::uint32_t a_layerID, UEFlag a_userEventFlags, bool a_enable, UserEvents::SENDER_ID a_senderID) + { + using func_t = decltype(&BSInputEnableManager::EnableUserEvent); + REL::Relocation func{ REL::ID(1432984) }; + return func(this, a_layerID, a_userEventFlags, a_enable, a_senderID); + } + + bool EnableOtherEvent(std::uint32_t a_layerID, OEFlag a_otherEventFlags, bool a_enable, UserEvents::SENDER_ID a_senderID) + { + using func_t = decltype(&BSInputEnableManager::EnableOtherEvent); + REL::Relocation func{ REL::ID(1419268) }; + return func(this, a_layerID, a_otherEventFlags, a_enable, a_senderID); + } + + void ForceUserEventEnabled(UEFlag a_userEventFlags, bool a_enable) + { + BSAutoLock locker(cacheLock); + if (a_enable) { + forceEnableInputUserEventsFlags.set(a_userEventFlags); + } else { + forceEnableInputUserEventsFlags.reset(a_userEventFlags); + } + } + + void ForceOtherEventEnabled(OEFlag a_otherEventFlags, bool a_enable) + { + BSAutoLock locker(cacheLock); + if (a_enable) { + forceOtherInputEventsFlags.set(a_otherEventFlags); + } else { + forceOtherInputEventsFlags.reset(a_otherEventFlags); + } + } + + // members + BSSpinLock cacheLock; // 110 + stl::enumeration cachedInputUserEventsFlags; // 118 + stl::enumeration cachedOtherInputEventsFlags; // 11C + stl::enumeration forceEnableInputUserEventsFlags; // 120 + stl::enumeration forceOtherInputEventsFlags; // 124 + BSSpinLock layerLock; // 128 + BSTArray layers; // 130 + BSTArray> layerWrappers; // 148 + BSTArray debugNames; // 160 + bool isCurrentlyInSaveLoad; // 178 + }; + static_assert(sizeof(BSInputEnableManager) == 0x180); +} diff --git a/CommonLibF4/include/RE/Bethesda/ControlMap.h b/CommonLibF4/include/RE/Bethesda/ControlMap.h index 000273d1..6dd05e61 100644 --- a/CommonLibF4/include/RE/Bethesda/ControlMap.h +++ b/CommonLibF4/include/RE/Bethesda/ControlMap.h @@ -20,6 +20,13 @@ namespace RE public BSTSingletonSDM // 000 { public: + using InputContextID = UserEvents::INPUT_CONTEXT_ID; + + enum : std::uint32_t + { + kInvalid = static_cast(-1) + }; + struct UserEventMapping { public: @@ -59,6 +66,24 @@ namespace RE return *singleton; } + std::uint32_t GetMappedKey(std::string_view a_eventID, INPUT_DEVICE a_device, InputContextID a_context = InputContextID::kMainGameplay) const + { + assert(a_device < INPUT_DEVICE::kTotal); + assert(a_context < InputContextID::kTotal); + + if (controlMaps[stl::to_underlying(a_context)]) { + const auto& mappings = controlMaps[stl::to_underlying(a_context)]->deviceMappings[stl::to_underlying(a_device)]; + BSFixedString eventID(a_eventID); + for (auto& mapping : mappings) { + if (mapping.eventID == eventID) { + return mapping.inputKey; + } + } + } + + return kInvalid; + } + bool PopInputContext(UserEvents::INPUT_CONTEXT_ID a_context) { using func_t = decltype(&ControlMap::PopInputContext); diff --git a/CommonLibF4/include/RE/Bethesda/IMenu.h b/CommonLibF4/include/RE/Bethesda/IMenu.h index 704341f3..6d356d62 100644 --- a/CommonLibF4/include/RE/Bethesda/IMenu.h +++ b/CommonLibF4/include/RE/Bethesda/IMenu.h @@ -55,6 +55,7 @@ namespace RE class BSGFxShaderFXTarget; class ExamineMenu; class ExtraDataList; + class HUDComponentBase; class MenuOpenCloseEvent; class MessageBoxData; class NiAVObject; @@ -75,6 +76,7 @@ namespace RE struct PickRefUpdateEvent; struct PipboyValueChangedEvent; struct QueueSurvivalBumpDownMessage; + struct RequestHUDModesEvent; struct RevertPlayerCharacterEvent; struct SaveLoadMessageTypeEvent; struct UIAdvanceMenusFunctionCompleteEvent; @@ -859,6 +861,31 @@ namespace RE }; static_assert(sizeof(Console) == 0xF0); + struct __declspec(novtable) HUDMenu : + public GameMenuBase, // 000 + public BSTEventSink, // 0E0 + public BSTEventSink // 0E8 + { + public: + static constexpr auto RTTI{ RTTI::HUDMenu }; + static constexpr auto VTABLE{ VTABLE::HUDMenu }; + static constexpr auto MENU_NAME{ "HUDMenu"sv }; + + enum class ShowMenuState + { + kConstructed = 0, + kShown, + kHidden, + kReshowOnDestructor + }; + + // members + BSTSmallArray, 32> hudObjects; // 0F0 + BSTArray hudModes; // 200 + stl::enumeration hudShowMenuState; // 218 + }; + static_assert(sizeof(HUDMenu) == 0x220); + struct BaseLoadedInventoryModel { public: diff --git a/CommonLibF4/include/RE/Bethesda/InputEvent.h b/CommonLibF4/include/RE/Bethesda/InputEvent.h index 98fb8815..abd2dd99 100644 --- a/CommonLibF4/include/RE/Bethesda/InputEvent.h +++ b/CommonLibF4/include/RE/Bethesda/InputEvent.h @@ -31,6 +31,7 @@ namespace RE kBackspace = 0x08, kTab = 0x09, kEnter = 0x0D, + kPause = 0x13, kCapsLock = 0x14, kEscape = 0x1B, kSpace = 0x20, @@ -42,6 +43,7 @@ namespace RE kUp = 0x26, kRight = 0x27, kDown = 0x28, + kPrintScreen = 0x2C, kInsert = 0x2D, kDelete = 0x2E, k0 = 0x30, @@ -123,6 +125,8 @@ namespace RE kRControl = 0xA3, kLAlt = 0xA4, kRAlt = 0xA5, + kNumLock = 0x90, + kScrollLock = 0x91, kGamepad = 0x10000, kDPAD_Up = 0x10001, @@ -131,7 +135,8 @@ namespace RE kDPAD_Right = 0x10008, kLTrigger = 0x10009, kRTrigger = 0x1000A, - kSelect = 0x10020, + kStart = 0x10010, + kBack = 0x10020, kLStick = 0x10040, kRStick = 0x10080, kLShoulder = 0x10100, @@ -140,6 +145,9 @@ namespace RE kBButton = 0x12000, kXButton = 0x14000, kYButton = 0x18000, + + kWheelUp = 0x10800, + kWheelDown = 0x10900, }; class IDEvent; @@ -320,7 +328,9 @@ namespace RE [[nodiscard]] bool QHeldDown() const noexcept { return value != 0.0 && heldDownSecs > 0.0F; } [[nodiscard]] float QHeldDownSecs() const noexcept { return heldDownSecs; } [[nodiscard]] bool QJustPressed() const noexcept { return value != 0.0F && heldDownSecs == 0.0F; } + [[nodiscard]] bool QPressed() const noexcept { return value != 0.0F; } [[nodiscard]] bool QReleased(float a_heldDownSecs) const noexcept { return value == 0.0F && a_heldDownSecs <= heldDownSecs; } + [[nodiscard]] bool QReleased() const noexcept { return value == 0.0F && heldDownSecs > 0.0F; } // members float value{ 0.0F }; // 38 diff --git a/CommonLibF4/include/RE/Bethesda/Sky.h b/CommonLibF4/include/RE/Bethesda/Sky.h index 861acb7b..2f447019 100644 --- a/CommonLibF4/include/RE/Bethesda/Sky.h +++ b/CommonLibF4/include/RE/Bethesda/Sky.h @@ -73,8 +73,9 @@ namespace RE [[nodiscard]] static Sky* GetSingleton() { - REL::Relocation singleton{ REL::ID(484694) }; - return *singleton; + using func_t = decltype(&Sky::GetSingleton); + REL::Relocation func{ REL::ID(484694) }; + return func(); } void ForceWeather(TESWeather* a_weather, bool a_override) diff --git a/CommonLibF4/include/RE/Bethesda/UserEvents.h b/CommonLibF4/include/RE/Bethesda/UserEvents.h index 8f673ba1..35263b63 100644 --- a/CommonLibF4/include/RE/Bethesda/UserEvents.h +++ b/CommonLibF4/include/RE/Bethesda/UserEvents.h @@ -71,4 +71,6 @@ namespace RE kScript }; } + + using UEFlag = UserEvents::USER_EVENT_FLAG; } diff --git a/CommonLibF4/include/RE/Fallout.h b/CommonLibF4/include/RE/Fallout.h index 33b33f89..7643199d 100644 --- a/CommonLibF4/include/RE/Fallout.h +++ b/CommonLibF4/include/RE/Fallout.h @@ -40,6 +40,7 @@ #include "RE/Bethesda/BSGraphics.h" #include "RE/Bethesda/BSHavok.h" #include "RE/Bethesda/BSInputDeviceManager.h" +#include "RE/Bethesda/BSInputEnableManager.h" #include "RE/Bethesda/BSInputEventReceiver.h" #include "RE/Bethesda/BSInputEventSingleUser.h" #include "RE/Bethesda/BSInputEventUser.h" diff --git a/CommonLibF4/src/F4SE/InputMap.cpp b/CommonLibF4/src/F4SE/InputMap.cpp new file mode 100644 index 00000000..64618af8 --- /dev/null +++ b/CommonLibF4/src/F4SE/InputMap.cpp @@ -0,0 +1,192 @@ +#include "F4SE/InputMap.h" + +#include "F4SE/Impl/ScePadAPI.h" +#include "F4SE/Impl/XInputAPI.h" +#include "RE/Bethesda/ControlMap.h" + +namespace F4SE +{ + using XInputButton = RE::XInput::XInputButton; + using ScePadButton = RE::ScePad::ScePadButton; + + std::uint32_t InputMap::XInputToScePadOffset(std::uint32_t keyMask) + { + switch (keyMask) { + case XInputButton::XINPUT_GAMEPAD_DPAD_UP: + return ScePadButton::SCE_PAD_BUTTON_UP; + case XInputButton::XINPUT_GAMEPAD_DPAD_DOWN: + return ScePadButton::SCE_PAD_BUTTON_DOWN; + case XInputButton::XINPUT_GAMEPAD_DPAD_LEFT: + return ScePadButton::SCE_PAD_BUTTON_LEFT; + case XInputButton::XINPUT_GAMEPAD_DPAD_RIGHT: + return ScePadButton::SCE_PAD_BUTTON_RIGHT; + case XInputButton::XINPUT_GAMEPAD_START: + return ScePadButton::SCE_PAD_BUTTON_OPTIONS; + case XInputButton::XINPUT_GAMEPAD_BACK: + return ScePadButton::SCE_PAD_BUTTON_TOUCH_PAD; + case XInputButton::XINPUT_GAMEPAD_LEFT_THUMB: + return ScePadButton::SCE_PAD_BUTTON_L3; + case XInputButton::XINPUT_GAMEPAD_RIGHT_THUMB: + return ScePadButton::SCE_PAD_BUTTON_R3; + case XInputButton::XINPUT_GAMEPAD_LEFT_SHOULDER: + return ScePadButton::SCE_PAD_BUTTON_L1; + case XInputButton::XINPUT_GAMEPAD_RIGHT_SHOULDER: + return ScePadButton::SCE_PAD_BUTTON_R1; + case XInputButton::XINPUT_GAMEPAD_A: + return ScePadButton::SCE_PAD_BUTTON_CROSS; + case XInputButton::XINPUT_GAMEPAD_B: + return ScePadButton::SCE_PAD_BUTTON_CIRCLE; + case XInputButton::XINPUT_GAMEPAD_X: + return ScePadButton::SCE_PAD_BUTTON_SQUARE; + case XInputButton::XINPUT_GAMEPAD_Y: + return ScePadButton::SCE_PAD_BUTTON_TRIANGLE; + default: + return keyMask; + } + } + + std::uint32_t InputMap::ScePadOffsetToXInput(std::uint32_t keyMask) + { + switch (keyMask) { + case ScePadButton::SCE_PAD_BUTTON_UP: + return XInputButton::XINPUT_GAMEPAD_DPAD_UP; + case ScePadButton::SCE_PAD_BUTTON_DOWN: + return XInputButton::XINPUT_GAMEPAD_DPAD_DOWN; + case ScePadButton::SCE_PAD_BUTTON_LEFT: + return XInputButton::XINPUT_GAMEPAD_DPAD_LEFT; + case ScePadButton::SCE_PAD_BUTTON_RIGHT: + return XInputButton::XINPUT_GAMEPAD_DPAD_RIGHT; + case ScePadButton::SCE_PAD_BUTTON_OPTIONS: + return XInputButton::XINPUT_GAMEPAD_START; + case ScePadButton::SCE_PAD_BUTTON_TOUCH_PAD: + return XInputButton::XINPUT_GAMEPAD_BACK; + case ScePadButton::SCE_PAD_BUTTON_L3: + return XInputButton::XINPUT_GAMEPAD_LEFT_THUMB; + case ScePadButton::SCE_PAD_BUTTON_R3: + return XInputButton::XINPUT_GAMEPAD_RIGHT_THUMB; + case ScePadButton::SCE_PAD_BUTTON_L1: + return XInputButton::XINPUT_GAMEPAD_LEFT_SHOULDER; + case ScePadButton::SCE_PAD_BUTTON_R1: + return XInputButton::XINPUT_GAMEPAD_RIGHT_SHOULDER; + case ScePadButton::SCE_PAD_BUTTON_CROSS: + return XInputButton::XINPUT_GAMEPAD_A; + case ScePadButton::SCE_PAD_BUTTON_CIRCLE: + return XInputButton::XINPUT_GAMEPAD_B; + case ScePadButton::SCE_PAD_BUTTON_SQUARE: + return XInputButton::XINPUT_GAMEPAD_X; + case ScePadButton::SCE_PAD_BUTTON_TRIANGLE: + return XInputButton::XINPUT_GAMEPAD_Y; + default: + return keyMask; + } + } + + std::uint32_t InputMap::GamepadMaskToKeycode(std::uint32_t keyMask) + { + if (RE::ControlMap::GetSingleton()->pcGamePadMapType == RE::PC_GAMEPAD_TYPE::kOrbis) { + keyMask = ScePadOffsetToXInput(keyMask); + } + + switch (keyMask) { + case XInputButton::XINPUT_GAMEPAD_DPAD_UP: + return kGamepadButtonOffset_DPAD_UP; + case XInputButton::XINPUT_GAMEPAD_DPAD_DOWN: + return kGamepadButtonOffset_DPAD_DOWN; + case XInputButton::XINPUT_GAMEPAD_DPAD_LEFT: + return kGamepadButtonOffset_DPAD_LEFT; + case XInputButton::XINPUT_GAMEPAD_DPAD_RIGHT: + return kGamepadButtonOffset_DPAD_RIGHT; + case XInputButton::XINPUT_GAMEPAD_START: + return kGamepadButtonOffset_START; + case XInputButton::XINPUT_GAMEPAD_BACK: + return kGamepadButtonOffset_BACK; + case XInputButton::XINPUT_GAMEPAD_LEFT_THUMB: + return kGamepadButtonOffset_LEFT_THUMB; + case XInputButton::XINPUT_GAMEPAD_RIGHT_THUMB: + return kGamepadButtonOffset_RIGHT_THUMB; + case XInputButton::XINPUT_GAMEPAD_LEFT_SHOULDER: + return kGamepadButtonOffset_LEFT_SHOULDER; + case XInputButton::XINPUT_GAMEPAD_RIGHT_SHOULDER: + return kGamepadButtonOffset_RIGHT_SHOULDER; + case XInputButton::XINPUT_GAMEPAD_A: + return kGamepadButtonOffset_A; + case XInputButton::XINPUT_GAMEPAD_B: + return kGamepadButtonOffset_B; + case XInputButton::XINPUT_GAMEPAD_X: + return kGamepadButtonOffset_X; + case XInputButton::XINPUT_GAMEPAD_Y: + return kGamepadButtonOffset_Y; + case 0x9: // Left Trigger game-defined ID + return kGamepadButtonOffset_LT; + case 0xA: // Right Trigger game-defined ID + return kGamepadButtonOffset_RT; + default: + return kMaxMacros; // Invalid + } + } + + std::uint32_t InputMap::GamepadKeycodeToMask(std::uint32_t keyCode) + { + std::uint32_t keyMask; + + switch (keyCode) { + case kGamepadButtonOffset_DPAD_UP: + keyMask = XInputButton::XINPUT_GAMEPAD_DPAD_UP; + break; + case kGamepadButtonOffset_DPAD_DOWN: + keyMask = XInputButton::XINPUT_GAMEPAD_DPAD_DOWN; + break; + case kGamepadButtonOffset_DPAD_LEFT: + keyMask = XInputButton::XINPUT_GAMEPAD_DPAD_LEFT; + break; + case kGamepadButtonOffset_DPAD_RIGHT: + keyMask = XInputButton::XINPUT_GAMEPAD_DPAD_RIGHT; + break; + case kGamepadButtonOffset_START: + keyMask = XInputButton::XINPUT_GAMEPAD_START; + break; + case kGamepadButtonOffset_BACK: + keyMask = XInputButton::XINPUT_GAMEPAD_BACK; + break; + case kGamepadButtonOffset_LEFT_THUMB: + keyMask = XInputButton::XINPUT_GAMEPAD_LEFT_THUMB; + break; + case kGamepadButtonOffset_RIGHT_THUMB: + keyMask = XInputButton::XINPUT_GAMEPAD_RIGHT_THUMB; + break; + case kGamepadButtonOffset_LEFT_SHOULDER: + keyMask = XInputButton::XINPUT_GAMEPAD_LEFT_SHOULDER; + break; + case kGamepadButtonOffset_RIGHT_SHOULDER: + keyMask = XInputButton::XINPUT_GAMEPAD_RIGHT_SHOULDER; + break; + case kGamepadButtonOffset_A: + keyMask = XInputButton::XINPUT_GAMEPAD_A; + break; + case kGamepadButtonOffset_B: + keyMask = XInputButton::XINPUT_GAMEPAD_B; + break; + case kGamepadButtonOffset_X: + keyMask = XInputButton::XINPUT_GAMEPAD_X; + break; + case kGamepadButtonOffset_Y: + keyMask = XInputButton::XINPUT_GAMEPAD_Y; + break; + case kGamepadButtonOffset_LT: + keyMask = 0x9; // Left Trigger game-defined ID + break; + case kGamepadButtonOffset_RT: + keyMask = 0xA; // Right Trigger game-defined ID + break; + default: + keyMask = 0xFF; // Invalid + break; + } + + if (RE::ControlMap::GetSingleton()->pcGamePadMapType == RE::PC_GAMEPAD_TYPE::kOrbis) { + keyMask = XInputToScePadOffset(keyMask); + } + + return keyMask; + } +} From aec1ba5ad75b935c39aeaed1b9739475cf69decc Mon Sep 17 00:00:00 2001 From: powerof3 Date: Wed, 15 May 2024 02:24:18 +0000 Subject: [PATCH 2/5] maintenance --- CommonLibF4/include/F4SE/Impl/PCH.h | 50 +++++++++---------- CommonLibF4/include/RE/Bethesda/BSLock.h | 2 +- .../include/RE/Bethesda/BSShaderProperty.h | 2 +- CommonLibF4/include/RE/Bethesda/ControlMap.h | 2 +- CommonLibF4/include/RE/Bethesda/Events.h | 10 ++-- .../include/RE/Bethesda/ImageSpaceEffect.h | 12 ++--- .../include/RE/Bethesda/ImageSpaceModifier.h | 2 +- .../RE/Bethesda/ReferenceEffectController.h | 2 +- CommonLibF4/include/RE/Bethesda/TESForms.h | 4 +- .../include/RE/Bethesda/TESObjectREFRs.h | 22 ++++---- .../RE/Bethesda/bhkCharacterController.h | 2 +- ExampleProject/src/main.cpp | 9 +--- 12 files changed, 57 insertions(+), 62 deletions(-) diff --git a/CommonLibF4/include/F4SE/Impl/PCH.h b/CommonLibF4/include/F4SE/Impl/PCH.h index e3ae961b..4ac9332a 100644 --- a/CommonLibF4/include/F4SE/Impl/PCH.h +++ b/CommonLibF4/include/F4SE/Impl/PCH.h @@ -96,13 +96,14 @@ namespace F4SE requires( const K& a_transparent, const typename C::key_type& a_key, - typename C::key_compare& a_compare) { - typename C::key_compare::is_transparent; - // clang-format off + typename C::key_compare& a_compare) + { + typename C::key_compare::is_transparent; + // clang-format off { a_compare(a_transparent, a_key) } -> std::convertible_to; { a_compare(a_key, a_transparent) } -> std::convertible_to; - // clang-format on - }; + // clang-format on + }; namespace nttp { @@ -142,9 +143,9 @@ namespace F4SE string(const CharT (&)[N]) -> string; } - template // - requires(std::invocable>) // - class scope_exit + template // + requires(std::invocable>) // + class scope_exit { public: // 1) @@ -288,8 +289,7 @@ namespace F4SE template constexpr enumeration(Args... a_values) noexcept // - requires(std::same_as && ...) - : + requires(std::same_as&&...) : _impl((static_cast(a_values) | ...)) {} @@ -318,7 +318,7 @@ namespace F4SE template constexpr enumeration& set(Args... a_args) noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { _impl |= (static_cast(a_args) | ...); return *this; @@ -326,7 +326,7 @@ namespace F4SE template constexpr enumeration& reset(Args... a_args) noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { _impl &= ~(static_cast(a_args) | ...); return *this; @@ -340,21 +340,21 @@ namespace F4SE template [[nodiscard]] constexpr bool any(Args... a_args) const noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { return (_impl & (static_cast(a_args) | ...)) != static_cast(0); } template [[nodiscard]] constexpr bool all(Args... a_args) const noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { return (_impl & (static_cast(a_args) | ...)) == (static_cast(a_args) | ...); } template [[nodiscard]] constexpr bool none(Args... a_args) const noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { return (_impl & (static_cast(a_args) | ...)) == static_cast(0); } @@ -387,14 +387,14 @@ namespace F4SE #define F4SE_MAKE_ARITHMETIC_OP(a_op) \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_enum, U a_shift) noexcept \ - -> enumeration \ + ->enumeration \ { \ return static_cast(static_cast(a_enum.get()) a_op a_shift); \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_enum, U a_shift) noexcept \ - -> enumeration& \ + ->enumeration& \ { \ return a_enum = a_enum a_op a_shift; \ } @@ -402,42 +402,42 @@ namespace F4SE #define F4SE_MAKE_ENUMERATION_OP(a_op) \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_lhs, enumeration a_rhs) noexcept \ - -> enumeration> \ + ->enumeration> \ { \ return static_cast(static_cast(a_lhs.get()) a_op static_cast(a_rhs.get())); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_lhs, E a_rhs) noexcept \ - -> enumeration \ + ->enumeration \ { \ return static_cast(static_cast(a_lhs.get()) a_op static_cast(a_rhs)); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op(E a_lhs, enumeration a_rhs) noexcept \ - -> enumeration \ + ->enumeration \ { \ return static_cast(static_cast(a_lhs) a_op static_cast(a_rhs.get())); \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_lhs, enumeration a_rhs) noexcept \ - -> enumeration& \ + ->enumeration& \ { \ return a_lhs = a_lhs a_op a_rhs; \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_lhs, E a_rhs) noexcept \ - -> enumeration& \ + ->enumeration& \ { \ return a_lhs = a_lhs a_op a_rhs; \ } \ \ template \ constexpr auto operator a_op##=(E& a_lhs, enumeration a_rhs) noexcept \ - -> E& \ + ->E& \ { \ return a_lhs = *(a_lhs a_op a_rhs); \ } @@ -445,14 +445,14 @@ namespace F4SE #define F4SE_MAKE_INCREMENTER_OP(a_op) \ template \ constexpr auto operator a_op##a_op(enumeration& a_lhs) noexcept \ - -> enumeration& \ + ->enumeration& \ { \ return a_lhs a_op## = static_cast(1); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op##a_op(enumeration& a_lhs, int) noexcept \ - -> enumeration \ + ->enumeration \ { \ const auto tmp = a_lhs; \ a_op##a_op a_lhs; \ diff --git a/CommonLibF4/include/RE/Bethesda/BSLock.h b/CommonLibF4/include/RE/Bethesda/BSLock.h index bbd95a09..55e5f290 100644 --- a/CommonLibF4/include/RE/Bethesda/BSLock.h +++ b/CommonLibF4/include/RE/Bethesda/BSLock.h @@ -9,7 +9,7 @@ namespace RE WinAPI::CRITICAL_SECTION criticalSection; // 00 }; static_assert(sizeof(BSCriticalSection) == 0x28); - + class BSNonReentrantSpinLock { public: diff --git a/CommonLibF4/include/RE/Bethesda/BSShaderProperty.h b/CommonLibF4/include/RE/Bethesda/BSShaderProperty.h index 2f86c1ed..c3dfd3c5 100644 --- a/CommonLibF4/include/RE/Bethesda/BSShaderProperty.h +++ b/CommonLibF4/include/RE/Bethesda/BSShaderProperty.h @@ -35,7 +35,7 @@ namespace RE kMultilayer, kBacklightMask, kSmoothSpec = kBacklightMask, - + kTotal, }; diff --git a/CommonLibF4/include/RE/Bethesda/ControlMap.h b/CommonLibF4/include/RE/Bethesda/ControlMap.h index 6dd05e61..87444379 100644 --- a/CommonLibF4/include/RE/Bethesda/ControlMap.h +++ b/CommonLibF4/include/RE/Bethesda/ControlMap.h @@ -26,7 +26,7 @@ namespace RE { kInvalid = static_cast(-1) }; - + struct UserEventMapping { public: diff --git a/CommonLibF4/include/RE/Bethesda/Events.h b/CommonLibF4/include/RE/Bethesda/Events.h index 533f608a..2a6784f0 100644 --- a/CommonLibF4/include/RE/Bethesda/Events.h +++ b/CommonLibF4/include/RE/Bethesda/Events.h @@ -576,7 +576,7 @@ namespace RE REL::Relocation func{ REL::ID(1251703) }; return func(); } - + // members NiPointer actor; // 00 std::uint32_t baseObject; // 08 @@ -609,7 +609,7 @@ namespace RE }; static_assert(sizeof(TESFurnitureEvent) == 0x18); - struct DamageImpactData + struct DamageImpactData { public: // members @@ -689,7 +689,7 @@ namespace RE REL::Relocation func{ REL::ID(1411899) }; return func(); } - + // members HitData hitData; // 000 NiPointer target; // 0E0 @@ -710,7 +710,7 @@ namespace RE REL::Relocation func{ REL::ID(1327824) }; return func(); } - + // members NiPointer target; // 00 NiPointer caster; // 08 @@ -727,7 +727,7 @@ namespace RE REL::Relocation func{ REL::ID(609604) }; return func(); } - + // members std::uint32_t formId; // 00 bool loaded; // 04 diff --git a/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h b/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h index 6e654644..43cd8727 100644 --- a/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h +++ b/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h @@ -101,7 +101,7 @@ namespace RE static_assert(sizeof(ImageSpaceEffectOption) == 0xC8); class __declspec(novtable) ImageSpaceEffectFullScreenBlur : - public ImageSpaceEffect // 00 + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectFullScreenBlur }; @@ -125,7 +125,7 @@ namespace RE static_assert(sizeof(ImageSpaceEffectFullScreenBlur) == 0x128); class __declspec(novtable) ImageSpaceEffectGetHit : - public ImageSpaceEffect // 00 + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectGetHit }; @@ -150,7 +150,7 @@ namespace RE static_assert(sizeof(ImageSpaceEffectGetHit) == 0x108); class __declspec(novtable) ImageSpaceEffectMotionBlur : - public ImageSpaceEffect // 00 + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectMotionBlur }; @@ -166,7 +166,7 @@ namespace RE static_assert(sizeof(ImageSpaceEffectMotionBlur) == 0xB0); class __declspec(novtable) ImageSpaceEffectPipboyScreen : - public ImageSpaceEffect // 00 + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectPipboyScreen }; @@ -188,7 +188,7 @@ namespace RE static_assert(sizeof(ImageSpaceEffectPipboyScreen) == 0xC0); class __declspec(novtable) ImageSpaceEffectRadialBlur : - public ImageSpaceEffect // 00 + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectRadialBlur }; @@ -206,7 +206,7 @@ namespace RE static_assert(sizeof(ImageSpaceEffectRadialBlur) == 0xB0); class __declspec(novtable) ImageSpaceEffectTemporalAA : - public ImageSpaceEffect // 00 + public ImageSpaceEffect // 00 { public: static constexpr auto RTTI{ RTTI::ImageSpaceEffectTemporalAA }; diff --git a/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h b/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h index 93bd3a6d..9af84ce7 100644 --- a/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h +++ b/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h @@ -74,7 +74,7 @@ namespace RE static void Stop(TESImageSpaceModifier* a_mod) { - using func_t = void (*)(TESImageSpaceModifier* ); + using func_t = void (*)(TESImageSpaceModifier*); REL::Relocation func{ REL::ID(217873) }; return func(a_mod); } diff --git a/CommonLibF4/include/RE/Bethesda/ReferenceEffectController.h b/CommonLibF4/include/RE/Bethesda/ReferenceEffectController.h index 07e20464..58d8245d 100644 --- a/CommonLibF4/include/RE/Bethesda/ReferenceEffectController.h +++ b/CommonLibF4/include/RE/Bethesda/ReferenceEffectController.h @@ -105,7 +105,7 @@ namespace RE public: static constexpr auto RTTI{ RTTI::SkyEffectController }; static constexpr auto VTABLE{ VTABLE::SkyEffectController }; - + // override (ReferenceEffectController) void RemoveHitEffect(ReferenceEffect* a_refEffect) override; // 0A - { return; } TESObjectREFR* GetTargetReference() override; // 0B - { return g_thePlayer; } diff --git a/CommonLibF4/include/RE/Bethesda/TESForms.h b/CommonLibF4/include/RE/Bethesda/TESForms.h index 2a117361..8dd626ff 100644 --- a/CommonLibF4/include/RE/Bethesda/TESForms.h +++ b/CommonLibF4/include/RE/Bethesda/TESForms.h @@ -822,7 +822,7 @@ namespace RE template [[nodiscard]] bool Is(Args... a_args) const noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { return (Is(a_args) || ...); } @@ -846,7 +846,7 @@ namespace RE template [[nodiscard]] bool IsNot(Args... a_args) const noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { return (IsNot(a_args) && ...); } diff --git a/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h b/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h index 9d9adfa7..87c2f39e 100644 --- a/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h +++ b/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h @@ -685,12 +685,12 @@ namespace RE } ModelReferenceEffect* ApplyArtObject( - BGSArtObject* a_art, - float a_time = -1.0f, - TESObjectREFR* a_facingRef = nullptr, - bool a_attachToCamera = false, - bool a_inheritRotation = false, - NiAVObject* a_3D = nullptr, + BGSArtObject* a_art, + float a_time = -1.0f, + TESObjectREFR* a_facingRef = nullptr, + bool a_attachToCamera = false, + bool a_inheritRotation = false, + NiAVObject* a_3D = nullptr, bool a_interfaceEffect = false) { using func_t = decltype(&TESObjectREFR::ApplyArtObject); @@ -699,12 +699,12 @@ namespace RE } ShaderReferenceEffect* ApplyEffectShader( - TESEffectShader* a_art, + TESEffectShader* a_art, float a_time = -1.0f, - TESObjectREFR* a_facingRef = nullptr, + TESObjectREFR* a_facingRef = nullptr, bool a_attachToCamera = false, - bool a_inheritRotation = false, - NiAVObject* a_3D = nullptr, + bool a_inheritRotation = false, + NiAVObject* a_3D = nullptr, bool a_interfaceEffect = false) { using func_t = decltype(&TESObjectREFR::ApplyEffectShader); @@ -737,7 +737,7 @@ namespace RE REL::Relocation func{ REL::ID(1135470) }; return func(this); } - + [[nodiscard]] const char* GetDisplayFullName() { using func_t = decltype(&TESObjectREFR::GetDisplayFullName); diff --git a/CommonLibF4/include/RE/Bethesda/bhkCharacterController.h b/CommonLibF4/include/RE/Bethesda/bhkCharacterController.h index 97a43eb5..4e0f3ec5 100644 --- a/CommonLibF4/include/RE/Bethesda/bhkCharacterController.h +++ b/CommonLibF4/include/RE/Bethesda/bhkCharacterController.h @@ -35,7 +35,7 @@ namespace RE struct DamageImpactData; struct MoveData; - + class hknpMotionPropertiesId { public: diff --git a/ExampleProject/src/main.cpp b/ExampleProject/src/main.cpp index bdc1f7f7..ca8aced2 100644 --- a/ExampleProject/src/main.cpp +++ b/ExampleProject/src/main.cpp @@ -44,11 +44,9 @@ extern "C" DLLEXPORT bool F4SEAPI F4SEPlugin_Query(const F4SE::QueryInterface* a return true; } - void MessageCallback(F4SE::MessagingInterface::Message* msg) { - switch (msg->type) - { + switch (msg->type) { case F4SE::MessagingInterface::kGameDataReady: break; case F4SE::MessagingInterface::kNewGame: @@ -58,18 +56,15 @@ void MessageCallback(F4SE::MessagingInterface::Message* msg) default: break; } - } - extern "C" DLLEXPORT bool F4SEAPI F4SEPlugin_Load(const F4SE::LoadInterface* a_f4se) { F4SE::Init(a_f4se); logger::info("hello world!"); - if (!F4SE::GetMessagingInterface()->RegisterListener(MessageCallback)) - { + if (!F4SE::GetMessagingInterface()->RegisterListener(MessageCallback)) { logger::info("Cannot register listener!"); return false; } From a0ece28cbbf3100a7d4d877225897777bf51a887 Mon Sep 17 00:00:00 2001 From: powerof3 <32599957+powerof3@users.noreply.github.com> Date: Sun, 19 May 2024 01:44:27 +0530 Subject: [PATCH 3/5] update InputMap --- CommonLibF4/cmake/sourcelist.cmake | 5 +- CommonLibF4/include/F4SE/Impl/ScePadAPI.h | 30 ---- CommonLibF4/include/F4SE/Impl/XInputAPI.h | 77 -------- CommonLibF4/include/RE/Bethesda/ControlMap.h | 4 +- CommonLibF4/include/REX/PS4.h | 3 + CommonLibF4/include/REX/PS4/SCEPAD.h | 27 +++ CommonLibF4/src/F4SE/InputMap.cpp | 178 +++++++++---------- 7 files changed, 124 insertions(+), 200 deletions(-) delete mode 100644 CommonLibF4/include/F4SE/Impl/ScePadAPI.h delete mode 100644 CommonLibF4/include/F4SE/Impl/XInputAPI.h create mode 100644 CommonLibF4/include/REX/PS4.h create mode 100644 CommonLibF4/include/REX/PS4/SCEPAD.h diff --git a/CommonLibF4/cmake/sourcelist.cmake b/CommonLibF4/cmake/sourcelist.cmake index d2130377..3a68b4c0 100644 --- a/CommonLibF4/cmake/sourcelist.cmake +++ b/CommonLibF4/cmake/sourcelist.cmake @@ -2,7 +2,6 @@ set(SOURCES include/F4SE/API.h include/F4SE/F4SE.h include/F4SE/Impl/PCH.h - include/F4SE/Impl/XInputAPI.h include/F4SE/InputMap.h include/F4SE/Interfaces.h include/F4SE/Logger.h @@ -356,6 +355,8 @@ set(SOURCES include/REL/Relocation.h include/REL/Segment.h include/REL/Version.h + include/REX/PS4.h + include/REX/PS4/SCEPAD.h include/REX/W32.h include/REX/W32/ADVAPI32.h include/REX/W32/BASE.h @@ -385,7 +386,7 @@ set(SOURCES include/REX/W32/XINPUT.h src/F4SE/API.cpp src/F4SE/Impl/PCH.cpp - src/F4SE/Impl/WinAPI.cpp + src/F4SE/InputMap.cpp src/F4SE/Interfaces.cpp src/F4SE/Logger.cpp src/F4SE/Trampoline.cpp diff --git a/CommonLibF4/include/F4SE/Impl/ScePadAPI.h b/CommonLibF4/include/F4SE/Impl/ScePadAPI.h deleted file mode 100644 index c7991870..00000000 --- a/CommonLibF4/include/F4SE/Impl/ScePadAPI.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -namespace RE -{ - namespace ScePad - { - enum ScePadButton : std::uint32_t - { - SCE_PAD_BUTTON_SHARE = 0x00000001, - SCE_PAD_BUTTON_L3 = 0x00000002, - SCE_PAD_BUTTON_R3 = 0x00000004, - SCE_PAD_BUTTON_OPTIONS = 0x00000008, - SCE_PAD_BUTTON_UP = 0x00000010, - SCE_PAD_BUTTON_RIGHT = 0x00000020, - SCE_PAD_BUTTON_DOWN = 0x00000040, - SCE_PAD_BUTTON_LEFT = 0x00000080, - SCE_PAD_BUTTON_L2 = 0x00000100, - SCE_PAD_BUTTON_R2 = 0x00000200, - SCE_PAD_BUTTON_L1 = 0x00000400, - SCE_PAD_BUTTON_R1 = 0x00000800, - SCE_PAD_BUTTON_TRIANGLE = 0x00001000, - SCE_PAD_BUTTON_CIRCLE = 0x00002000, - SCE_PAD_BUTTON_CROSS = 0x00004000, - SCE_PAD_BUTTON_SQUARE = 0x00008000, - SCE_PAD_BUTTON_PLAYSTATION = 0x0010000, - SCE_PAD_BUTTON_TOUCH_PAD = 0x00100000, - SCE_PAD_BUTTON_INTERCEPTED = 0x80000000, - }; - } -} diff --git a/CommonLibF4/include/F4SE/Impl/XInputAPI.h b/CommonLibF4/include/F4SE/Impl/XInputAPI.h deleted file mode 100644 index 8f0b50af..00000000 --- a/CommonLibF4/include/F4SE/Impl/XInputAPI.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once - -namespace RE -{ - namespace XInput - { - struct __XINPUT_GAMEPAD - { - std::uint16_t wButtons; - std::byte bLeftTrigger; - std::byte bRightTrigger; - std::int16_t sThumbLX; - std::int16_t sThumbLY; - std::int16_t sThumbRX; - std::int16_t sThumbRY; - }; - using XINPUT_GAMEPAD = __XINPUT_GAMEPAD; - - struct __XINPUT_STATE - { - std::uint32_t dwPacketNumber; - __XINPUT_GAMEPAD Gamepad; - }; - using XINPUT_STATE = __XINPUT_STATE; - - struct __XINPUT_KEYSTROKE - { - std::uint16_t VirtualKey; - std::uint16_t Unicode; - std::uint16_t Flags; - std::uint8_t UserIndex; - std::uint8_t HidCode; - }; - using XINPUT_KEYSTROKE = __XINPUT_KEYSTROKE; - - struct __XINPUT_VIBRATION - { - std::uint16_t wLeftMotorSpeed; - std::uint16_t wRightMotorSpeed; - }; - using XINPUT_VIBRATION = __XINPUT_VIBRATION; - - struct __XINPUT_CAPABILITIES - { - std::uint8_t Type; - std::uint8_t SubType; - std::uint16_t Flags; - XINPUT_GAMEPAD Gamepad; - XINPUT_VIBRATION Vibration; - }; - using XINPUT_CAPABILITIES = __XINPUT_CAPABILITIES; - - enum XInputButton : std::uint16_t - { - XINPUT_GAMEPAD_DPAD_UP = 0x0001, - XINPUT_GAMEPAD_DPAD_DOWN = 0x0002, - XINPUT_GAMEPAD_DPAD_LEFT = 0x0004, - XINPUT_GAMEPAD_DPAD_RIGHT = 0x0008, - XINPUT_GAMEPAD_START = 0x0010, - XINPUT_GAMEPAD_BACK = 0x0020, - XINPUT_GAMEPAD_LEFT_THUMB = 0x0040, - XINPUT_GAMEPAD_RIGHT_THUMB = 0x0080, - XINPUT_GAMEPAD_LEFT_SHOULDER = 0x0100, - XINPUT_GAMEPAD_RIGHT_SHOULDER = 0x0200, - XINPUT_GAMEPAD_A = 0x1000, - XINPUT_GAMEPAD_B = 0x2000, - XINPUT_GAMEPAD_X = 0x4000, - XINPUT_GAMEPAD_Y = 0x8000 - }; - - static constexpr std::uint16_t XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE = 7849; - static constexpr std::uint16_t XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE = 8689; - static constexpr std::uint8_t XINPUT_GAMEPAD_TRIGGER_THRESHOLD = 30; - - static constexpr std::uint16_t XINPUT_BUTTON_MASK = XINPUT_GAMEPAD_DPAD_UP | XINPUT_GAMEPAD_DPAD_DOWN | XINPUT_GAMEPAD_DPAD_LEFT | XINPUT_GAMEPAD_DPAD_RIGHT | XINPUT_GAMEPAD_START | XINPUT_GAMEPAD_BACK | XINPUT_GAMEPAD_LEFT_THUMB | XINPUT_GAMEPAD_RIGHT_THUMB | XINPUT_GAMEPAD_LEFT_SHOULDER | XINPUT_GAMEPAD_RIGHT_SHOULDER | XINPUT_GAMEPAD_A | XINPUT_GAMEPAD_B | XINPUT_GAMEPAD_X | XINPUT_GAMEPAD_Y; - } -} diff --git a/CommonLibF4/include/RE/Bethesda/ControlMap.h b/CommonLibF4/include/RE/Bethesda/ControlMap.h index 73826dff..ff3b1733 100644 --- a/CommonLibF4/include/RE/Bethesda/ControlMap.h +++ b/CommonLibF4/include/RE/Bethesda/ControlMap.h @@ -71,8 +71,8 @@ namespace RE assert(a_device < INPUT_DEVICE::kTotal); assert(a_context < InputContextID::kTotal); - if (controlMaps[stl::to_underlying(a_context)]) { - const auto& mappings = controlMaps[stl::to_underlying(a_context)]->deviceMappings[stl::to_underlying(a_device)]; + if (controlMaps[std::to_underlying(a_context)]) { + const auto& mappings = controlMaps[std::to_underlying(a_context)]->deviceMappings[std::to_underlying(a_device)]; BSFixedString eventID(a_eventID); for (auto& mapping : mappings) { if (mapping.eventID == eventID) { diff --git a/CommonLibF4/include/REX/PS4.h b/CommonLibF4/include/REX/PS4.h new file mode 100644 index 00000000..8d7b0f3f --- /dev/null +++ b/CommonLibF4/include/REX/PS4.h @@ -0,0 +1,3 @@ +#pragma once + +#include "REX/PS4/SCEPAD.h" diff --git a/CommonLibF4/include/REX/PS4/SCEPAD.h b/CommonLibF4/include/REX/PS4/SCEPAD.h new file mode 100644 index 00000000..fa88dfc2 --- /dev/null +++ b/CommonLibF4/include/REX/PS4/SCEPAD.h @@ -0,0 +1,27 @@ +#pragma once + +namespace REX::PS4 +{ + enum SCE_PAD_BUTTON : std::uint32_t + { + SCE_PAD_BUTTON_SHARE = 0x00000001, + SCE_PAD_BUTTON_L3 = 0x00000002, + SCE_PAD_BUTTON_R3 = 0x00000004, + SCE_PAD_BUTTON_OPTIONS = 0x00000008, + SCE_PAD_BUTTON_UP = 0x00000010, + SCE_PAD_BUTTON_RIGHT = 0x00000020, + SCE_PAD_BUTTON_DOWN = 0x00000040, + SCE_PAD_BUTTON_LEFT = 0x00000080, + SCE_PAD_BUTTON_L2 = 0x00000100, + SCE_PAD_BUTTON_R2 = 0x00000200, + SCE_PAD_BUTTON_L1 = 0x00000400, + SCE_PAD_BUTTON_R1 = 0x00000800, + SCE_PAD_BUTTON_TRIANGLE = 0x00001000, + SCE_PAD_BUTTON_CIRCLE = 0x00002000, + SCE_PAD_BUTTON_CROSS = 0x00004000, + SCE_PAD_BUTTON_SQUARE = 0x00008000, + SCE_PAD_BUTTON_PLAYSTATION = 0x00010000, + SCE_PAD_BUTTON_TOUCH_PAD = 0x00100000, + SCE_PAD_BUTTON_INTERCEPTED = 0x80000000, + }; +} diff --git a/CommonLibF4/src/F4SE/InputMap.cpp b/CommonLibF4/src/F4SE/InputMap.cpp index 64618af8..24772bbd 100644 --- a/CommonLibF4/src/F4SE/InputMap.cpp +++ b/CommonLibF4/src/F4SE/InputMap.cpp @@ -1,45 +1,45 @@ #include "F4SE/InputMap.h" -#include "F4SE/Impl/ScePadAPI.h" -#include "F4SE/Impl/XInputAPI.h" #include "RE/Bethesda/ControlMap.h" +#include "REX/PS4/SCEPAD.h" +#include "REX/W32/DINPUT.h" +#include "REX/W32/USER32.h" +#include "REX/W32/XINPUT.h" + namespace F4SE { - using XInputButton = RE::XInput::XInputButton; - using ScePadButton = RE::ScePad::ScePadButton; - std::uint32_t InputMap::XInputToScePadOffset(std::uint32_t keyMask) { switch (keyMask) { - case XInputButton::XINPUT_GAMEPAD_DPAD_UP: - return ScePadButton::SCE_PAD_BUTTON_UP; - case XInputButton::XINPUT_GAMEPAD_DPAD_DOWN: - return ScePadButton::SCE_PAD_BUTTON_DOWN; - case XInputButton::XINPUT_GAMEPAD_DPAD_LEFT: - return ScePadButton::SCE_PAD_BUTTON_LEFT; - case XInputButton::XINPUT_GAMEPAD_DPAD_RIGHT: - return ScePadButton::SCE_PAD_BUTTON_RIGHT; - case XInputButton::XINPUT_GAMEPAD_START: - return ScePadButton::SCE_PAD_BUTTON_OPTIONS; - case XInputButton::XINPUT_GAMEPAD_BACK: - return ScePadButton::SCE_PAD_BUTTON_TOUCH_PAD; - case XInputButton::XINPUT_GAMEPAD_LEFT_THUMB: - return ScePadButton::SCE_PAD_BUTTON_L3; - case XInputButton::XINPUT_GAMEPAD_RIGHT_THUMB: - return ScePadButton::SCE_PAD_BUTTON_R3; - case XInputButton::XINPUT_GAMEPAD_LEFT_SHOULDER: - return ScePadButton::SCE_PAD_BUTTON_L1; - case XInputButton::XINPUT_GAMEPAD_RIGHT_SHOULDER: - return ScePadButton::SCE_PAD_BUTTON_R1; - case XInputButton::XINPUT_GAMEPAD_A: - return ScePadButton::SCE_PAD_BUTTON_CROSS; - case XInputButton::XINPUT_GAMEPAD_B: - return ScePadButton::SCE_PAD_BUTTON_CIRCLE; - case XInputButton::XINPUT_GAMEPAD_X: - return ScePadButton::SCE_PAD_BUTTON_SQUARE; - case XInputButton::XINPUT_GAMEPAD_Y: - return ScePadButton::SCE_PAD_BUTTON_TRIANGLE; + case REX::W32::XINPUT_GAMEPAD_DPAD_UP: + return REX::PS4::SCE_PAD_BUTTON_UP; + case REX::W32::XINPUT_GAMEPAD_DPAD_DOWN: + return REX::PS4::SCE_PAD_BUTTON_DOWN; + case REX::W32::XINPUT_GAMEPAD_DPAD_LEFT: + return REX::PS4::SCE_PAD_BUTTON_LEFT; + case REX::W32::XINPUT_GAMEPAD_DPAD_RIGHT: + return REX::PS4::SCE_PAD_BUTTON_RIGHT; + case REX::W32::XINPUT_GAMEPAD_START: + return REX::PS4::SCE_PAD_BUTTON_OPTIONS; + case REX::W32::XINPUT_GAMEPAD_BACK: + return REX::PS4::SCE_PAD_BUTTON_TOUCH_PAD; + case REX::W32::XINPUT_GAMEPAD_LEFT_THUMB: + return REX::PS4::SCE_PAD_BUTTON_L3; + case REX::W32::XINPUT_GAMEPAD_RIGHT_THUMB: + return REX::PS4::SCE_PAD_BUTTON_R3; + case REX::W32::XINPUT_GAMEPAD_LEFT_SHOULDER: + return REX::PS4::SCE_PAD_BUTTON_L1; + case REX::W32::XINPUT_GAMEPAD_RIGHT_SHOULDER: + return REX::PS4::SCE_PAD_BUTTON_R1; + case REX::W32::XINPUT_GAMEPAD_A: + return REX::PS4::SCE_PAD_BUTTON_CROSS; + case REX::W32::XINPUT_GAMEPAD_B: + return REX::PS4::SCE_PAD_BUTTON_CIRCLE; + case REX::W32::XINPUT_GAMEPAD_X: + return REX::PS4::SCE_PAD_BUTTON_SQUARE; + case REX::W32::XINPUT_GAMEPAD_Y: + return REX::PS4::SCE_PAD_BUTTON_TRIANGLE; default: return keyMask; } @@ -48,34 +48,34 @@ namespace F4SE std::uint32_t InputMap::ScePadOffsetToXInput(std::uint32_t keyMask) { switch (keyMask) { - case ScePadButton::SCE_PAD_BUTTON_UP: - return XInputButton::XINPUT_GAMEPAD_DPAD_UP; - case ScePadButton::SCE_PAD_BUTTON_DOWN: - return XInputButton::XINPUT_GAMEPAD_DPAD_DOWN; - case ScePadButton::SCE_PAD_BUTTON_LEFT: - return XInputButton::XINPUT_GAMEPAD_DPAD_LEFT; - case ScePadButton::SCE_PAD_BUTTON_RIGHT: - return XInputButton::XINPUT_GAMEPAD_DPAD_RIGHT; - case ScePadButton::SCE_PAD_BUTTON_OPTIONS: - return XInputButton::XINPUT_GAMEPAD_START; - case ScePadButton::SCE_PAD_BUTTON_TOUCH_PAD: - return XInputButton::XINPUT_GAMEPAD_BACK; - case ScePadButton::SCE_PAD_BUTTON_L3: - return XInputButton::XINPUT_GAMEPAD_LEFT_THUMB; - case ScePadButton::SCE_PAD_BUTTON_R3: - return XInputButton::XINPUT_GAMEPAD_RIGHT_THUMB; - case ScePadButton::SCE_PAD_BUTTON_L1: - return XInputButton::XINPUT_GAMEPAD_LEFT_SHOULDER; - case ScePadButton::SCE_PAD_BUTTON_R1: - return XInputButton::XINPUT_GAMEPAD_RIGHT_SHOULDER; - case ScePadButton::SCE_PAD_BUTTON_CROSS: - return XInputButton::XINPUT_GAMEPAD_A; - case ScePadButton::SCE_PAD_BUTTON_CIRCLE: - return XInputButton::XINPUT_GAMEPAD_B; - case ScePadButton::SCE_PAD_BUTTON_SQUARE: - return XInputButton::XINPUT_GAMEPAD_X; - case ScePadButton::SCE_PAD_BUTTON_TRIANGLE: - return XInputButton::XINPUT_GAMEPAD_Y; + case REX::PS4::SCE_PAD_BUTTON_UP: + return REX::W32::XINPUT_GAMEPAD_DPAD_UP; + case REX::PS4::SCE_PAD_BUTTON_DOWN: + return REX::W32::XINPUT_GAMEPAD_DPAD_DOWN; + case REX::PS4::SCE_PAD_BUTTON_LEFT: + return REX::W32::XINPUT_GAMEPAD_DPAD_LEFT; + case REX::PS4::SCE_PAD_BUTTON_RIGHT: + return REX::W32::XINPUT_GAMEPAD_DPAD_RIGHT; + case REX::PS4::SCE_PAD_BUTTON_OPTIONS: + return REX::W32::XINPUT_GAMEPAD_START; + case REX::PS4::SCE_PAD_BUTTON_TOUCH_PAD: + return REX::W32::XINPUT_GAMEPAD_BACK; + case REX::PS4::SCE_PAD_BUTTON_L3: + return REX::W32::XINPUT_GAMEPAD_LEFT_THUMB; + case REX::PS4::SCE_PAD_BUTTON_R3: + return REX::W32::XINPUT_GAMEPAD_RIGHT_THUMB; + case REX::PS4::SCE_PAD_BUTTON_L1: + return REX::W32::XINPUT_GAMEPAD_LEFT_SHOULDER; + case REX::PS4::SCE_PAD_BUTTON_R1: + return REX::W32::XINPUT_GAMEPAD_RIGHT_SHOULDER; + case REX::PS4::SCE_PAD_BUTTON_CROSS: + return REX::W32::XINPUT_GAMEPAD_A; + case REX::PS4::SCE_PAD_BUTTON_CIRCLE: + return REX::W32::XINPUT_GAMEPAD_B; + case REX::PS4::SCE_PAD_BUTTON_SQUARE: + return REX::W32::XINPUT_GAMEPAD_X; + case REX::PS4::SCE_PAD_BUTTON_TRIANGLE: + return REX::W32::XINPUT_GAMEPAD_Y; default: return keyMask; } @@ -88,33 +88,33 @@ namespace F4SE } switch (keyMask) { - case XInputButton::XINPUT_GAMEPAD_DPAD_UP: + case REX::W32::XINPUT_GAMEPAD_DPAD_UP: return kGamepadButtonOffset_DPAD_UP; - case XInputButton::XINPUT_GAMEPAD_DPAD_DOWN: + case REX::W32::XINPUT_GAMEPAD_DPAD_DOWN: return kGamepadButtonOffset_DPAD_DOWN; - case XInputButton::XINPUT_GAMEPAD_DPAD_LEFT: + case REX::W32::XINPUT_GAMEPAD_DPAD_LEFT: return kGamepadButtonOffset_DPAD_LEFT; - case XInputButton::XINPUT_GAMEPAD_DPAD_RIGHT: + case REX::W32::XINPUT_GAMEPAD_DPAD_RIGHT: return kGamepadButtonOffset_DPAD_RIGHT; - case XInputButton::XINPUT_GAMEPAD_START: + case REX::W32::XINPUT_GAMEPAD_START: return kGamepadButtonOffset_START; - case XInputButton::XINPUT_GAMEPAD_BACK: + case REX::W32::XINPUT_GAMEPAD_BACK: return kGamepadButtonOffset_BACK; - case XInputButton::XINPUT_GAMEPAD_LEFT_THUMB: + case REX::W32::XINPUT_GAMEPAD_LEFT_THUMB: return kGamepadButtonOffset_LEFT_THUMB; - case XInputButton::XINPUT_GAMEPAD_RIGHT_THUMB: + case REX::W32::XINPUT_GAMEPAD_RIGHT_THUMB: return kGamepadButtonOffset_RIGHT_THUMB; - case XInputButton::XINPUT_GAMEPAD_LEFT_SHOULDER: + case REX::W32::XINPUT_GAMEPAD_LEFT_SHOULDER: return kGamepadButtonOffset_LEFT_SHOULDER; - case XInputButton::XINPUT_GAMEPAD_RIGHT_SHOULDER: + case REX::W32::XINPUT_GAMEPAD_RIGHT_SHOULDER: return kGamepadButtonOffset_RIGHT_SHOULDER; - case XInputButton::XINPUT_GAMEPAD_A: + case REX::W32::XINPUT_GAMEPAD_A: return kGamepadButtonOffset_A; - case XInputButton::XINPUT_GAMEPAD_B: + case REX::W32::XINPUT_GAMEPAD_B: return kGamepadButtonOffset_B; - case XInputButton::XINPUT_GAMEPAD_X: + case REX::W32::XINPUT_GAMEPAD_X: return kGamepadButtonOffset_X; - case XInputButton::XINPUT_GAMEPAD_Y: + case REX::W32::XINPUT_GAMEPAD_Y: return kGamepadButtonOffset_Y; case 0x9: // Left Trigger game-defined ID return kGamepadButtonOffset_LT; @@ -131,46 +131,46 @@ namespace F4SE switch (keyCode) { case kGamepadButtonOffset_DPAD_UP: - keyMask = XInputButton::XINPUT_GAMEPAD_DPAD_UP; + keyMask = REX::W32::XINPUT_GAMEPAD_DPAD_UP; break; case kGamepadButtonOffset_DPAD_DOWN: - keyMask = XInputButton::XINPUT_GAMEPAD_DPAD_DOWN; + keyMask = REX::W32::XINPUT_GAMEPAD_DPAD_DOWN; break; case kGamepadButtonOffset_DPAD_LEFT: - keyMask = XInputButton::XINPUT_GAMEPAD_DPAD_LEFT; + keyMask = REX::W32::XINPUT_GAMEPAD_DPAD_LEFT; break; case kGamepadButtonOffset_DPAD_RIGHT: - keyMask = XInputButton::XINPUT_GAMEPAD_DPAD_RIGHT; + keyMask = REX::W32::XINPUT_GAMEPAD_DPAD_RIGHT; break; case kGamepadButtonOffset_START: - keyMask = XInputButton::XINPUT_GAMEPAD_START; + keyMask = REX::W32::XINPUT_GAMEPAD_START; break; case kGamepadButtonOffset_BACK: - keyMask = XInputButton::XINPUT_GAMEPAD_BACK; + keyMask = REX::W32::XINPUT_GAMEPAD_BACK; break; case kGamepadButtonOffset_LEFT_THUMB: - keyMask = XInputButton::XINPUT_GAMEPAD_LEFT_THUMB; + keyMask = REX::W32::XINPUT_GAMEPAD_LEFT_THUMB; break; case kGamepadButtonOffset_RIGHT_THUMB: - keyMask = XInputButton::XINPUT_GAMEPAD_RIGHT_THUMB; + keyMask = REX::W32::XINPUT_GAMEPAD_RIGHT_THUMB; break; case kGamepadButtonOffset_LEFT_SHOULDER: - keyMask = XInputButton::XINPUT_GAMEPAD_LEFT_SHOULDER; + keyMask = REX::W32::XINPUT_GAMEPAD_LEFT_SHOULDER; break; case kGamepadButtonOffset_RIGHT_SHOULDER: - keyMask = XInputButton::XINPUT_GAMEPAD_RIGHT_SHOULDER; + keyMask = REX::W32::XINPUT_GAMEPAD_RIGHT_SHOULDER; break; case kGamepadButtonOffset_A: - keyMask = XInputButton::XINPUT_GAMEPAD_A; + keyMask = REX::W32::XINPUT_GAMEPAD_A; break; case kGamepadButtonOffset_B: - keyMask = XInputButton::XINPUT_GAMEPAD_B; + keyMask = REX::W32::XINPUT_GAMEPAD_B; break; case kGamepadButtonOffset_X: - keyMask = XInputButton::XINPUT_GAMEPAD_X; + keyMask = REX::W32::XINPUT_GAMEPAD_X; break; case kGamepadButtonOffset_Y: - keyMask = XInputButton::XINPUT_GAMEPAD_Y; + keyMask = REX::W32::XINPUT_GAMEPAD_Y; break; case kGamepadButtonOffset_LT: keyMask = 0x9; // Left Trigger game-defined ID From 78cbf661e7878a808417e9a50b7e1bf42bbcbcc8 Mon Sep 17 00:00:00 2001 From: powerof3 <32599957+powerof3@users.noreply.github.com> Date: Tue, 28 May 2024 01:14:05 +0530 Subject: [PATCH 4/5] update --- CommonLibF4/include/F4SE/Impl/PCH.h | 51 ++-- CommonLibF4/include/RE/Bethesda/Actor.h | 2 +- CommonLibF4/include/RE/Bethesda/BGSSaveLoad.h | 4 +- CommonLibF4/include/RE/Bethesda/BSExtraData.h | 17 +- .../include/RE/Bethesda/BSPointerHandle.h | 6 +- CommonLibF4/include/RE/Bethesda/Events.h | 17 +- .../include/RE/Bethesda/FormComponents.h | 219 +++++++++++++++++- CommonLibF4/include/RE/Bethesda/FormFactory.h | 2 +- .../include/RE/Bethesda/TESBoundAnimObjects.h | 6 + CommonLibF4/include/RE/Bethesda/TESForms.h | 74 +++++- .../include/RE/Bethesda/TESObjectREFRs.h | 16 +- .../src/RE/Bethesda/FormComponents.cpp | 76 ++++-- .../src/RE/Bethesda/TESBoundAnimObjects.cpp | 37 +++ 13 files changed, 459 insertions(+), 68 deletions(-) diff --git a/CommonLibF4/include/F4SE/Impl/PCH.h b/CommonLibF4/include/F4SE/Impl/PCH.h index a9137b91..73dea6af 100644 --- a/CommonLibF4/include/F4SE/Impl/PCH.h +++ b/CommonLibF4/include/F4SE/Impl/PCH.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -95,14 +96,13 @@ namespace F4SE requires( const K& a_transparent, const typename C::key_type& a_key, - typename C::key_compare& a_compare) - { - typename C::key_compare::is_transparent; - // clang-format off + typename C::key_compare& a_compare) { + typename C::key_compare::is_transparent; + // clang-format off { a_compare(a_transparent, a_key) } -> std::convertible_to; { a_compare(a_key, a_transparent) } -> std::convertible_to; - // clang-format on - }; + // clang-format on + }; namespace nttp { @@ -142,9 +142,9 @@ namespace F4SE string(const CharT (&)[N]) -> string; } - template // - requires(std::invocable>) // - class scope_exit + template // + requires(std::invocable>) // + class scope_exit { public: // 1) @@ -286,7 +286,8 @@ namespace F4SE template constexpr enumeration(Args... a_values) noexcept // - requires(std::same_as&&...) : + requires(std::same_as && ...) + : _impl((static_cast(a_values) | ...)) {} @@ -315,7 +316,7 @@ namespace F4SE template constexpr enumeration& set(Args... a_args) noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { _impl |= (static_cast(a_args) | ...); return *this; @@ -323,7 +324,7 @@ namespace F4SE template constexpr enumeration& reset(Args... a_args) noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { _impl &= ~(static_cast(a_args) | ...); return *this; @@ -337,21 +338,21 @@ namespace F4SE template [[nodiscard]] constexpr bool any(Args... a_args) const noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { return (_impl & (static_cast(a_args) | ...)) != static_cast(0); } template [[nodiscard]] constexpr bool all(Args... a_args) const noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { return (_impl & (static_cast(a_args) | ...)) == (static_cast(a_args) | ...); } template [[nodiscard]] constexpr bool none(Args... a_args) const noexcept // - requires(std::same_as&&...) + requires(std::same_as && ...) { return (_impl & (static_cast(a_args) | ...)) == static_cast(0); } @@ -384,14 +385,14 @@ namespace F4SE #define F4SE_MAKE_ARITHMETIC_OP(a_op) \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_enum, U a_shift) noexcept \ - ->enumeration \ + -> enumeration \ { \ return static_cast(static_cast(a_enum.get()) a_op a_shift); \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_enum, U a_shift) noexcept \ - ->enumeration& \ + -> enumeration& \ { \ return a_enum = a_enum a_op a_shift; \ } @@ -399,42 +400,42 @@ namespace F4SE #define F4SE_MAKE_ENUMERATION_OP(a_op) \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_lhs, enumeration a_rhs) noexcept \ - ->enumeration> \ + -> enumeration> \ { \ return static_cast(static_cast(a_lhs.get()) a_op static_cast(a_rhs.get())); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_lhs, E a_rhs) noexcept \ - ->enumeration \ + -> enumeration \ { \ return static_cast(static_cast(a_lhs.get()) a_op static_cast(a_rhs)); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op(E a_lhs, enumeration a_rhs) noexcept \ - ->enumeration \ + -> enumeration \ { \ return static_cast(static_cast(a_lhs) a_op static_cast(a_rhs.get())); \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_lhs, enumeration a_rhs) noexcept \ - ->enumeration& \ + -> enumeration& \ { \ return a_lhs = a_lhs a_op a_rhs; \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_lhs, E a_rhs) noexcept \ - ->enumeration& \ + -> enumeration& \ { \ return a_lhs = a_lhs a_op a_rhs; \ } \ \ template \ constexpr auto operator a_op##=(E& a_lhs, enumeration a_rhs) noexcept \ - ->E& \ + -> E& \ { \ return a_lhs = *(a_lhs a_op a_rhs); \ } @@ -442,14 +443,14 @@ namespace F4SE #define F4SE_MAKE_INCREMENTER_OP(a_op) \ template \ constexpr auto operator a_op##a_op(enumeration& a_lhs) noexcept \ - ->enumeration& \ + -> enumeration& \ { \ return a_lhs a_op## = static_cast(1); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op##a_op(enumeration& a_lhs, int) noexcept \ - ->enumeration \ + -> enumeration \ { \ const auto tmp = a_lhs; \ a_op##a_op a_lhs; \ diff --git a/CommonLibF4/include/RE/Bethesda/Actor.h b/CommonLibF4/include/RE/Bethesda/Actor.h index ae0361fc..45bc20a1 100644 --- a/CommonLibF4/include/RE/Bethesda/Actor.h +++ b/CommonLibF4/include/RE/Bethesda/Actor.h @@ -1056,7 +1056,7 @@ namespace RE [[nodiscard]] bool GetHostileToActor(Actor* a_actor) { using func_t = decltype(&Actor::GetHostileToActor); - REL::Relocation func{ REL::ID(1148686) }; + REL::Relocation func{ REL::ID(2229968) }; return func(this, a_actor); } diff --git a/CommonLibF4/include/RE/Bethesda/BGSSaveLoad.h b/CommonLibF4/include/RE/Bethesda/BGSSaveLoad.h index c6750642..3438ddc8 100644 --- a/CommonLibF4/include/RE/Bethesda/BGSSaveLoad.h +++ b/CommonLibF4/include/RE/Bethesda/BGSSaveLoad.h @@ -123,14 +123,14 @@ namespace RE [[nodiscard]] static BGSSaveLoadManager* GetSingleton() { - REL::Relocation singleton{ REL::ID(1247320) }; + REL::Relocation singleton{ REL::ID(2697802) }; return *singleton; } void QueueSaveLoadTask(QUEUED_TASK a_task) { using func_t = decltype(&BGSSaveLoadManager::QueueSaveLoadTask); - REL::Relocation func{ REL::ID(1487308) }; + REL::Relocation func{ REL::ID(2228080) }; return func(this, a_task); } diff --git a/CommonLibF4/include/RE/Bethesda/BSExtraData.h b/CommonLibF4/include/RE/Bethesda/BSExtraData.h index 3f2cd526..c05bba78 100644 --- a/CommonLibF4/include/RE/Bethesda/BSExtraData.h +++ b/CommonLibF4/include/RE/Bethesda/BSExtraData.h @@ -70,7 +70,7 @@ namespace RE kLock, // ExtraLock kTeleport, // ExtraTeleport kMapMarker, - kLeveledCreature, + kLeveledCreature, // ExtraLeveledCreature kLevelItem, kScale, kSeed, @@ -249,6 +249,7 @@ namespace RE class BGSMessage; class BGSRefAlias; class TBO_InstanceData; + class TESActorBase; class TESBoundObject; class TESForm; class TESObjectCELL; @@ -400,6 +401,20 @@ namespace RE }; static_assert(sizeof(ExtraTeleport) == 0x20); + class __declspec(novtable) ExtraLeveledCreature : + public BSExtraData // 00 + { + public: + static constexpr auto RTTI{ RTTI::ExtraLeveledCreature }; + static constexpr auto VTABLE{ VTABLE::ExtraLeveledCreature }; + static constexpr auto TYPE{ EXTRA_DATA_TYPE::kLeveledCreature }; + + // members + TESActorBase* originalBase; // 18 + TESActorBase* templates[13]; // 20 + }; + static_assert(sizeof(ExtraLeveledCreature) == 0x88); + class __declspec(novtable) ExtraInstanceData : public BSExtraData // 00 { diff --git a/CommonLibF4/include/RE/Bethesda/BSPointerHandle.h b/CommonLibF4/include/RE/Bethesda/BSPointerHandle.h index 6ffc347c..a4d036fc 100644 --- a/CommonLibF4/include/RE/Bethesda/BSPointerHandle.h +++ b/CommonLibF4/include/RE/Bethesda/BSPointerHandle.h @@ -161,21 +161,21 @@ namespace RE static BSPointerHandle CreateHandle(T* a_ptr) { using func_t = decltype(&BSPointerHandleManagerInterface::CreateHandle); - REL::Relocation func{ REL::ID(224532) }; + REL::Relocation func{ REL::ID(2188375) }; return func(a_ptr); } static BSPointerHandle GetHandle(T* a_ptr) { using func_t = decltype(&BSPointerHandleManagerInterface::GetHandle); - REL::Relocation func{ REL::ID(901626) }; + REL::Relocation func{ REL::ID(2188676) }; return func(a_ptr); } static bool GetSmartPointer(const BSPointerHandle& a_handle, NiPointer& a_smartPointerOut) { using func_t = decltype(&BSPointerHandleManagerInterface::GetSmartPointer); - REL::Relocation func{ REL::ID(967277) }; + REL::Relocation func{ REL::ID(2188681) }; return func(a_handle, a_smartPointerOut); } }; diff --git a/CommonLibF4/include/RE/Bethesda/Events.h b/CommonLibF4/include/RE/Bethesda/Events.h index c9bb4807..f6088062 100644 --- a/CommonLibF4/include/RE/Bethesda/Events.h +++ b/CommonLibF4/include/RE/Bethesda/Events.h @@ -582,7 +582,7 @@ namespace RE [[nodiscard]] static BSTEventSource* GetEventSource() { using func_t = decltype(&TESDeathEvent::GetEventSource); - REL::Relocation func{ REL::ID(1465690) }; + REL::Relocation func{ REL::ID(2201833) }; return func(); } @@ -612,6 +612,21 @@ namespace RE }; static_assert(sizeof(TESEquipEvent) == 0x18); + struct TESFormDeleteEvent + { + public: + [[nodiscard]] static BSTEventSource* GetEventSource() + { + using func_t = decltype(&TESFormDeleteEvent::GetEventSource); + REL::Relocation func{ REL::ID(2201842) }; + return func(); + } + + // members + std::uint32_t formID; // 00 + }; + static_assert(sizeof(TESFormDeleteEvent) == 0x04); + struct TESFurnitureEvent { public: diff --git a/CommonLibF4/include/RE/Bethesda/FormComponents.h b/CommonLibF4/include/RE/Bethesda/FormComponents.h index 8bd029f9..43daad54 100644 --- a/CommonLibF4/include/RE/Bethesda/FormComponents.h +++ b/CommonLibF4/include/RE/Bethesda/FormComponents.h @@ -1,5 +1,6 @@ #pragma once +#include "RE/Bethesda/BSContainer.h" #include "RE/Bethesda/BSFixedString.h" #include "RE/Bethesda/BSStringT.h" #include "RE/Bethesda/BSTArray.h" @@ -900,17 +901,32 @@ namespace RE // add virtual BGSKeyword* GetDefaultKeyword() const { return nullptr; } // 07 + void CopyKeywords(const std::vector& a_copiedData); + void AddKeyword(BGSKeyword* a_keyword) { using func_t = decltype(&BGSKeywordForm::AddKeyword); - REL::Relocation func{ REL::ID(762999) }; + REL::Relocation func{ REL::ID(2192766) }; return func(this, a_keyword); } + bool AddKeywords(const std::vector& a_keywords); + [[nodiscard]] bool ContainsKeywordString(std::string_view a_editorID) const; [[nodiscard]] bool HasKeywordID(std::uint32_t a_formID) const; [[nodiscard]] bool HasKeywordString(std::string_view a_editorID) const; + void ForEachKeyword(std::function a_callback) const + { + if (keywords) { + for (std::uint32_t idx = 0; idx < numKeywords; ++idx) { + if (keywords[idx] && a_callback(keywords[idx]) == BSContainer::ForEachResult::kStop) { + return; + } + } + } + } + [[nodiscard]] std::optional GetKeywordAt(std::uint32_t a_idx) const { if (a_idx < numKeywords) { @@ -941,6 +957,8 @@ namespace RE return func(this, a_keyword); } + bool RemoveKeywords(const std::vector& a_keywords); + // members BGSKeyword** keywords; // 10 std::uint32_t numKeywords; // 18 @@ -1216,6 +1234,20 @@ namespace RE static constexpr auto RTTI{ RTTI::TESContainer }; static constexpr auto VTABLE{ VTABLE::TESContainer }; + void CopyObjectList(const std::vector& a_copiedData) + { + const auto oldData = containerObjects; + + const auto newSize = a_copiedData.size(); + const auto newData = calloc(newSize); + std::ranges::copy(a_copiedData, newData); + + numContainerObjects = static_cast(newSize); + containerObjects = newData; + + free(oldData); + } + void ForEachContainerObject(std::function a_fn) const { for (std::uint32_t i = 0; i < numContainerObjects; ++i) { @@ -1242,22 +1274,33 @@ namespace RE std::vector copiedData{ containerObjects, containerObjects + numContainerObjects }; const auto newObj = new ContainerObject(a_object, a_count, a_owner); copiedData.push_back(newObj); - - const auto oldData = containerObjects; - - const auto newSize = copiedData.size(); - const auto newData = calloc(newSize); - std::ranges::copy(copiedData, newData); - - numContainerObjects = static_cast(newSize); - containerObjects = newData; - free(oldData); - + CopyObjectList(copiedData); return true; } return added; } + bool AddObjectsToContainer(std::map& a_objects, TESForm* a_owner) + { + for (std::uint32_t i = 0; i < numContainerObjects; ++i) { + if (const auto entry = containerObjects[i]; entry && entry->obj) { + if (auto it = a_objects.find(entry->obj); it != a_objects.end()) { + entry->count += it->second; + a_objects.erase(it); + } + } + } + if (!a_objects.empty()) { + std::vector copiedData{ containerObjects, containerObjects + numContainerObjects }; + for (auto& [object, count] : a_objects) { + const auto newObj = new ContainerObject(object, count, a_owner); + copiedData.push_back(newObj); + } + CopyObjectList(copiedData); + } + return true; + } + // members ContainerObject** containerObjects; // 08 std::uint32_t numContainerObjects; // 10 @@ -1555,6 +1598,13 @@ namespace RE [[nodiscard]] constexpr bool UsesOppositeGenderAnims() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kOppositeGenderanims); } [[nodiscard]] constexpr bool UsesTemplate() const noexcept { return actorData.actorBaseFlags.all(ACTOR_BASE_DATA::Flag::kUsesTemplate); } + std::uint16_t GetLevel() const + { + using func_t = decltype(&TESActorBaseData::GetLevel); + REL::Relocation func{ REL::ID(2192891) }; + return func(this); + } + // members ACTOR_BASE_DATA actorData; // 08 std::int32_t changeFlags; // 1C @@ -1632,6 +1682,30 @@ namespace RE }; static_assert(sizeof(TESImageSpaceModifiableForm) == 0x10); + struct INSTANCE_FILTER + { + public: + // members + std::uint32_t levelOverride; // 00 + std::uint8_t tierStartLevel; // 04 + std::uint8_t altLevelsPerTier; // 05 + bool epic; // 06 + BSScrapArray> keywordChances; // 08 + }; + static_assert(sizeof(INSTANCE_FILTER) == 0x28); + + struct CALCED_OBJECT + { + public: + // members + TESBoundObject* object; // 00 + const char* overrideName; // 08 + std::int32_t count; // 10 + ContainerItemExtra itemExtra; // 18 + INSTANCE_FILTER instanceFilter; // 30 + }; + static_assert(sizeof(CALCED_OBJECT) == 0x58); + struct LEVELED_OBJECT { public: @@ -1651,6 +1725,14 @@ namespace RE static constexpr auto RTTI{ RTTI::TESLeveledList }; static constexpr auto VTABLE{ VTABLE::TESLeveledList }; + enum class LeveledListAllBelowForce + { + kNever = -1, + kDefault = 0, + kAlways = 1, + kShiftUp = 2, + }; + // add virtual std::int8_t GetChanceNone(); // 07 virtual bool GetMultCalc(); // 08 @@ -1665,6 +1747,27 @@ namespace RE return func(this, a_level, a_count, a_chanceNone, a_item, a_itemExtra); } + void CalculateCurrentFormList( + std::uint16_t a_level, + std::uint16_t a_count, + BSScrapArray& a_outCont, + LeveledListAllBelowForce a_allBelowForce = LeveledListAllBelowForce::kDefault, + bool a_clampToPlayer = false, + INSTANCE_FILTER* a_instanceFilter = nullptr, + const char* a_overrideName = nullptr) + { + using func_t = decltype(&TESLeveledList::CalculateCurrentFormList); + REL::Relocation func{ REL::ID(2193259) }; + return func(this, a_level, a_count, a_outCont, a_allBelowForce, a_clampToPlayer, a_instanceFilter, a_overrideName); + } + + void CalculateCurrentFormListForRef(TESObjectREFR* a_ref, BSScrapArray& a_outCont, bool a_legendary) + { + using func_t = decltype(&TESLeveledList::CalculateCurrentFormListForRef); + REL::Relocation func{ REL::ID(2193260) }; + return func(this, a_ref, a_outCont, a_legendary); + } + bool GetUseAll() { using func_t = decltype(&TESLeveledList::GetUseAll); @@ -1800,6 +1903,98 @@ namespace RE F4_HEAP_REDEFINE_NEW(SpellData); + void CopySpellList(const std::vector& a_copiedData) + { + const auto oldData = levSpells; + + const auto newSize = a_copiedData.size(); + const auto newData = calloc(newSize); + std::ranges::copy(a_copiedData, newData); + + numLevSpells = static_cast(newSize); + levSpells = newData; + + free(oldData); + } + + void CopySpellList(const std::vector& a_copiedData) + { + const auto oldData = spells; + + const auto newSize = a_copiedData.size(); + const auto newData = calloc(newSize); + std::ranges::copy(a_copiedData, newData); + + numSpells = static_cast(newSize); + spells = newData; + + free(oldData); + } + + bool AddLevSpells(const std::vector& a_levSpells) + { + std::vector copiedData{ levSpells, levSpells + numLevSpells }; + std::ranges::remove_copy_if(a_levSpells, std::back_inserter(copiedData), [&](auto& spell) { + return std::ranges::find(copiedData, spell) != copiedData.end(); + }); + CopySpellList(copiedData); + return true; + } + + bool AddSpells(const std::vector& a_spells) + { + std::vector copiedData{ spells, spells + numSpells }; + std::ranges::remove_copy_if(a_spells, std::back_inserter(copiedData), [&](auto& spell) { + return std::ranges::find(copiedData, spell) != copiedData.end(); + }); + CopySpellList(copiedData); + return true; + } + + std::optional GetIndex(const SpellItem* a_spell) const + { + if (spells) { + for (std::uint32_t i = 0; i < numSpells; i++) { + if (spells[i] == a_spell) { + return i; + } + } + } + return std::nullopt; + } + + std::optional GetIndex(const TESLevSpell* a_levSpell) const + { + if (levSpells) { + for (std::uint32_t i = 0; i < numLevSpells; i++) { + if (levSpells[i] == a_levSpell) { + return i; + } + } + } + return std::nullopt; + } + + bool RemoveLevSpells(const std::vector& a_levSpells) + { + std::vector copiedData{ levSpells, levSpells + numLevSpells }; + if (std::erase_if(copiedData, [&](auto& spell) { return std::ranges::find(a_levSpells, spell) != a_levSpells.end(); }) > 0) { + CopySpellList(copiedData); + return true; + } + return false; + } + + bool RemoveSpells(const std::vector& a_spells) + { + std::vector copiedData{ spells, spells + numSpells }; + if (std::erase_if(copiedData, [&](auto& spell) { return std::ranges::find(a_spells, spell) != a_spells.end(); }) > 0) { + CopySpellList(copiedData); + return true; + } + return false; + } + // members SpellItem** spells; // 00 TESLevSpell** levSpells; // 08 diff --git a/CommonLibF4/include/RE/Bethesda/FormFactory.h b/CommonLibF4/include/RE/Bethesda/FormFactory.h index 8d0fec3a..04139dee 100644 --- a/CommonLibF4/include/RE/Bethesda/FormFactory.h +++ b/CommonLibF4/include/RE/Bethesda/FormFactory.h @@ -36,7 +36,7 @@ namespace RE -> std::span { constexpr auto len = std::to_underlying(ENUM_FORM_ID::kTotal); - REL::Relocation factories{ REL::ID(228366) }; + REL::Relocation factories{ REL::ID(2689177) }; return { *factories }; } }; diff --git a/CommonLibF4/include/RE/Bethesda/TESBoundAnimObjects.h b/CommonLibF4/include/RE/Bethesda/TESBoundAnimObjects.h index a13f01d6..a732de0d 100644 --- a/CommonLibF4/include/RE/Bethesda/TESBoundAnimObjects.h +++ b/CommonLibF4/include/RE/Bethesda/TESBoundAnimObjects.h @@ -362,6 +362,8 @@ namespace RE }; static_assert(sizeof(HeadRelatedData) == 0x18); + void CopyPerkRankArray(const std::vector& a_copiedData); + bool AddPerk(BGSPerk* a_perk, std::int8_t a_rank) { if (!GetPerkIndex(a_perk)) { @@ -379,6 +381,8 @@ namespace RE return false; } + bool AddPerks(const std::vector& a_perks, std::int8_t a_rank); + [[nodiscard]] bool ContainsKeyword(std::string_view a_editorID) const; [[nodiscard]] static BSTHashMap>& GetAlternateHeadPartListMap() @@ -453,6 +457,8 @@ namespace RE [[nodiscard]] bool HasApplicableKeywordString(std::string_view a_editorID) const; + bool RemovePerks(const std::vector& a_perks); + [[nodiscard]] bool IsInFaction(const TESFaction* a_faction) { for (const auto& faction : factions) { diff --git a/CommonLibF4/include/RE/Bethesda/TESForms.h b/CommonLibF4/include/RE/Bethesda/TESForms.h index 8f00edaf..e63d7f66 100644 --- a/CommonLibF4/include/RE/Bethesda/TESForms.h +++ b/CommonLibF4/include/RE/Bethesda/TESForms.h @@ -803,6 +803,17 @@ namespace RE return func(a_formTypeString); } + [[nodiscard]] static const char* GetFormTypeString(ENUM_FORM_ID a_formType) + { + auto formEnumString = GetFormEnumString(); + return formEnumString[std::to_underlying(a_formType)].formString; + } + + [[nodiscard]] const char* GetFormTypeString() const + { + return GetFormTypeString(GetFormType()); + } + [[nodiscard]] std::uint32_t GetFormFlags() const noexcept { return formFlags; } [[nodiscard]] std::uint32_t GetFormID() const noexcept { return formID; } [[nodiscard]] ENUM_FORM_ID GetFormType() const noexcept { return *formType; } @@ -1530,7 +1541,7 @@ namespace RE [[nodiscard]] TESRegionList* GetRegionList(bool a_createIfMissing) { using func_t = decltype(&TESObjectCELL::GetRegionList); - REL::Relocation func{ REL::ID(1565031) }; + REL::Relocation func{ REL::ID(2200265) }; return func(this, a_createIfMissing); } @@ -2032,6 +2043,23 @@ namespace RE return func(this, a_form); } + void ForEachForm(std::function a_callback) const + { + for (const auto& form : arrayOfForms) { + if (form && a_callback(form) == BSContainer::ForEachResult::kStop) { + return; + } + } + if (scriptAddedTempForms) { + for (const auto& addedFormID : *scriptAddedTempForms) { + const auto addedForm = TESForm::GetFormByID(addedFormID); + if (addedForm && a_callback(addedForm) == BSContainer::ForEachResult::kStop) { + return; + } + } + } + } + [[nodiscard]] std::optional GetItemIndex(const TESForm& a_item) const noexcept { if (scriptAddedTempForms) { @@ -3409,3 +3437,47 @@ namespace RE }; static_assert(sizeof(BGSGodRays) == 0x60); } + +namespace std +{ + [[nodiscard]] inline std::string to_string(RE::ENUM_FORM_ID a_formType) + { + return RE::TESForm::GetFormTypeString(a_formType); + } +} + +#ifdef FMT_VERSION +namespace fmt +{ + template <> + struct formatter + { + template + constexpr auto parse(ParseContext& a_ctx) + { + return a_ctx.begin(); + } + + template + auto format(const RE::ENUM_FORM_ID& a_formType, FormatContext& a_ctx) + { + return fmt::format_to(a_ctx.out(), "{}", RE::TESForm::GetFormTypeString(a_formType)); + } + }; +} +#endif + +#ifdef __cpp_lib_format +namespace std +{ + template + struct formatter : std::formatter + { + template + auto format(RE::ENUM_FORM_ID a_formType, FormatContext& a_ctx) + { + return formatter::format(RE::TESForm::GetFormTypeString(a_formType), a_ctx); + } + }; +} +#endif diff --git a/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h b/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h index dec69a43..8dc0ad58 100644 --- a/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h +++ b/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h @@ -366,6 +366,13 @@ namespace RE } } + void BuildFromContainer(const TESContainer* a_container) + { + using func_t = decltype(&BGSInventoryList::BuildFromContainer); + REL::Relocation func{ REL::ID(2194158) }; + return func(this, a_container); + } + // members BSTArray data; // 58 float cachedWeight; // 70 @@ -734,7 +741,7 @@ namespace RE [[nodiscard]] BGSLocation* GetCurrentLocation() const { using func_t = decltype(&TESObjectREFR::GetCurrentLocation); - REL::Relocation func{ REL::ID(1135470) }; + REL::Relocation func{ REL::ID(2201163) }; return func(this); } @@ -834,6 +841,13 @@ namespace RE return func(this); } + [[nodiscard]] bool IsLeveledCreature() + { + using func_t = decltype(&TESObjectREFR::IsLeveledCreature); + REL::Relocation func{ REL::ID(2202655) }; + return func(this); + } + void MarkAsDeleted() { using func_t = decltype(&TESObjectREFR::MarkAsDeleted); diff --git a/CommonLibF4/src/RE/Bethesda/FormComponents.cpp b/CommonLibF4/src/RE/Bethesda/FormComponents.cpp index 7a2c3e4c..f198f1de 100644 --- a/CommonLibF4/src/RE/Bethesda/FormComponents.cpp +++ b/CommonLibF4/src/RE/Bethesda/FormComponents.cpp @@ -19,42 +19,78 @@ namespace RE } } + void BGSKeywordForm::CopyKeywords(const std::vector& a_copiedData) + { + const auto oldData = keywords; + + const auto newSize = a_copiedData.size(); + const auto newData = calloc(newSize); + std::ranges::copy(a_copiedData, newData); + + numKeywords = static_cast(newSize); + keywords = newData; + + free(oldData); + } + + bool BGSKeywordForm::AddKeywords(const std::vector& a_keywords) + { + std::vector copiedData{ keywords, keywords + numKeywords }; + std::ranges::remove_copy_if(a_keywords, std::back_inserter(copiedData), [&](auto& keyword) { + return std::ranges::find(copiedData, keyword) != copiedData.end(); + }); + CopyKeywords(copiedData); + return true; + } + bool BGSKeywordForm::ContainsKeywordString(std::string_view a_editorID) const { - if (keywords) { - for (std::uint32_t idx = 0; idx < numKeywords; ++idx) { - if (keywords[idx] && keywords[idx]->formEditorID.contains(a_editorID)) { - return true; - } + bool result = false; + ForEachKeyword([&](const BGSKeyword* a_keyword) { + if (a_keyword->formEditorID.contains(a_editorID)) { + result = true; + return BSContainer::ForEachResult::kStop; } - } + return BSContainer::ForEachResult::kContinue; + }); + return result; return false; } bool BGSKeywordForm::HasKeywordID(std::uint32_t a_formID) const { - if (keywords) { - for (std::uint32_t idx = 0; idx < numKeywords; ++idx) { - if (keywords[idx] && keywords[idx]->formID == a_formID) { - return true; - } + bool result = false; + ForEachKeyword([&](const BGSKeyword* a_keyword) { + if (a_keyword->GetFormID() == a_formID) { + result = true; + return BSContainer::ForEachResult::kStop; } - } - - return false; + return BSContainer::ForEachResult::kContinue; + }); + return result; } bool BGSKeywordForm::HasKeywordString(std::string_view a_editorID) const { - if (keywords) { - for (std::uint32_t idx = 0; idx < numKeywords; ++idx) { - if (keywords[idx] && keywords[idx]->formEditorID == a_editorID) { - return true; - } + bool result = false; + ForEachKeyword([&](const BGSKeyword* a_keyword) { + if (a_keyword->formEditorID == a_editorID) { + result = true; + return BSContainer::ForEachResult::kStop; } - } + return BSContainer::ForEachResult::kContinue; + }); + return result; + } + bool BGSKeywordForm::RemoveKeywords(const std::vector& a_keywords) + { + std::vector copiedData{ keywords, keywords + numKeywords }; + if (std::erase_if(copiedData, [&](auto& keyword) { return std::ranges::find(a_keywords, keyword) != a_keywords.end(); }) > 0) { + CopyKeywords(copiedData); + return true; + } return false; } diff --git a/CommonLibF4/src/RE/Bethesda/TESBoundAnimObjects.cpp b/CommonLibF4/src/RE/Bethesda/TESBoundAnimObjects.cpp index a8f70a04..1207077a 100644 --- a/CommonLibF4/src/RE/Bethesda/TESBoundAnimObjects.cpp +++ b/CommonLibF4/src/RE/Bethesda/TESBoundAnimObjects.cpp @@ -5,6 +5,33 @@ namespace RE { + void TESNPC::CopyPerkRankArray(const std::vector& a_copiedData) + { + const auto oldData = perks; + + const auto newSize = a_copiedData.size(); + const auto newData = calloc(newSize); + std::ranges::copy(a_copiedData, newData); + + perkCount = static_cast(newSize); + perks = newData; + + free(oldData); + } + + bool TESNPC::AddPerks(const std::vector& a_perks, std::int8_t a_rank) + { + std::vector copiedData{ perks, perks + perkCount }; + std::ranges::for_each(a_perks, [&](auto& perk) { + if (!GetPerkIndex(perk)) { + const auto newPerk = new PerkRankData(perk, a_rank); + copiedData.push_back(*newPerk); + } + }); + CopyPerkRankArray(copiedData); + return true; + } + bool TESNPC::ContainsKeyword(std::string_view a_editorID) const { if (ContainsKeywordString(a_editorID)) { @@ -27,6 +54,16 @@ namespace RE return false; } + bool TESNPC::RemovePerks(const std::vector& a_perks) + { + std::vector copiedData{ perks, perks + perkCount }; + if (std::erase_if(copiedData, [&](auto& perkRank) { return std::ranges::find(a_perks, perkRank.perk) != a_perks.end(); }) > 0) { + CopyPerkRankArray(copiedData); + return true; + } + return false; + } + bool TESNPC::UsingAlternateHeadPartList() const { if (const auto player = PlayerCharacter::GetSingleton(); IsPlayer() && player) { From 50b119eb6175184f6019d4a80bb4e4cc868e038a Mon Sep 17 00:00:00 2001 From: powerof3 Date: Mon, 27 May 2024 19:44:27 +0000 Subject: [PATCH 5/5] maintenance --- CommonLibF4/include/F4SE/Impl/PCH.h | 50 +++++++++---------- CommonLibF4/include/RE/Bethesda/BSExtraData.h | 2 +- CommonLibF4/include/RE/Bethesda/Events.h | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/CommonLibF4/include/F4SE/Impl/PCH.h b/CommonLibF4/include/F4SE/Impl/PCH.h index 73dea6af..2a5e7441 100644 --- a/CommonLibF4/include/F4SE/Impl/PCH.h +++ b/CommonLibF4/include/F4SE/Impl/PCH.h @@ -96,13 +96,14 @@ namespace F4SE requires( const K& a_transparent, const typename C::key_type& a_key, - typename C::key_compare& a_compare) { - typename C::key_compare::is_transparent; - // clang-format off + typename C::key_compare& a_compare) + { + typename C::key_compare::is_transparent; + // clang-format off { a_compare(a_transparent, a_key) } -> std::convertible_to; { a_compare(a_key, a_transparent) } -> std::convertible_to; - // clang-format on - }; + // clang-format on + }; namespace nttp { @@ -142,9 +143,9 @@ namespace F4SE string(const CharT (&)[N]) -> string; } - template // - requires(std::invocable>) // - class scope_exit + template // + requires(std::invocable>) // + class scope_exit { public: // 1) @@ -286,8 +287,7 @@ namespace F4SE template constexpr enumeration(Args... a_values) noexcept // - requires(std::same_as && ...) - : + requires(std::same_as&&...) : _impl((static_cast(a_values) | ...)) {} @@ -316,7 +316,7 @@ namespace F4SE template constexpr enumeration& set(Args... a_args) noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { _impl |= (static_cast(a_args) | ...); return *this; @@ -324,7 +324,7 @@ namespace F4SE template constexpr enumeration& reset(Args... a_args) noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { _impl &= ~(static_cast(a_args) | ...); return *this; @@ -338,21 +338,21 @@ namespace F4SE template [[nodiscard]] constexpr bool any(Args... a_args) const noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { return (_impl & (static_cast(a_args) | ...)) != static_cast(0); } template [[nodiscard]] constexpr bool all(Args... a_args) const noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { return (_impl & (static_cast(a_args) | ...)) == (static_cast(a_args) | ...); } template [[nodiscard]] constexpr bool none(Args... a_args) const noexcept // - requires(std::same_as && ...) + requires(std::same_as&&...) { return (_impl & (static_cast(a_args) | ...)) == static_cast(0); } @@ -385,14 +385,14 @@ namespace F4SE #define F4SE_MAKE_ARITHMETIC_OP(a_op) \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_enum, U a_shift) noexcept \ - -> enumeration \ + ->enumeration \ { \ return static_cast(static_cast(a_enum.get()) a_op a_shift); \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_enum, U a_shift) noexcept \ - -> enumeration& \ + ->enumeration& \ { \ return a_enum = a_enum a_op a_shift; \ } @@ -400,42 +400,42 @@ namespace F4SE #define F4SE_MAKE_ENUMERATION_OP(a_op) \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_lhs, enumeration a_rhs) noexcept \ - -> enumeration> \ + ->enumeration> \ { \ return static_cast(static_cast(a_lhs.get()) a_op static_cast(a_rhs.get())); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op(enumeration a_lhs, E a_rhs) noexcept \ - -> enumeration \ + ->enumeration \ { \ return static_cast(static_cast(a_lhs.get()) a_op static_cast(a_rhs)); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op(E a_lhs, enumeration a_rhs) noexcept \ - -> enumeration \ + ->enumeration \ { \ return static_cast(static_cast(a_lhs) a_op static_cast(a_rhs.get())); \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_lhs, enumeration a_rhs) noexcept \ - -> enumeration& \ + ->enumeration& \ { \ return a_lhs = a_lhs a_op a_rhs; \ } \ \ template \ constexpr auto operator a_op##=(enumeration& a_lhs, E a_rhs) noexcept \ - -> enumeration& \ + ->enumeration& \ { \ return a_lhs = a_lhs a_op a_rhs; \ } \ \ template \ constexpr auto operator a_op##=(E& a_lhs, enumeration a_rhs) noexcept \ - -> E& \ + ->E& \ { \ return a_lhs = *(a_lhs a_op a_rhs); \ } @@ -443,14 +443,14 @@ namespace F4SE #define F4SE_MAKE_INCREMENTER_OP(a_op) \ template \ constexpr auto operator a_op##a_op(enumeration& a_lhs) noexcept \ - -> enumeration& \ + ->enumeration& \ { \ return a_lhs a_op## = static_cast(1); \ } \ \ template \ [[nodiscard]] constexpr auto operator a_op##a_op(enumeration& a_lhs, int) noexcept \ - -> enumeration \ + ->enumeration \ { \ const auto tmp = a_lhs; \ a_op##a_op a_lhs; \ diff --git a/CommonLibF4/include/RE/Bethesda/BSExtraData.h b/CommonLibF4/include/RE/Bethesda/BSExtraData.h index c05bba78..d0523ce5 100644 --- a/CommonLibF4/include/RE/Bethesda/BSExtraData.h +++ b/CommonLibF4/include/RE/Bethesda/BSExtraData.h @@ -70,7 +70,7 @@ namespace RE kLock, // ExtraLock kTeleport, // ExtraTeleport kMapMarker, - kLeveledCreature, // ExtraLeveledCreature + kLeveledCreature, // ExtraLeveledCreature kLevelItem, kScale, kSeed, diff --git a/CommonLibF4/include/RE/Bethesda/Events.h b/CommonLibF4/include/RE/Bethesda/Events.h index f6088062..f503ffa2 100644 --- a/CommonLibF4/include/RE/Bethesda/Events.h +++ b/CommonLibF4/include/RE/Bethesda/Events.h @@ -623,7 +623,7 @@ namespace RE } // members - std::uint32_t formID; // 00 + std::uint32_t formID; // 00 }; static_assert(sizeof(TESFormDeleteEvent) == 0x04);