Skip to content

Commit

Permalink
Merge pull request #15 from powerof3/master
Browse files Browse the repository at this point in the history
feat: InputMap/BSInputEnableManager/HUDMenu
  • Loading branch information
shad0wshayd3 authored May 27, 2024
2 parents 9e0ccf9 + 50b119e commit a63fead
Show file tree
Hide file tree
Showing 26 changed files with 933 additions and 46 deletions.
5 changes: 5 additions & 0 deletions CommonLibF4/cmake/sourcelist.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ set(SOURCES
include/F4SE/API.h
include/F4SE/F4SE.h
include/F4SE/Impl/PCH.h
include/F4SE/InputMap.h
include/F4SE/Interfaces.h
include/F4SE/Logger.h
include/F4SE/Trampoline.h
Expand Down Expand Up @@ -45,6 +46,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
Expand Down Expand Up @@ -353,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
Expand Down Expand Up @@ -382,6 +386,7 @@ set(SOURCES
include/REX/W32/XINPUT.h
src/F4SE/API.cpp
src/F4SE/Impl/PCH.cpp
src/F4SE/InputMap.cpp
src/F4SE/Interfaces.cpp
src/F4SE/Logger.cpp
src/F4SE/Trampoline.cpp
Expand Down
1 change: 1 addition & 0 deletions CommonLibF4/include/F4SE/F4SE.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
7 changes: 7 additions & 0 deletions CommonLibF4/include/F4SE/Impl/PCH.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <new>
#include <optional>
#include <random>
#include <ranges>
#include <source_location>
#include <span>
#include <sstream>
Expand Down Expand Up @@ -329,6 +330,12 @@ namespace F4SE
return *this;
}

constexpr enumeration& reset() noexcept
{
_impl = 0;
return *this;
}

template <class... Args>
[[nodiscard]] constexpr bool any(Args... a_args) const noexcept //
requires(std::same_as<Args, enum_type>&&...)
Expand Down
51 changes: 51 additions & 0 deletions CommonLibF4/include/F4SE/InputMap.h
Original file line number Diff line number Diff line change
@@ -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);
}
}
2 changes: 1 addition & 1 deletion CommonLibF4/include/RE/Bethesda/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ namespace RE
[[nodiscard]] bool GetHostileToActor(Actor* a_actor)
{
using func_t = decltype(&Actor::GetHostileToActor);
REL::Relocation<func_t> func{ REL::ID(1148686) };
REL::Relocation<func_t> func{ REL::ID(2229968) };
return func(this, a_actor);
}

Expand Down
4 changes: 2 additions & 2 deletions CommonLibF4/include/RE/Bethesda/BGSSaveLoad.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,14 @@ namespace RE

[[nodiscard]] static BGSSaveLoadManager* GetSingleton()
{
REL::Relocation<BGSSaveLoadManager**> singleton{ REL::ID(1247320) };
REL::Relocation<BGSSaveLoadManager**> singleton{ REL::ID(2697802) };
return *singleton;
}

void QueueSaveLoadTask(QUEUED_TASK a_task)
{
using func_t = decltype(&BGSSaveLoadManager::QueueSaveLoadTask);
REL::Relocation<func_t> func{ REL::ID(1487308) };
REL::Relocation<func_t> func{ REL::ID(2228080) };
return func(this, a_task);
}

Expand Down
17 changes: 16 additions & 1 deletion CommonLibF4/include/RE/Bethesda/BSExtraData.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ namespace RE
kLock, // ExtraLock
kTeleport, // ExtraTeleport
kMapMarker,
kLeveledCreature,
kLeveledCreature, // ExtraLeveledCreature
kLevelItem,
kScale,
kSeed,
Expand Down Expand Up @@ -249,6 +249,7 @@ namespace RE
class BGSMessage;
class BGSRefAlias;
class TBO_InstanceData;
class TESActorBase;
class TESBoundObject;
class TESForm;
class TESObjectCELL;
Expand Down Expand Up @@ -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
{
Expand Down
145 changes: 145 additions & 0 deletions CommonLibF4/include/RE/Bethesda/BSInputEnableManager.h
Original file line number Diff line number Diff line change
@@ -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<std::underlying_type_t<OTHER_EVENT_FLAG>>(-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_t> 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<UserEventEnabledEvent>, // 000
public BSTEventSource<OtherEventEnabledEvent>, // 058
public BSTEventSource<InputEnableLayerDestroyedEvent>, // 0B0
public BSTSingletonSDM<BSInputEnableManager> // 108
{
public:
struct EnableLayer
{
public:
// members
stl::enumeration<UEFlag, std::uint32_t> inputUserEvents; // 00
stl::enumeration<OEFlag, std::uint32_t> otherInputEvents; // 04
};
static_assert(sizeof(EnableLayer) == 0x08);

[[nodiscard]] static BSInputEnableManager* GetSingleton()
{
REL::Relocation<BSInputEnableManager**> singleton{ REL::ID(781703) };
return *singleton;
}

bool AllocateNewLayer(BSTSmartPointer<BSInputEnableLayer>& a_layer, const char* a_debugName)
{
using func_t = decltype(&BSInputEnableManager::AllocateNewLayer);
REL::Relocation<func_t> 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_t> 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_t> 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<UEFlag, std::uint32_t> cachedInputUserEventsFlags; // 118
stl::enumeration<OEFlag, std::uint32_t> cachedOtherInputEventsFlags; // 11C
stl::enumeration<UEFlag, std::uint32_t> forceEnableInputUserEventsFlags; // 120
stl::enumeration<OEFlag, std::uint32_t> forceOtherInputEventsFlags; // 124
BSSpinLock layerLock; // 128
BSTArray<BSInputEnableManager::EnableLayer> layers; // 130
BSTArray<BSTSmartPointer<BSInputEnableLayer>> layerWrappers; // 148
BSTArray<BSFixedString> debugNames; // 160
bool isCurrentlyInSaveLoad; // 178
};
static_assert(sizeof(BSInputEnableManager) == 0x180);
}
6 changes: 3 additions & 3 deletions CommonLibF4/include/RE/Bethesda/BSPointerHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,21 +161,21 @@ namespace RE
static BSPointerHandle<T> CreateHandle(T* a_ptr)
{
using func_t = decltype(&BSPointerHandleManagerInterface<T, Manager>::CreateHandle);
REL::Relocation<func_t> func{ REL::ID(224532) };
REL::Relocation<func_t> func{ REL::ID(2188375) };
return func(a_ptr);
}

static BSPointerHandle<T> GetHandle(T* a_ptr)
{
using func_t = decltype(&BSPointerHandleManagerInterface<T, Manager>::GetHandle);
REL::Relocation<func_t> func{ REL::ID(901626) };
REL::Relocation<func_t> func{ REL::ID(2188676) };
return func(a_ptr);
}

static bool GetSmartPointer(const BSPointerHandle<T>& a_handle, NiPointer<T>& a_smartPointerOut)
{
using func_t = decltype(&BSPointerHandleManagerInterface<T, Manager>::GetSmartPointer);
REL::Relocation<func_t> func{ REL::ID(967277) };
REL::Relocation<func_t> func{ REL::ID(2188681) };
return func(a_handle, a_smartPointerOut);
}
};
Expand Down
25 changes: 25 additions & 0 deletions CommonLibF4/include/RE/Bethesda/ControlMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ namespace RE
public BSTSingletonSDM<ControlMap> // 000
{
public:
using InputContextID = UserEvents::INPUT_CONTEXT_ID;

enum : std::uint32_t
{
kInvalid = static_cast<std::uint8_t>(-1)
};

struct UserEventMapping
{
public:
Expand Down Expand Up @@ -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[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) {
return mapping.inputKey;
}
}
}

return kInvalid;
}

bool PopInputContext(UserEvents::INPUT_CONTEXT_ID a_context)
{
using func_t = decltype(&ControlMap::PopInputContext);
Expand Down
Loading

0 comments on commit a63fead

Please sign in to comment.