|
template<class F , class... Args>
requires (std::invocable<F, Args...>) |
std::invoke_result_t< F, Args... > | invoke (F &&a_func, Args &&... a_args) noexcept(std::is_nothrow_invocable_v< F, Args... >) |
|
void | safe_write (std::uintptr_t a_dst, const void *a_src, std::size_t a_count) |
|
template<std::integral T> |
void | safe_write (std::uintptr_t a_dst, const T &a_data) |
|
template<class T > |
void | safe_write (std::uintptr_t a_dst, std::span< T > a_data) |
|
void | safe_fill (std::uintptr_t a_dst, std::uint8_t a_value, std::size_t a_count) |
|
constexpr bool | operator== (const Version &a_lhs, const Version &a_rhs) noexcept |
|
constexpr std::strong_ordering | operator<=> (const Version &a_lhs, const Version &a_rhs) noexcept |
|
std::optional< Version > | get_file_version (stl::zwstring a_filename) |
|
template<stl::nttp::string S> |
constexpr auto | make_pattern () noexcept |
|
template<class T > |
SKYRIM_ADDR T | Relocate (T &&a_seAndVR, T &&a_ae) noexcept |
|
template<class T > |
SKYRIM_REL T | Relocate (T a_se, T a_ae, T a_vr) noexcept |
|
template<class Fn , class... Args> |
detail::RelocateVirtualHelper< Fn >::return_type | RelocateVirtual (std::ptrdiff_t a_seAndAEVtableOffset, std::ptrdiff_t a_vrVtableOffset, std::ptrdiff_t a_seAndAEVtableIndex, std::ptrdiff_t a_vrVtableIndex, typename detail::RelocateVirtualHelper< Fn >::this_type *a_self, Args &&... a_args) |
|
template<class Fn , class... Args> |
detail::RelocateVirtualHelper< Fn >::return_type | RelocateVirtual (std::ptrdiff_t a_seAndAEVtableIndex, std::ptrdiff_t a_vrVtableIndex, typename detail::RelocateVirtualHelper< Fn >::this_type *a_self, Args &&... a_args) |
|
template<class T , class This > |
T & | RelocateMember (This *a_self, std::ptrdiff_t a_seAndAE, std::ptrdiff_t a_vr) |
|
template<class T , class This > |
T & | RelocateMember (This *a_self, std::ptrdiff_t offset) |
|
template<class T , class This > |
T & | RelocateMemberIf (bool condition, This *a_self, std::ptrdiff_t a, std::ptrdiff_t b) |
|
template<class T , class This > |
T & | RelocateMemberIfNewer (Version v, This *a_self, std::ptrdiff_t older, std::ptrdiff_t newer) |
|
|
constexpr std::uint8_t | NOP = 0x90 |
|
constexpr std::uint8_t | NOP2 [] = { 0x66, 0x90 } |
|
constexpr std::uint8_t | NOP3 [] = { 0x0F, 0x1F, 0x00 } |
|
constexpr std::uint8_t | NOP4 [] = { 0x0F, 0x1F, 0x40, 0x00 } |
|
constexpr std::uint8_t | NOP5 [] = { 0x0F, 0x1F, 0x44, 0x00, 0x00 } |
|
constexpr std::uint8_t | NOP6 [] = { 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00 } |
|
constexpr std::uint8_t | NOP7 [] = { 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 } |
|
constexpr std::uint8_t | NOP8 [] = { 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 } |
|
constexpr std::uint8_t | NOP9 [] = { 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 } |
|
constexpr std::uint8_t | JMP8 = 0xEB |
|
constexpr std::uint8_t | JMP32 = 0xE9 |
|
constexpr std::uint8_t | RET = 0xC3 |
|
constexpr std::uint8_t | INT3 = 0xCC |
|
template<class T >
SKYRIM_ADDR T REL::Relocate |
( |
T && |
a_seAndVR, |
|
|
T && |
a_ae |
|
) |
| |
|
noexcept |
Return the correct value of two choices between SE/VR, and AE versions of Skyrim.
This is commonly used to select between relative offsets within a function, when hooking a call instruction. In such cases the function can be identified by its Address Library ID, but the offset within the function may vary between Skyrim versions. This selection is made at runtime, allowing the same compiled code to run in multiple versions of Skyrim.
- Template Parameters
-
T | the type of value to return. |
- Parameters
-
a_seAndVR | the value to use for SE and VR. |
a_ae | the value to use for AE. |
- Returns
- Either
a_seAndVR
if the current runtime is Skyrim SE or VR, or a_ae
if the runtime is AE.
template<class T >
SKYRIM_REL T REL::Relocate |
( |
T |
a_se, |
|
|
T |
a_ae, |
|
|
T |
a_vr |
|
) |
| |
|
noexcept |
Return the correct value of two choices between SE, AE, and VR versions of Skyrim.
This is commonly used to select between relative offsets within a function, when hooking a call instruction. In such cases the function can be identified by its Address Library ID, but the offset within the function may vary between Skyrim versions. This selection is made at runtime, allowing the same compiled code to run in multiple versions of Skyrim.
- Template Parameters
-
T | the type of value to return. |
- Parameters
-
a_se | the value to use for SE. |
a_ae | the value to use for AE. |
a_vr | the value to use for VR. |
- Returns
- Either
a_se
if the current runtime is Skyrim SE, or a_ae
if the runtime is AE, or a_vr
if running Skyrim VR.
template<class T , class This >
T & REL::RelocateMember |
( |
This * |
a_self, |
|
|
std::ptrdiff_t |
a_seAndAE, |
|
|
std::ptrdiff_t |
a_vr |
|
) |
| |
|
inline |
Gets a member variable in a cross-platform way, using runtime-specific memory offsets.
This function handles the variant memory structures used in Skyrim VR as compared to versions of SE. It allows a memory offset relative to the object's base address for SE (and AE) and a separate one for VR. This simplifies the process of creating functions to get member variables that are at different offsets in different runtimes from a single build.
- Template Parameters
-
T | the type of the member being accessed. |
This | the type of the target object that has the member. |
- Parameters
-
a_self | the target object that has the member. |
a_seAndAE | the memory offset of the member in Skyrim SE and AE. |
a_vr | the memory offset of the member in Skyrim VR. |
- Returns
- A reference to the member.
template<class Fn , class... Args>
Invokes a virtual function in a cross-platform way where the vtable structure is variant across AE/SE and VR runtimes.
Some classes in Skyrim VR add new virtual functions in the middle of the vtable structure, which makes it ABI-incompatible with AE/SE. A naive virtual function call, therefore, cannot work across all runtimes without the plugin being recompiled specifically for VR. This call works with types which have variant vtables to allow a non-virtual function definition to be created in the virtual function's place, and to have that call dynamically lookup the correct function based on the vtable structure expected in the current runtime.
This call assumes the vtable to be used is the one at offset 0, i.e. it invokes a virtual function either on the first parent class or the current class.
- Template Parameters
-
Fn | the type of the function being called. |
Args | the types of the arguments being passed. |
- Parameters
-
a_seAndAEVtableIndex | the index of the function in the class' vtable in SE and AE. |
a_vrVtableIndex | the index of the function in the class' vtable in VR. |
a_self | the this argument for the call. |
a_args | the remaining arguments for the call, if any. |
- Returns
- The result of the function call.
template<class Fn , class... Args>
detail::RelocateVirtualHelper< Fn >::return_type REL::RelocateVirtual |
( |
std::ptrdiff_t |
a_seAndAEVtableOffset, |
|
|
std::ptrdiff_t |
a_vrVtableOffset, |
|
|
std::ptrdiff_t |
a_seAndAEVtableIndex, |
|
|
std::ptrdiff_t |
a_vrVtableIndex, |
|
|
typename detail::RelocateVirtualHelper< Fn >::this_type * |
a_self, |
|
|
Args &&... |
a_args |
|
) |
| |
|
inline |
Invokes a virtual function in a cross-platform way where the vtable structure is variant across AE/SE and VR runtimes.
Some classes in Skyrim VR add new virtual functions in the middle of the vtable structure, which makes it ABI-incompatible with AE/SE. A naive virtual function call, therefore, cannot work across all runtimes without the plugin being recompiled specifically for VR. This call works with types which have variant vtables to allow a non-virtual function definition to be created in the virtual function's place, and to have that call dynamically lookup the correct function based on the vtable structure expected in the current runtime.
- Template Parameters
-
Fn | the type of the function being called. |
Args | the types of the arguments being passed. |
- Parameters
-
a_seAndAEVtableOffset | the offset from the this pointer to the vtable with the virtual function in SE/AE. |
a_vrVtableIndex | the offset from the this pointer to the vtable with the virtual function in VR. |
a_seAndAEVtableIndex | the index of the function in the class' vtable in SE and AE. |
a_vrVtableIndex | the index of the function in the class' vtable in VR. |
a_self | the this argument for the call. |
a_args | the remaining arguments for the call, if any. |
- Returns
- The result of the function call.