docs: add plugin setup guide

This commit is contained in:
2026-05-30 18:33:24 +12:00
parent f3db41c402
commit b61043a3fe
1776 changed files with 122386 additions and 2 deletions
+66
View File
@@ -0,0 +1,66 @@
#pragma once
#include "REX/LOG.h"
namespace F4SE
{
using PluginHandle = std::uint32_t;
class PreLoadInterface;
class LoadInterface;
struct PluginInfo;
class MessagingInterface;
class ScaleformInterface;
class PapyrusInterface;
class SerializationInterface;
class TaskInterface;
class ObjectInterface;
class TrampolineInterface;
struct InitInfo
{
bool log{ true };
#ifndef NDEBUG
REX::ELogLevel logLevel{ REX::ELogLevel::Debug };
#else
REX::ELogLevel logLevel{ REX::ELogLevel::Info };
#endif
const char* logName{ nullptr };
const char* logPattern{ nullptr };
std::size_t logRotate{ 0 };
bool trampoline{ false };
std::size_t trampolineSize{ 0 };
bool hook{ true };
};
void Init(const PreLoadInterface* a_intfc, InitInfo a_info = {}) noexcept;
void Init(const LoadInterface* a_intfc, InitInfo a_info = {}) noexcept;
[[nodiscard]] REL::Version GetF4SEVersion() noexcept;
[[nodiscard]] std::string_view GetPluginName() noexcept;
[[nodiscard]] std::string_view GetPluginAuthor() noexcept;
[[nodiscard]] REL::Version GetPluginVersion() noexcept;
[[nodiscard]] PluginHandle GetPluginHandle() noexcept;
[[nodiscard]] const PluginInfo* GetPluginInfo(std::string_view a_plugin) noexcept;
[[nodiscard]] std::uint32_t GetReleaseIndex() noexcept;
[[nodiscard]] std::string_view GetSaveFolderName() noexcept;
[[nodiscard]] const MessagingInterface* GetMessagingInterface() noexcept;
[[nodiscard]] const ScaleformInterface* GetScaleformInterface() noexcept;
[[nodiscard]] const PapyrusInterface* GetPapyrusInterface() noexcept;
[[nodiscard]] const SerializationInterface* GetSerializationInterface() noexcept;
[[nodiscard]] const TaskInterface* GetTaskInterface() noexcept;
[[nodiscard]] const ObjectInterface* GetObjectInterface() noexcept;
[[nodiscard]] const TrampolineInterface* GetTrampolineInterface() noexcept;
}
namespace F4SE
{
// DEPRECATED
[[deprecated("Use F4SE::Init(..., {}) instead")]] void Init(const LoadInterface* a_intfc, bool a_log) noexcept;
// DEPRECATED
[[deprecated("Use F4SE::Init(..., {}) instead")]] void AllocTrampoline(std::size_t a_size) noexcept;
}
@@ -0,0 +1,9 @@
#pragma once
#include "F4SE/Impl/PCH.h"
#include "F4SE/API.h"
#include "F4SE/InputMap.h"
#include "F4SE/Interfaces.h"
#include "F4SE/Trampoline.h"
#include "F4SE/Version.h"
@@ -0,0 +1,26 @@
#pragma once
#include <REL/REL.h>
#include <REX/REX.h>
namespace F4SE
{
using namespace std::literals;
}
namespace RE
{
using namespace std::literals;
}
namespace Scaleform
{
using namespace std::literals;
}
#include "RE/IDs.h"
#include "RE/IDs_NiRTTI.h"
#include "RE/IDs_RTTI.h"
#include "RE/IDs_VTABLE.h"
#include "RE/B/BSCoreTypes.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);
}
}
@@ -0,0 +1,568 @@
#pragma once
#include "REL/Relocation.h"
#define F4SEAPI __cdecl
namespace RE
{
namespace BSScript
{
class IVirtualMachine;
}
}
namespace Scaleform
{
namespace GFx
{
class Movie;
class Value;
}
}
namespace F4SE
{
using PluginHandle = std::uint32_t;
class DelayFunctorManager;
class ObjectRegistry;
class PersistentObjectStorage;
namespace Impl
{
struct F4SEInterface
{
std::uint32_t f4seVersion;
std::uint32_t runtimeVersion;
std::uint32_t editorVersion;
std::uint32_t isEditor;
void*(F4SEAPI* QueryInterface)(std::uint32_t);
std::uint32_t(F4SEAPI* GetPluginHandle)(void);
std::uint32_t(F4SEAPI* GetReleaseIndex)(void);
const void*(F4SEAPI* GetPluginInfo)(const char*); // 0.6.22+
const char*(F4SEAPI* GetSaveFolderName)(void); // 0.7.1+
};
struct F4SEMessagingInterface
{
std::uint32_t interfaceVersion;
bool(F4SEAPI* RegisterListener)(std::uint32_t, const char*, void*);
bool(F4SEAPI* Dispatch)(std::uint32_t, std::uint32_t, void*, std::uint32_t, const char*);
void*(F4SEAPI* GetEventDispatcher)(std::uint32_t);
};
struct F4SEScaleformInterface
{
std::uint32_t interfaceVersion;
bool(F4SEAPI* Register)(const char*, void*);
};
struct F4SESerializationInterface
{
std::uint32_t version;
void(F4SEAPI* SetUniqueID)(std::uint32_t, std::uint32_t);
void(F4SEAPI* SetRevertCallback)(std::uint32_t, void*);
void(F4SEAPI* SetSaveCallback)(std::uint32_t, void*);
void(F4SEAPI* SetLoadCallback)(std::uint32_t, void*);
void(F4SEAPI* SetFormDeleteCallback)(std::uint32_t, void*);
bool(F4SEAPI* WriteRecord)(std::uint32_t, std::uint32_t, const void*, std::uint32_t);
bool(F4SEAPI* OpenRecord)(std::uint32_t, std::uint32_t);
bool(F4SEAPI* WriteRecordData)(const void*, std::uint32_t);
bool(F4SEAPI* GetNextRecordInfo)(std::uint32_t*, std::uint32_t*, std::uint32_t*);
std::uint32_t(F4SEAPI* ReadRecordData)(void*, std::uint32_t);
bool(F4SEAPI* ResolveHandle)(std::uint64_t, std::uint64_t*);
bool(F4SEAPI* ResolveFormID)(std::uint32_t, std::uint32_t*);
};
struct F4SEPapyrusInterface
{
std::uint32_t interfaceVersion;
bool(F4SEAPI* Register)(void*);
void(F4SEAPI* GetExternalEventRegistrations)(const char*, void*, void*);
};
struct F4SETaskInterface
{
std::uint32_t interfaceVersion;
void(F4SEAPI* AddTask)(void*);
void(F4SEAPI* AddUITask)(void*);
void(F4SEAPI* AddTaskPermanent)(void*);
};
struct F4SEObjectInterface
{
std::uint32_t interfaceVersion;
DelayFunctorManager&(F4SEAPI* GetDelayFunctorManager)(void);
ObjectRegistry&(F4SEAPI* GetObjectRegistry)(void);
PersistentObjectStorage&(F4SEAPI* GetPersistentObjectStorage)(void);
};
struct F4SETrampolineInterface
{
std::uint32_t interfaceVersion;
void*(F4SEAPI* AllocateFromBranchPool)(std::uint32_t, std::size_t);
void*(F4SEAPI* AllocateFromLocalPool)(std::uint32_t, std::size_t);
};
}
class QueryInterface
{
protected:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SEInterface&>(*this);
}
private:
[[nodiscard]] constexpr static REL::Version MakeVersion(std::uint32_t a_version) noexcept
{
return {
static_cast<std::uint16_t>((a_version >> 8 * 3) & 0x0FF),
static_cast<std::uint16_t>((a_version >> 8 * 2) & 0x0FF),
static_cast<std::uint16_t>((a_version >> 8 / 2) & 0xFFF),
static_cast<std::uint16_t>((a_version >> 8 * 0) & 0x00F)
};
}
public:
[[nodiscard]] REL::Version EditorVersion() const noexcept { return MakeVersion(GetProxy().editorVersion); }
[[nodiscard]] REL::Version F4SEVersion() const noexcept { return MakeVersion(GetProxy().f4seVersion); }
[[nodiscard]] PluginHandle GetPluginHandle() const { return GetProxy().GetPluginHandle(); }
[[nodiscard]] std::uint32_t GetReleaseIndex() const { return GetProxy().GetReleaseIndex(); }
[[nodiscard]] std::string_view GetSaveFolderName() const { return GetProxy().GetSaveFolderName(); }
[[nodiscard]] bool IsEditor() const noexcept { return GetProxy().isEditor != 0; }
[[nodiscard]] REL::Version RuntimeVersion() const noexcept { return MakeVersion(GetProxy().runtimeVersion); }
};
class PreLoadInterface :
public QueryInterface
{
public:
enum : std::uint32_t
{
kInvalid = 0,
kTrampoline = 7
};
[[nodiscard]] void* QueryInterface(std::uint32_t a_id) const { return GetProxy().QueryInterface(a_id); }
template <class T>
T* QueryInterface(std::uint32_t a_id) const noexcept
{
auto result = static_cast<T*>(QueryInterface(a_id));
if (result && result->Version() > T::kVersion)
REX::ERROR("interface definition is out of date");
return result;
}
};
class LoadInterface :
public QueryInterface
{
public:
enum : std::uint32_t
{
kInvalid = 0,
kMessaging = 1,
kScaleform = 2,
kPapyrus = 3,
kSerialization = 4,
kTask = 5,
kObject = 6,
kTrampoline = 7
};
[[nodiscard]] void* QueryInterface(std::uint32_t a_id) const { return GetProxy().QueryInterface(a_id); }
template <class T>
T* QueryInterface(std::uint32_t a_id) const noexcept
{
auto result = static_cast<T*>(QueryInterface(a_id));
if (result && result->Version() > T::kVersion)
REX::ERROR("interface definition is out of date");
return result;
}
};
class MessagingInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SEMessagingInterface&>(*this);
}
public:
enum : std::uint32_t
{
kVersion = 1
};
enum : std::uint32_t
{
kPostLoad,
kPostPostLoad,
kPreLoadGame,
kPostLoadGame,
kPreSaveGame,
kPostSaveGame,
kDeleteGame,
kInputLoaded,
kNewGame,
kGameLoaded,
kGameDataReady
};
struct Message
{
const char* sender;
std::uint32_t type;
std::uint32_t dataLen;
void* data;
};
using EventCallback = void F4SEAPI(Message* a_msg);
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
bool RegisterListener(EventCallback* a_handler) const { return RegisterListener(a_handler, "F4SE"sv); }
bool RegisterListener(EventCallback* a_handler, std::string_view a_sender) const;
bool Dispatch(std::uint32_t a_messageType, void* a_data, std::uint32_t a_dataLen, const char* a_receiver) const;
[[nodiscard]] void* GetEventDispatcher(std::uint32_t a_dispatcherID) const
{
return GetProxy().GetEventDispatcher(a_dispatcherID);
}
};
class ScaleformInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SEScaleformInterface&>(*this);
}
public:
enum : std::uint32_t
{
kVersion = 1
};
using RegisterCallback = bool F4SEAPI(Scaleform::GFx::Movie* a_view, Scaleform::GFx::Value* a_value);
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
bool Register(std::string_view a_name, RegisterCallback* a_callback) const;
};
class SerializationInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SESerializationInterface&>(*this);
}
public:
enum : std::uint32_t
{
kVersion = 1,
};
using EventCallback = void F4SEAPI(const SerializationInterface* a_intfc);
using FormDeleteCallback = void F4SEAPI(std::uint64_t a_handle);
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().version; }
void SetUniqueID(std::uint32_t a_uid) const;
void SetRevertCallback(EventCallback* a_callback) const;
void SetSaveCallback(EventCallback* a_callback) const;
void SetLoadCallback(EventCallback* a_callback) const;
void SetFormDeleteCallback(FormDeleteCallback* a_callback) const;
bool WriteRecord(std::uint32_t a_type, std::uint32_t a_version, const void* a_buf, std::uint32_t a_length) const;
bool OpenRecord(std::uint32_t a_type, std::uint32_t a_version) const;
bool WriteRecordData(const void* a_buf, std::uint32_t a_length) const;
template <class T, std::enable_if_t<std::negation_v<std::is_pointer<T>>, int> = 0>
bool WriteRecordData(const T& a_buf) const
{
return WriteRecordData(std::addressof(a_buf), sizeof(T));
}
template <class T, std::size_t N, std::enable_if_t<std::is_array_v<T>, int> = 0>
bool WriteRecordData(const T (&a_buf)[N]) const
{
return WriteRecordData(std::addressof(a_buf), sizeof(T) * N);
}
bool GetNextRecordInfo(std::uint32_t& a_type, std::uint32_t& a_version, std::uint32_t& a_length) const;
std::uint32_t ReadRecordData(void* a_buf, std::uint32_t a_length) const;
template <class T, std::enable_if_t<std::negation_v<std::is_pointer<T>>, int> = 0>
std::uint32_t ReadRecordData(T& a_buf) const
{
return ReadRecordData(std::addressof(a_buf), sizeof(T));
}
template <class T, std::enable_if_t<std::negation_v<std::is_pointer<T>>, int> = 0>
std::uint32_t ReadRecordDataEx(std::uint32_t& a_length, T& a_buf) const
{
a_length -= sizeof(T);
return ReadRecordData(std::addressof(a_buf), sizeof(T));
}
template <class T, std::size_t N, std::enable_if_t<std::is_array_v<T>, int> = 0>
std::uint32_t ReadRecordData(T (&a_buf)[N]) const
{
return ReadRecordData(std::addressof(a_buf), sizeof(T) * N);
}
template <class T, std::size_t N, std::enable_if_t<std::is_array_v<T>, int> = 0>
std::uint32_t ReadRecordDataEx(std::uint32_t& a_length, T (&a_buf)[N]) const
{
a_length -= sizeof(T);
return ReadRecordData(std::addressof(a_buf), sizeof(T) * N);
}
[[nodiscard]] std::optional<std::uint64_t> ResolveHandle(std::uint64_t a_handle) const
{
std::uint64_t result{ 0 };
if (GetProxy().ResolveHandle(a_handle, std::addressof(result))) {
return result;
} else {
return std::nullopt;
}
}
[[nodiscard]] std::optional<std::uint32_t> ResolveFormID(std::uint32_t a_formID) const
{
std::uint32_t result{ 0 };
if (GetProxy().ResolveFormID(a_formID, std::addressof(result))) {
return result;
} else {
return std::nullopt;
}
}
};
class PapyrusInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SEPapyrusInterface&>(*this);
}
public:
enum : std::uint32_t
{
kVersion = 2
};
using RegisterFunctions = bool F4SEAPI(RE::BSScript::IVirtualMachine* a_vm);
using RegistrantFunctor = void F4SEAPI(std::uint64_t a_handle, const char* a_scriptName, const char* a_callbackName, void* a_data);
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
bool Register(RegisterFunctions* a_callback) const;
void GetExternalEventRegistrations(std::string_view a_eventName, void* a_data, RegistrantFunctor* a_functor) const
{
GetProxy().GetExternalEventRegistrations(a_eventName.data(), a_data, reinterpret_cast<void*>(a_functor));
}
};
class ITaskDelegate
{
public:
virtual ~ITaskDelegate() noexcept = default;
virtual void Run() = 0;
};
class TaskInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SETaskInterface&>(*this);
}
class TaskDelegate :
public ITaskDelegate
{
public:
explicit TaskDelegate(std::function<void()> a_task) noexcept :
_impl(std::move(a_task))
{}
void Run() override { _impl(); }
private:
std::function<void()> _impl;
};
public:
enum
{
kVersion = 2
};
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
void AddTask(ITaskDelegate* a_task) const { GetProxy().AddTask(a_task); }
void AddTask(std::function<void()> a_task) const { AddTask(new TaskDelegate(std::move(a_task))); }
void AddUITask(ITaskDelegate* a_task) const { GetProxy().AddUITask(a_task); }
void AddUITask(std::function<void()> a_task) const { AddUITask(new TaskDelegate(std::move(a_task))); }
void AddTaskPermanent(ITaskDelegate* a_task) const { GetProxy().AddTaskPermanent(a_task); }
void AddTaskPermanent(std::function<void()> a_task) const { AddTaskPermanent(new TaskDelegate(std::move(a_task))); }
};
class ObjectInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SEObjectInterface&>(*this);
}
public:
enum
{
kVersion = 1
};
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
[[nodiscard]] DelayFunctorManager& GetDelayFunctorManager() const { return GetProxy().GetDelayFunctorManager(); }
[[nodiscard]] ObjectRegistry& GetObjectRegistry() const { return GetProxy().GetObjectRegistry(); }
[[nodiscard]] PersistentObjectStorage& GetPersistentObjectStorage() const { return GetProxy().GetPersistentObjectStorage(); }
};
class TrampolineInterface
{
private:
[[nodiscard]] decltype(auto) GetProxy() const noexcept
{
return reinterpret_cast<const Impl::F4SETrampolineInterface&>(*this);
}
public:
enum
{
kVersion = 1
};
[[nodiscard]] std::uint32_t Version() const noexcept { return GetProxy().interfaceVersion; }
[[nodiscard]] void* AllocateFromBranchPool(std::size_t a_size) const;
[[nodiscard]] void* AllocateFromLocalPool(std::size_t a_size) const;
};
struct PluginInfo
{
enum : std::uint32_t
{
kVersion = 1
};
std::uint32_t infoVersion;
const char* name;
std::uint32_t version;
};
struct PluginVersionData
{
enum Version : std::uint32_t
{
kVersion = 1
};
constexpr void PluginVersion(const REL::Version a_version) noexcept { pluginVersion = a_version.pack(); }
[[nodiscard]] constexpr REL::Version GetPluginVersion() const noexcept { return REL::Version::unpack(pluginVersion); }
constexpr void PluginName(const std::string_view a_plugin) noexcept { SetCharBuffer(a_plugin, std::span{ pluginName }); }
[[nodiscard]] constexpr std::string_view GetPluginName() const noexcept { return std::string_view{ pluginName }; }
constexpr void AuthorName(const std::string_view a_name) noexcept { SetCharBuffer(a_name, std::span{ author }); }
[[nodiscard]] constexpr std::string_view GetAuthorName() const noexcept { return std::string_view{ author }; }
constexpr void UsesSigScanning(const bool a_value) noexcept { SetOrClearBit(addressIndependence, 1 << 0, a_value); }
// 1 << 2 is for address library for 1.11.137 and later
constexpr void UsesAddressLibrary(const bool a_value) noexcept { SetOrClearBit(addressIndependence, 1 << 2, a_value); }
constexpr void HasNoStructUse(const bool a_value) noexcept { SetOrClearBit(structureIndependence, 1 << 0, a_value); }
// 1 << 2 is for runtime 1.11.137 and later
constexpr void IsLayoutDependent(const bool a_value) noexcept { SetOrClearBit(structureIndependence, 1 << 2, a_value); }
constexpr void CompatibleVersions(std::initializer_list<REL::Version> a_versions) noexcept
{
// must be zero-terminated
assert(a_versions.size() < std::size(compatibleVersions) - 1);
std::ranges::transform(a_versions, std::begin(compatibleVersions), [](const REL::Version& a_version) noexcept {
return a_version.pack();
});
}
constexpr void MinimumRequiredXSEVersion(const REL::Version a_version) noexcept { xseMinimum = a_version.pack(); }
[[nodiscard]] static const PluginVersionData* GetSingleton() noexcept;
const std::uint32_t dataVersion{ kVersion };
std::uint32_t pluginVersion = 0;
char pluginName[256] = {};
char author[256] = {};
std::uint32_t addressIndependence;
std::uint32_t structureIndependence;
std::uint32_t compatibleVersions[16] = {};
std::uint32_t xseMinimum = 0;
const std::uint32_t reservedNonBreaking = 0;
const std::uint32_t reservedBreaking = 0;
const std::uint8_t reserved[512] = {};
private:
static constexpr void SetCharBuffer(std::string_view a_src, std::span<char> a_dst) noexcept
{
assert(a_src.size() < a_dst.size());
std::ranges::fill(a_dst, '\0');
std::ranges::copy(a_src, a_dst.begin());
}
static constexpr void SetOrClearBit(std::uint32_t& a_data, const std::uint32_t a_bit, const bool a_set) noexcept
{
if (a_set)
a_data |= a_bit;
else
a_data &= ~a_bit;
}
};
static_assert(offsetof(PluginVersionData, dataVersion) == 0x000);
static_assert(offsetof(PluginVersionData, pluginVersion) == 0x004);
static_assert(offsetof(PluginVersionData, pluginName) == 0x008);
static_assert(offsetof(PluginVersionData, author) == 0x108);
static_assert(offsetof(PluginVersionData, addressIndependence) == 0x208);
static_assert(offsetof(PluginVersionData, structureIndependence) == 0x20C);
static_assert(offsetof(PluginVersionData, compatibleVersions) == 0x210);
static_assert(offsetof(PluginVersionData, xseMinimum) == 0x250);
static_assert(offsetof(PluginVersionData, reservedNonBreaking) == 0x254);
static_assert(offsetof(PluginVersionData, reservedBreaking) == 0x258);
static_assert(offsetof(PluginVersionData, reserved) == 0x25C);
static_assert(sizeof(PluginVersionData) == 0x45C);
}
#define F4SE_EXPORT extern "C" [[maybe_unused]] __declspec(dllexport)
#define F4SE_PLUGIN_PRELOAD(...) F4SE_EXPORT bool F4SEPlugin_Preload(__VA_ARGS__)
#define F4SE_PLUGIN_LOAD(...) F4SE_EXPORT bool F4SEPlugin_Load(__VA_ARGS__)
#define F4SE_PLUGIN_VERSION F4SE_EXPORT constinit F4SE::PluginVersionData F4SEPlugin_Version
#define F4SEPluginPreload F4SE_PLUGIN_PRELOAD
#define F4SEPluginLoad F4SE_PLUGIN_LOAD
#define F4SEPluginVersion F4SE_PLUGIN_VERSION
@@ -0,0 +1,14 @@
#pragma once
#include "REL/Trampoline.h"
namespace F4SE
{
using Trampoline [[deprecated("Use REL::Trampoline instead")]] = REL::Trampoline;
// DEPRECATED
[[nodiscard, deprecated("Use REL::GetTrampoline instead")]] inline REL::Trampoline& GetTrampoline() noexcept
{
return REL::GetTrampoline();
}
}
@@ -0,0 +1,64 @@
#pragma once
namespace F4SE
{
inline constexpr REL::Version RUNTIME_1_1_29{ 1, 1, 29, 0 };
inline constexpr REL::Version RUNTIME_1_1_30{ 1, 1, 30, 0 };
inline constexpr REL::Version RUNTIME_1_2_0{ 1, 2, 0, 0 };
inline constexpr REL::Version RUNTIME_1_2_37{ 1, 2, 37, 0 };
inline constexpr REL::Version RUNTIME_1_3_45{ 1, 3, 45, 0 };
inline constexpr REL::Version RUNTIME_1_3_47{ 1, 3, 47, 0 };
inline constexpr REL::Version RUNTIME_1_4_124{ 1, 4, 124, 0 };
inline constexpr REL::Version RUNTIME_1_4_125{ 1, 4, 125, 0 };
inline constexpr REL::Version RUNTIME_1_4_131{ 1, 4, 131, 0 };
inline constexpr REL::Version RUNTIME_1_4_132{ 1, 4, 132, 0 };
inline constexpr REL::Version RUNTIME_1_5_141{ 1, 5, 141, 0 };
inline constexpr REL::Version RUNTIME_1_5_147{ 1, 5, 147, 0 };
inline constexpr REL::Version RUNTIME_1_5_151{ 1, 5, 151, 0 };
inline constexpr REL::Version RUNTIME_1_5_154{ 1, 5, 154, 0 };
inline constexpr REL::Version RUNTIME_1_5_157{ 1, 5, 157, 0 };
inline constexpr REL::Version RUNTIME_1_5_205{ 1, 5, 205, 0 };
inline constexpr REL::Version RUNTIME_1_5_210{ 1, 5, 210, 0 };
inline constexpr REL::Version RUNTIME_1_5_307{ 1, 5, 307, 0 };
inline constexpr REL::Version RUNTIME_1_5_412{ 1, 5, 412, 0 };
inline constexpr REL::Version RUNTIME_1_5_414{ 1, 5, 414, 0 };
inline constexpr REL::Version RUNTIME_1_5_416{ 1, 5, 416, 0 };
inline constexpr REL::Version RUNTIME_1_6_0{ 1, 6, 0, 0 };
inline constexpr REL::Version RUNTIME_1_6_3{ 1, 6, 3, 0 };
inline constexpr REL::Version RUNTIME_1_6_9{ 1, 6, 9, 0 };
inline constexpr REL::Version RUNTIME_1_7_7{ 1, 7, 7, 0 };
inline constexpr REL::Version RUNTIME_1_7_9{ 1, 7, 9, 0 };
inline constexpr REL::Version RUNTIME_1_7_10{ 1, 7, 10, 0 };
inline constexpr REL::Version RUNTIME_1_7_12{ 1, 7, 12, 0 };
inline constexpr REL::Version RUNTIME_1_7_15{ 1, 7, 15, 0 };
inline constexpr REL::Version RUNTIME_1_7_19{ 1, 7, 19, 0 };
inline constexpr REL::Version RUNTIME_1_7_22{ 1, 7, 22, 0 };
inline constexpr REL::Version RUNTIME_1_8_7{ 1, 8, 7, 0 };
inline constexpr REL::Version RUNTIME_1_9_4{ 1, 9, 4, 0 };
inline constexpr REL::Version RUNTIME_1_10_20{ 1, 10, 20, 0 };
inline constexpr REL::Version RUNTIME_1_10_26{ 1, 10, 26, 0 };
inline constexpr REL::Version RUNTIME_1_10_40{ 1, 10, 40, 0 };
inline constexpr REL::Version RUNTIME_1_10_50{ 1, 10, 50, 0 };
inline constexpr REL::Version RUNTIME_1_10_64{ 1, 10, 64, 0 };
inline constexpr REL::Version RUNTIME_1_10_75{ 1, 10, 75, 0 };
inline constexpr REL::Version RUNTIME_1_10_82{ 1, 10, 82, 0 };
inline constexpr REL::Version RUNTIME_1_10_89{ 1, 10, 89, 0 };
inline constexpr REL::Version RUNTIME_1_10_98{ 1, 10, 98, 0 };
inline constexpr REL::Version RUNTIME_1_10_106{ 1, 10, 106, 0 };
inline constexpr REL::Version RUNTIME_1_10_111{ 1, 10, 111, 0 };
inline constexpr REL::Version RUNTIME_1_10_114{ 1, 10, 114, 0 };
inline constexpr REL::Version RUNTIME_1_10_120{ 1, 10, 120, 0 };
inline constexpr REL::Version RUNTIME_1_10_130{ 1, 10, 130, 0 };
inline constexpr REL::Version RUNTIME_1_10_138{ 1, 10, 138, 0 };
inline constexpr REL::Version RUNTIME_1_10_162{ 1, 10, 162, 0 };
inline constexpr REL::Version RUNTIME_1_10_163{ 1, 10, 163, 0 };
inline constexpr REL::Version RUNTIME_1_10_980{ 1, 10, 980, 0 };
inline constexpr REL::Version RUNTIME_1_10_984{ 1, 10, 984, 0 };
inline constexpr REL::Version RUNTIME_1_11_137{ 1, 11, 137, 0 };
inline constexpr REL::Version RUNTIME_1_11_159{ 1, 11, 159, 0 };
inline constexpr REL::Version RUNTIME_1_11_169{ 1, 11, 169, 0 };
inline constexpr REL::Version RUNTIME_1_11_191{ 1, 11, 191, 0 };
inline constexpr REL::Version RUNTIME_1_11_221{ 1, 11, 221, 0 };
inline constexpr auto RUNTIME_LATEST = RUNTIME_1_11_221;
}