diff --git a/CommonLibF4/cmake/sourcelist.cmake b/CommonLibF4/cmake/sourcelist.cmake index da677f4b..80666ec5 100644 --- a/CommonLibF4/cmake/sourcelist.cmake +++ b/CommonLibF4/cmake/sourcelist.cmake @@ -230,6 +230,7 @@ set(SOURCES include/RE/Bethesda/Settings.h include/RE/Bethesda/Sky.h include/RE/Bethesda/SplineUtils.h + include/RE/Bethesda/TES.h include/RE/Bethesda/TESBoundAnimObjects.h include/RE/Bethesda/TESBoundObjects.h include/RE/Bethesda/TESCamera.h @@ -244,6 +245,7 @@ set(SOURCES include/RE/Bethesda/TESRace.h include/RE/Bethesda/TESWaterForm.h include/RE/Bethesda/TESWorldSpace.h + include/RE/Bethesda/TLS.h include/RE/Bethesda/TaskQueueInterface.h include/RE/Bethesda/UI.h include/RE/Bethesda/UIMessage.h @@ -404,6 +406,7 @@ set(SOURCES include/REX/W32/DXGI_5.h include/REX/W32/DXGI_6.h include/REX/W32/KERNEL32.h + include/REX/W32/NT.h include/REX/W32/OLE32.h include/REX/W32/SHELL32.h include/REX/W32/USER32.h diff --git a/CommonLibF4/include/RE/Bethesda/Actor.h b/CommonLibF4/include/RE/Bethesda/Actor.h index 82ce6d0d..937aa675 100644 --- a/CommonLibF4/include/RE/Bethesda/Actor.h +++ b/CommonLibF4/include/RE/Bethesda/Actor.h @@ -624,7 +624,7 @@ namespace RE bool SetupSpecialIdle(Actor& a_actor, RE::DEFAULT_OBJECT a_defaultObject, TESIdleForm* a_idle, bool a_testConditions, TESObjectREFR* a_targetOverride) { using func_t = decltype(&AIProcess::SetupSpecialIdle); - static REL::Relocation func{ REL::ID(1446774) }; + static REL::Relocation func{ REL::ID(2231704) }; return func(this, a_actor, a_defaultObject, a_idle, a_testConditions, a_targetOverride); } diff --git a/CommonLibF4/include/RE/Bethesda/Archive2.h b/CommonLibF4/include/RE/Bethesda/Archive2.h index d4bcbe55..4fc097a3 100644 --- a/CommonLibF4/include/RE/Bethesda/Archive2.h +++ b/CommonLibF4/include/RE/Bethesda/Archive2.h @@ -341,4 +341,15 @@ namespace RE::BSResource::Archive2 BSFixedString nameText; // 30 }; static_assert(sizeof(AsyncReaderStream) == 0x38); + + class StreamOpenedEvent + { + public: + // members + BSFixedString streamName; // 00 + BSFixedString sourceName; // 08 + std::uint64_t startOffset; // 10 + std::uint32_t sizeInArchive; // 18 + }; + static_assert(sizeof(StreamOpenedEvent) == 0x20); } diff --git a/CommonLibF4/include/RE/Bethesda/BSGraphics.h b/CommonLibF4/include/RE/Bethesda/BSGraphics.h index 474583f4..82c01f77 100644 --- a/CommonLibF4/include/RE/Bethesda/BSGraphics.h +++ b/CommonLibF4/include/RE/Bethesda/BSGraphics.h @@ -245,7 +245,7 @@ namespace RE public: [[nodiscard]] static RendererData* GetSingleton() { - static REL::Relocation singleton{ REL::ID(1235449) }; + static REL::Relocation singleton{ REL::ID(2704429) }; return *singleton; } @@ -512,7 +512,7 @@ namespace RE public: [[nodiscard]] static State GetSingleton() { - static REL::Relocation singleton{ REL::ID(600795) }; + static REL::Relocation singleton{ REL::ID(2704621) }; return *singleton; } @@ -621,7 +621,7 @@ namespace RE [[nodiscard]] static RenderTargetManager GetSingleton() { - static REL::Relocation singleton{ REL::ID(1508457) }; + static REL::Relocation singleton{ REL::ID(2666735) }; return *singleton; } @@ -633,9 +633,10 @@ namespace RE } // members - RenderTargetProperties renderTargetData[100]; // 000 - DepthStencilTargetProperties depthStencilTargetData[12]; // C80 - CubeMapRenderTargetProperties cubeMapRenderTargetData[1]; // DA0 + RenderTargetProperties renderTargetData[100]; // 000 + DepthStencilTargetProperties depthStencilTargetData[12]; // C80 + CubeMapRenderTargetProperties cubeMapRenderTargetData[1]; // DA0 + std::byte padDC4[0x30]; std::uint32_t renderTargetID[100]; // DC4 std::uint32_t depthStencilTargetID[12]; // F54 std::uint32_t cubeMapRenderTargetID[1]; // F84 @@ -656,7 +657,7 @@ namespace RE BSTAtomicValue dynamicResolutionDisabled; // FB4 Create_T create; // FB8 }; - static_assert(sizeof(RenderTargetManager) == 0xFC0); + static_assert(sizeof(RenderTargetManager) == 0xFF0); }; namespace BSShaderTechniqueIDMap diff --git a/CommonLibF4/include/RE/Bethesda/BSInputEventUser.h b/CommonLibF4/include/RE/Bethesda/BSInputEventUser.h index d11884de..4d1ca8af 100644 --- a/CommonLibF4/include/RE/Bethesda/BSInputEventUser.h +++ b/CommonLibF4/include/RE/Bethesda/BSInputEventUser.h @@ -39,6 +39,14 @@ namespace RE }; static_assert(sizeof(DisconnectHandler) == 0x10); + struct __declspec(novtable) MenuOpenHandler : + public BSInputEventUser // 00 + { + static constexpr auto RTTI{ RTTI::MenuOpenHandler }; + static constexpr auto VTABLE{ VTABLE::MenuOpenHandler }; + }; + static_assert(sizeof(MenuOpenHandler) == 0x10); + struct __declspec(novtable) ScreenshotHandler : public BSInputEventUser // 00 { diff --git a/CommonLibF4/include/RE/Bethesda/BSScaleformManager.h b/CommonLibF4/include/RE/Bethesda/BSScaleformManager.h index 2b74747d..caeaf89b 100644 --- a/CommonLibF4/include/RE/Bethesda/BSScaleformManager.h +++ b/CommonLibF4/include/RE/Bethesda/BSScaleformManager.h @@ -85,7 +85,7 @@ namespace RE [[nodiscard]] static BSScaleformManager* GetSingleton() { - static REL::Relocation singleton{ REL::ID(106578) }; + static REL::Relocation singleton{ REL::ID(2689600) }; return *singleton; } diff --git a/CommonLibF4/include/RE/Bethesda/ControlMap.h b/CommonLibF4/include/RE/Bethesda/ControlMap.h index 7b01e9f8..1e407222 100644 --- a/CommonLibF4/include/RE/Bethesda/ControlMap.h +++ b/CommonLibF4/include/RE/Bethesda/ControlMap.h @@ -115,7 +115,7 @@ namespace RE void SetTextEntryMode(bool a_enable) { using func_t = decltype(&ControlMap::SetTextEntryMode); - static REL::Relocation func{ REL::ID(0) }; + static REL::Relocation func{ REL::ID(2268339) }; return func(this, a_enable); } diff --git a/CommonLibF4/include/RE/Bethesda/IMenu.h b/CommonLibF4/include/RE/Bethesda/IMenu.h index 0974c4ea..bf75f707 100644 --- a/CommonLibF4/include/RE/Bethesda/IMenu.h +++ b/CommonLibF4/include/RE/Bethesda/IMenu.h @@ -40,6 +40,7 @@ namespace RE { enum class ContainerMenuMode; + enum class DIFFICULTY_LEVEL; enum class EQUIP_TYPE; namespace Workshop @@ -794,6 +795,65 @@ namespace RE }; static_assert(sizeof(GameMenuBase) == 0xE0); + struct __declspec(novtable) StartMenuBase : + public GameMenuBase // 00 + { + public: + static constexpr auto RTTI{ RTTI::StartMenuBase }; + static constexpr auto VTABLE{ VTABLE::StartMenuBase }; + + virtual ~StartMenuBase(); // 00 + + // add + virtual void DoLoadGame(std::int32_t a_saveIndex); // 14 + virtual void InitMainList(); // 15 + virtual bool GetIsMenuReady(); // 16 + virtual void SaveSettings_Derived(); // 17 + virtual void SetMenuColor(); // 18 + + // members + msvc::unique_ptr mainPanel; // 0E0 + msvc::unique_ptr versionText; // 0E8 + msvc::unique_ptr mainPanelBackground; // 0F0 + msvc::unique_ptr loadPanelBackground; // 0F8 + msvc::unique_ptr loadPanelBrackets; // 100 + msvc::unique_ptr loadPanelList; // 108 + msvc::unique_ptr loadPanelPlayerInfo; // 110 + msvc::unique_ptr confirmText; // 118 + msvc::unique_ptr levelText; // 120 + msvc::unique_ptr playtimeText; // 128 + msvc::unique_ptr locationText; // 130 + msvc::unique_ptr levelMeter; // 138 + msvc::unique_ptr modsLoadedText; // 140 + msvc::unique_ptr settingsCategoryList; // 148 + msvc::unique_ptr settingsList; // 150 + msvc::unique_ptr DLCList; // 158 + msvc::unique_ptr loadingIcon; // 160 + msvc::unique_ptr colorReference; // 168 + msvc::unique_ptr splashScreenText; // 170 + msvc::unique_ptr controlsPanel; // 178 + msvc::unique_ptr helpPanelBackground; // 180 + msvc::unique_ptr helpListBackground; // 188 + msvc::unique_ptr gamerTagPanel; // 190 + msvc::unique_ptr gamerTagText; // 198 + msvc::unique_ptr gamerTagIcon; // 1A0 + msvc::unique_ptr bethesdaLogo; // 1A8 + msvc::unique_ptr characterSelectList; // 1B0 + msvc::unique_ptr remapPrompt; // 1B8 + msvc::unique_ptr settingGuideText; // 1C0 + msvc::unique_ptr blackBackground; // 1C8 + msvc::unique_ptr modManager; // 1D0 + msvc::unique_ptr DLCImageSizer; // 1D8 + msvc::unique_ptr DLCPanelBrackets; // 1E0 + msvc::unique_ptr loginObj; // 1E8 + msvc::unique_ptr motD; // 1F0 + BSTOptional currentDisplayDifficultyLevel; // 1F8 + Scaleform::GFx::Value saveLoadPanelObj; // 218 + bool gameDataReady; // 220 + bool controlsChanged; // 221 + }; + static_assert(sizeof(StartMenuBase) == 0x228); + struct Rumble { public: @@ -828,13 +888,13 @@ namespace RE [[nodiscard]] static decltype(auto) GetPickRef() { - static REL::Relocation ref{ REL::ID(170742) }; + static REL::Relocation ref{ REL::ID(2701395) }; return *ref; } [[nodiscard]] static decltype(auto) GetPickRefs() { - static REL::Relocation*> pickRefs{ REL::ID(875116) }; + static REL::Relocation*> pickRefs{ REL::ID(2701391) }; return *pickRefs; } @@ -2286,6 +2346,33 @@ namespace RE }; static_assert(sizeof(LockpickingMenu) == 0x1C0); + class __declspec(novtable) PauseMenu : + public StartMenuBase // 00 + { + public: + static constexpr auto RTTI{ RTTI::PauseMenu }; + static constexpr auto VTABLE{ VTABLE::PauseMenu }; + static constexpr auto MENU_NAME{ "PauseMenu"sv }; + + // members + msvc::unique_ptr helpTopicList; // 228 + msvc::unique_ptr helpPanelBrackets; // 230 + msvc::unique_ptr helpListBrackets; // 238 + msvc::unique_ptr helpText; // 240 + msvc::unique_ptr helpTitleText; // 248 + msvc::unique_ptr helpScrollUp; // 250 + msvc::unique_ptr helpScrollDown; // 258 + Rumble::AutoRumblePause rumbleLock; // 260 + bool hideScreen3D; // 261 + bool modMenuShaderWasEnabled; // 262 + bool vatsWasEnabled; // 263 + bool vatsDepthTestMask; // 264 + bool quitToMainMenuQueued; // 265 + bool quitToDesktopQueued; // 266 + bool noProfileSelected; // 267 + }; + static_assert(sizeof(PauseMenu) == 0x268); + class __declspec(novtable) SitWaitMenu : public GameMenuBase // 00 { diff --git a/CommonLibF4/include/RE/Bethesda/ImageSpaceData.h b/CommonLibF4/include/RE/Bethesda/ImageSpaceData.h index 5d3b2970..256d6e83 100644 --- a/CommonLibF4/include/RE/Bethesda/ImageSpaceData.h +++ b/CommonLibF4/include/RE/Bethesda/ImageSpaceData.h @@ -59,11 +59,24 @@ namespace RE }; static_assert(sizeof(Tint) == 0x10); + struct DepthOfField // DNAM + { + public: + // members + float strength; // 00 + float distance; // 04 + float range; // 08 + float vignetteRadius; // 0C + float vignetteStrength; // 10 + float mode; // 14 + }; + static_assert(sizeof(DepthOfField) == 0x18); + // members - HDR hdrData; // 00 - Cinematic cinematicData; // 24 - Tint tintData; // 30 - float dofData[6]; // 40 + HDR hdrData; // 00 + Cinematic cinematicData; // 24 + Tint tintData; // 30 + DepthOfField dofData; // 40 }; static_assert(sizeof(ImageSpaceBaseData) == 0x58); @@ -82,7 +95,21 @@ namespace RE { public: // members - float data[20]; // 00 + float fadeAmount; // 00 + float fadeR; // 04 + float fadeG; // 08 + float fadeB; // 0C + float blurRadius; // 10 + float doubleVisionStrength; // 14 + float radiusBlurStrength; // 18 + float radiusBlurRampUp; // 1C + float radiusBlurStart; // 20 + float radiusBlurRampDown; // 24 + float radiusBlurDownStart; // 28 + float radiusBlurCenterX; // 2C + float radiusBlurCenterY; // 30 + ImageSpaceBaseData::DepthOfField depthOfField; // 34 + float motionBlurStrength; // 4C }; static_assert(sizeof(ImageSpaceModData) == 0x50); diff --git a/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h b/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h index 2a0516ab..7c1cc777 100644 --- a/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h +++ b/CommonLibF4/include/RE/Bethesda/ImageSpaceEffect.h @@ -100,6 +100,45 @@ namespace RE }; static_assert(sizeof(ImageSpaceEffectOption) == 0xC8); + class __declspec(novtable) ImageSpaceEffectBokehDepthOfField : + public ImageSpaceEffectOption // 00 + { + public: + static constexpr auto RTTI{ RTTI::ImageSpaceEffectBokehDepthOfField }; + static constexpr auto VTABLE{ VTABLE::ImageSpaceEffectBokehDepthOfField }; + + virtual ~ImageSpaceEffectBokehDepthOfField() override; // 00 + + // override (ImageSpaceEffect) + virtual void Render(BSTriShape* a_geometry, ImageSpaceEffectParam* a_param) override; // 01 + virtual void Setup(ImageSpaceManager* a_manager, ImageSpaceEffectParam* a_param) override; // 03 + virtual bool IsActive() override; // 08 + }; + static_assert(sizeof(ImageSpaceEffectBokehDepthOfField) == 0xC8); + + class __declspec(novtable) ImageSpaceEffectDepthOfField : + public ImageSpaceEffectOption // 00 + { + public: + static constexpr auto RTTI{ RTTI::ImageSpaceEffectDepthOfField }; + static constexpr auto VTABLE{ VTABLE::ImageSpaceEffectDepthOfField }; + + virtual ~ImageSpaceEffectDepthOfField() override; // 00 + + // override (ImageSpaceEffect) + virtual void Setup(ImageSpaceManager* a_manager, ImageSpaceEffectParam* a_param) override; // 03 + virtual void BorrowTextures(ImageSpaceEffectParam* a_param) override; // 05 + virtual void ReturnTextures() override; // 06 + virtual bool IsActive() override; // 08 + virtual bool UpdateParams(ImageSpaceEffectParam* a_param) override; // 09 + + // members + ImageSpaceTexture maskBuffer; // B0 + ImageSpaceTexture buffer[3]; // F0 + bool useFog; // 168 + }; + static_assert(sizeof(ImageSpaceEffectDepthOfField) == 0x170); + class __declspec(novtable) ImageSpaceEffectFullScreenBlur : public ImageSpaceEffect // 00 { @@ -149,6 +188,25 @@ namespace RE }; static_assert(sizeof(ImageSpaceEffectGetHit) == 0x108); + class __declspec(novtable) ImageSpaceEffectHDR : + public ImageSpaceEffect // 00 + { + public: + static constexpr auto RTTI{ RTTI::ImageSpaceEffectHDR }; + static constexpr auto VTABLE{ VTABLE::ImageSpaceEffectHDR }; + + virtual ~ImageSpaceEffectHDR(); // 00 + + // override (ImageSpaceEffect) + virtual void Render(BSTriShape* a_geometry, ImageSpaceEffectParam* a_param) override; // 01 + virtual void Setup(ImageSpaceManager* a_manager, ImageSpaceEffectParam* a_param) override; // 03 + virtual void Shutdown() override; // 04 + virtual bool UpdateParams(ImageSpaceEffectParam* a_param) override; // 09 + + inline static REL::Relocation UsePipboyScreenMask{ REL::ID(2678029) }; + }; + static_assert(sizeof(ImageSpaceEffectHDR) == 0xB0); + class __declspec(novtable) ImageSpaceEffectMotionBlur : public ImageSpaceEffect // 00 { diff --git a/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h b/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h index 43ece7ec..ce3b9403 100644 --- a/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h +++ b/CommonLibF4/include/RE/Bethesda/ImageSpaceModifier.h @@ -27,6 +27,16 @@ namespace RE static constexpr auto RTTI{ RTTI::ImageSpaceModifierInstance }; static constexpr auto VTABLE{ VTABLE::ImageSpaceModifierInstance }; + enum class FLAGS + { + kNone = 0, + kPermanent = 1 << 0, + kCrossfade = 1 << 1, + kPreviousCrossfade = 1 << 2, + kMenuIMOD = 1 << 3, + kStopped = 1 << 4 + }; + virtual ~ImageSpaceModifierInstance(); // 00 // add @@ -35,11 +45,18 @@ namespace RE virtual void PrintInfo(char* a_buffer) = 0; // 2A virtual ImageSpaceModifierInstanceForm* IsForm(); // 2B + void Stop() + { + using func_t = decltype(&ImageSpaceModifierInstance::Stop); + static REL::Relocation func{ REL::ID(2199897) }; + return func(this); + } + // members - float strength; // 10 - NiPointer target; // 18 - float age; // 20 - std::uint32_t flags; // 24 + float strength; // 10 + NiPointer target; // 18 + float age; // 20 + REX::EnumSet flags; // 24 }; static_assert(sizeof(ImageSpaceModifierInstance) == 0x28); @@ -61,28 +78,28 @@ namespace RE static ImageSpaceModifierInstanceForm* Trigger(TESImageSpaceModifier* a_mod, float a_strength, NiAVObject* a_target) { using func_t = ImageSpaceModifierInstanceForm* (*)(TESImageSpaceModifier*, float, NiAVObject*); - static REL::Relocation func{ REL::ID(179769) }; + static REL::Relocation func{ REL::ID(2199906) }; return func(a_mod, a_strength, a_target); } static ImageSpaceModifierInstanceForm* Trigger(const BSFixedString& a_name) { using func_t = ImageSpaceModifierInstanceForm* (*)(const BSFixedString&); - static REL::Relocation func{ REL::ID(1216312) }; + static REL::Relocation func{ REL::ID(2199907) }; return func(a_name); } static void Stop(TESImageSpaceModifier* a_mod) { using func_t = void (*)(TESImageSpaceModifier*); - static REL::Relocation func{ REL::ID(217873) }; + static REL::Relocation func{ REL::ID(2199909) }; return func(a_mod); } static void Stop(const BSFixedString& a_name) { using func_t = void (*)(const BSFixedString&); - static REL::Relocation func{ REL::ID(549773) }; + static REL::Relocation func{ REL::ID(2199910) }; return func(a_name); } @@ -120,12 +137,34 @@ namespace RE static constexpr auto RTTI{ RTTI::ImageSpaceModifierInstanceDOF }; static constexpr auto VTABLE{ VTABLE::ImageSpaceModifierInstanceDOF }; + enum class DepthOfFieldMode + { + kFrontBack = 0, + kFront, + kBack, + kNone, + }; + virtual ~ImageSpaceModifierInstanceDOF(); // 00 // override (ImageSpaceModifierInstanceTemp) virtual void Apply() override; // 29 virtual void PrintInfo(char* a_buffer) override; // 2A + static ImageSpaceModifierInstanceDOF* Trigger( + float a_distance, + float a_range, + float a_vignetteRadius, + float a_vignetteStrength, + DepthOfFieldMode a_mode, + float a_strength, + float a_duration) + { + using func_t = decltype(&ImageSpaceModifierInstanceDOF::Trigger); + static REL::Relocation func{ REL::ID(2199922) }; + return func(a_distance, a_range, a_vignetteRadius, a_vignetteStrength, a_mode, a_strength, a_duration); + } + // members ImageSpaceModData data; // 30 }; diff --git a/CommonLibF4/include/RE/Bethesda/InputEvent.h b/CommonLibF4/include/RE/Bethesda/InputEvent.h index c9f876fb..79b89a2a 100644 --- a/CommonLibF4/include/RE/Bethesda/InputEvent.h +++ b/CommonLibF4/include/RE/Bethesda/InputEvent.h @@ -82,6 +82,7 @@ namespace RE kX = 0x58, kY = 0x59, kZ = 0x5A, + kApps = 0x5D, kNumpad_0 = 0x60, kNumpad_1 = 0x61, kNumpad_2 = 0x62, diff --git a/CommonLibF4/include/RE/Bethesda/Interface3D.h b/CommonLibF4/include/RE/Bethesda/Interface3D.h index dd3b6d1c..acd31c7d 100644 --- a/CommonLibF4/include/RE/Bethesda/Interface3D.h +++ b/CommonLibF4/include/RE/Bethesda/Interface3D.h @@ -370,6 +370,13 @@ namespace RE return func(this); } + static void DisableAll(bool a_disableAll) + { + using func_t = decltype(&Renderer::DisableAll); + static REL::Relocation func{ REL::ID(2222521) }; + return func(a_disableAll); + } + void Release() { using func_t = decltype(&Renderer::Release); diff --git a/CommonLibF4/include/RE/Bethesda/InventoryUserUIUtils.h b/CommonLibF4/include/RE/Bethesda/InventoryUserUIUtils.h index 18291a5e..5953bb6a 100644 --- a/CommonLibF4/include/RE/Bethesda/InventoryUserUIUtils.h +++ b/CommonLibF4/include/RE/Bethesda/InventoryUserUIUtils.h @@ -10,6 +10,23 @@ namespace RE class HUDModeType; + namespace HUDMenuUtils + { + inline NiColor GetGameplayHUDColor() + { + using func_t = decltype(&HUDMenuUtils::GetGameplayHUDColor); + static REL::Relocation func{ REL::ID(2248840) }; + return func(); + } + + inline NiColor GetGameplayHUDBackgroundColor() + { + using func_t = decltype(&HUDMenuUtils::GetGameplayHUDBackgroundColor); + static REL::Relocation func{ REL::ID(2248845) }; + return func(); + } + } + namespace InventoryUserUIUtils { namespace detail diff --git a/CommonLibF4/include/RE/Bethesda/Main.h b/CommonLibF4/include/RE/Bethesda/Main.h index 9efc233c..5ba4b170 100644 --- a/CommonLibF4/include/RE/Bethesda/Main.h +++ b/CommonLibF4/include/RE/Bethesda/Main.h @@ -57,6 +57,13 @@ namespace RE return *singleton; } + void SetCameraFOV(float a_fov) + { + using func_t = decltype(&Main::SetCameraFOV); + static REL::Relocation func{ REL::ID(2228973) }; + return func(this, a_fov); + } + // members BSTArray>> sortedVisibleHighActors; // 08 std::uint32_t localMapRenderDelay; // 20 diff --git a/CommonLibF4/include/RE/Bethesda/MenuControls.h b/CommonLibF4/include/RE/Bethesda/MenuControls.h index 67cae373..e9db5a0f 100644 --- a/CommonLibF4/include/RE/Bethesda/MenuControls.h +++ b/CommonLibF4/include/RE/Bethesda/MenuControls.h @@ -12,7 +12,6 @@ namespace RE struct CameraZoomHandler; struct ClickHandler; struct GFxConvertHandler; - struct MenuOpenHandler; struct QuickSaveLoadHandler; class MenuControls : diff --git a/CommonLibF4/include/RE/Bethesda/PlayerControls.h b/CommonLibF4/include/RE/Bethesda/PlayerControls.h index 6531535c..106bfdca 100644 --- a/CommonLibF4/include/RE/Bethesda/PlayerControls.h +++ b/CommonLibF4/include/RE/Bethesda/PlayerControls.h @@ -12,21 +12,16 @@ namespace RE { + class BGSAction; class MenuModeChangeEvent; class MenuOpenCloseEvent; class QuickContainerStateEvent; class UserEventEnabledEvent; struct ActivateHandler; - struct AttackBlockHandler; - struct AutoMoveHandler; struct GrabRotationHandler; - struct JumpHandler; - struct MeleeThrowHandler; struct MovementHandler; - struct ReadyWeaponHandler; struct RunHandler; - struct SneakHandler; struct SprintHandler; struct TESFurnitureEvent; struct TogglePOVHandler; @@ -109,6 +104,19 @@ namespace RE }; static_assert(sizeof(PlayerInputHandler) == 0x20); + class AutoMoveHandler : + public PlayerInputHandler + { + public: + static constexpr auto RTTI{ RTTI::AutoMoveHandler }; + static constexpr auto VTABLE{ VTABLE::AutoMoveHandler }; + + explicit constexpr AutoMoveHandler(PlayerControlsData& a_data) noexcept : + PlayerInputHandler(a_data) + {} + }; + static_assert(sizeof(AutoMoveHandler) == 0x20); + class HeldStateHandler : public PlayerInputHandler // 00 { @@ -137,6 +145,62 @@ namespace RE }; static_assert(sizeof(HeldStateHandler) == 0x28); + class AttackBlockHandler : + public HeldStateHandler + { + public: + static constexpr auto RTTI{ RTTI::AttackBlockHandler }; + static constexpr auto VTABLE{ VTABLE::AttackBlockHandler }; + + enum class POWER_ATTACK_STATE + { + kNone = 0, + kLeft, + kRight, + kDual, + }; + + // members + std::uint64_t dualAttackStartTime; // 28 + BSFixedString debounceEvent; // 30 + REX::EnumSet checkForPowerAttack; // 38 + std::uint32_t numPowerAttacks; // 3C + SettingT* initialDelay; // 40 + SettingT* subsequentDelay; // 48 + float attackTimer; // 50 + std::uint64_t rightAttackTimestamp; // 58 + float rightAttackHeldSeconds; // 60 + float rightAttackLastHeldSeconds; // 64 + float rightAttackLatchEngage; // 68 + float rightAttackLatchRelease; // 6C + bool debounce; // 70 + bool castAttemptMade; // 71 + bool leftAttackButtonHeld; // 72 + bool rightAttackButtonHeld; // 73 + bool rightAttackQueued; // 74 + bool rightAttackPrevFrame; // 75 + bool setAttackTimer; // 76 + bool checkPostMeleeActions; // 77 + bool checkPostThrowActions; // 78 + }; + static_assert(sizeof(AttackBlockHandler) == 0x80); + + class JumpHandler : + public PlayerInputHandler + { + public: + static constexpr auto RTTI{ RTTI::JumpHandler }; + static constexpr auto VTABLE{ VTABLE::JumpHandler }; + + explicit constexpr JumpHandler(PlayerControlsData& a_data) noexcept : + PlayerInputHandler(a_data) + {} + + // members + bool debounceAlternateExit{ false }; // 20 + }; + static_assert(sizeof(JumpHandler) == 0x28); + class LookHandler : public PlayerInputHandler { @@ -153,6 +217,49 @@ namespace RE }; static_assert(sizeof(LookHandler) == 0x28); + class MeleeThrowHandler : + public HeldStateHandler + { + public: + static constexpr auto RTTI{ RTTI::MeleeThrowHandler }; + static constexpr auto VTABLE{ VTABLE::MeleeThrowHandler }; + + // members + bool buttonHoldDebounce; // 28 + bool pressRegistered; // 29 + bool queueThrow; // 2A + }; + static_assert(sizeof(MeleeThrowHandler) == 0x30); + + class ReadyWeaponHandler : + public PlayerInputHandler + { + public: + static constexpr auto RTTI{ RTTI::ReadyWeaponHandler }; + static constexpr auto VTABLE{ VTABLE::ReadyWeaponHandler }; + + explicit constexpr ReadyWeaponHandler(PlayerControlsData& a_data) noexcept : + PlayerInputHandler(a_data) + {} + + // members + bool actionTaken{ false }; // 20 + }; + static_assert(sizeof(ReadyWeaponHandler) == 0x28); + + class SneakHandler : + public PlayerInputHandler + { + public: + static constexpr auto RTTI{ RTTI::SneakHandler }; + static constexpr auto VTABLE{ VTABLE::SneakHandler }; + + explicit constexpr SneakHandler(PlayerControlsData& a_data) noexcept : + PlayerInputHandler(a_data) + {} + }; + static_assert(sizeof(SneakHandler) == 0x20); + class __declspec(novtable) PlayerControls : BSInputEventReceiver, // 000 BSTEventSink, // 010 @@ -221,7 +328,7 @@ namespace RE void DoRegisterHandler(PlayerInputHandler* a_handler, bool a_isHeldStateHandler) { using func_t = decltype(&PlayerControls::DoRegisterHandler); - static REL::Relocation func{ REL::ID(177801) }; + static REL::Relocation func{ REL::ID(2234822) }; return func(this, a_handler, a_isHeldStateHandler); } }; diff --git a/CommonLibF4/include/RE/Bethesda/SendHUDMessage.h b/CommonLibF4/include/RE/Bethesda/SendHUDMessage.h index 6e96cd38..c920a5e8 100644 --- a/CommonLibF4/include/RE/Bethesda/SendHUDMessage.h +++ b/CommonLibF4/include/RE/Bethesda/SendHUDMessage.h @@ -7,14 +7,14 @@ namespace RE inline void PopHUDMode(const HUDModeType& a_hudMode) { using func_t = decltype(&SendHUDMessage::PopHUDMode); - static REL::Relocation func{ REL::ID(1495042) }; + static REL::Relocation func{ REL::ID(2222444) }; return func(a_hudMode); } inline void PushHUDMode(const HUDModeType& a_hudMode) { using func_t = decltype(&SendHUDMessage::PushHUDMode); - static REL::Relocation func{ REL::ID(1321764) }; + static REL::Relocation func{ REL::ID(2222443) }; return func(a_hudMode); } diff --git a/CommonLibF4/include/RE/Bethesda/Sky.h b/CommonLibF4/include/RE/Bethesda/Sky.h index 8147ba4b..1e7a0dc4 100644 --- a/CommonLibF4/include/RE/Bethesda/Sky.h +++ b/CommonLibF4/include/RE/Bethesda/Sky.h @@ -74,14 +74,14 @@ namespace RE [[nodiscard]] static Sky* GetSingleton() { using func_t = decltype(&Sky::GetSingleton); - static REL::Relocation func{ REL::ID(484694) }; + static REL::Relocation func{ REL::ID(2192448) }; return func(); } void ForceWeather(TESWeather* a_weather, bool a_override) { using func_t = decltype(&Sky::ForceWeather); - static REL::Relocation func{ REL::ID(698558) }; + static REL::Relocation func{ REL::ID(2208861) }; return func(this, a_weather, a_override); } @@ -96,7 +96,7 @@ namespace RE void ResetWeather() { using func_t = decltype(&Sky::ResetWeather); - static REL::Relocation func{ REL::ID(6511) }; + static REL::Relocation func{ REL::ID(2208860) }; return func(this); } diff --git a/CommonLibF4/include/RE/Bethesda/TES.h b/CommonLibF4/include/RE/Bethesda/TES.h new file mode 100644 index 00000000..facb409b --- /dev/null +++ b/CommonLibF4/include/RE/Bethesda/TES.h @@ -0,0 +1,119 @@ +#pragma once + +#include "RE/Bethesda/BSContainer.h" +#include "RE/Bethesda/BSTEvent.h" +#include "RE/Bethesda/BSTList.h" +#include "RE/Bethesda/BSTTuple.h" +#include "RE/NetImmerse/NiPoint.h" +#include "RE/NetImmerse/NiSmartPointer.h" + +namespace RE +{ + namespace BSResource::Archive2 + { + class StreamOpenedEvent; + } + + class GridCellArray; + class GridDistantArray; + class ImageSpaceModifierInstance; + class LoadedAreaBound; + class NavMeshInfoMap; + class NiAVObject; + class NiFogProperty; + class NiNode; + class Sky; + class TESNPC; + class TESObjectCELL; + class TESWorldSpace; + + struct bhkPickData; + struct PositionPlayerEvent; + + class TES : + public BSTEventSink, // 000 + public BSTEventSink // 008 + { + public: + static constexpr auto RTTI{ RTTI::TES }; + static constexpr auto VTABLE{ VTABLE::TES }; + + using TACCallbackFunc_t = void(TESObjectCELL*, void*, void*); + + struct ParticleObjectCache + { + public: + // members + NiPointer model; // 00 + NiPointer* clones; // 08 + ParticleObjectCache* next; // 10 + }; + static_assert(sizeof(ParticleObjectCache) == 0x18); + + virtual ~TES(); // 00 + + // override (BSTEventSink) + BSEventNotifyControl ProcessEvent(const BSResource::Archive2::StreamOpenedEvent& a_event, BSTEventSource* a_eventSource) override; // 01 - { return BSEventNotifyControl::kContinue; } + + // override (BSTEventSink) + BSEventNotifyControl ProcessEvent(const PositionPlayerEvent& a_event, BSTEventSource* a_eventSource) override; // 01 + + [[nodiscard]] static TES* GetSingleton() + { + static REL::Relocation singleton{ REL::ID(2698044) }; + return *singleton; + } + + // members + GridDistantArray* gridDistant; // 010 + GridCellArray* gridCells; // 018 + NiNode* objRoot; // 020 + NiNode* lodLandRoot; // 028 + NiNode* objLODWaterRoot; // 030 + NiDirectionalLight* objLight; // 038 + NiFogProperty* objFog; // 040 + std::int32_t currentGridX; // 044 + std::int32_t currentGridY; // 048 + std::int32_t currentQueuedX; // 04C + std::int32_t currentQueuedY; // 050 + TESObjectCELL* interiorCell; // 058 + TESObjectCELL** interiorBuffer; // 060 + TESObjectCELL** exteriorBuffer; // 068 + std::uint32_t tempInteriorBufferSize; // 070 + std::uint32_t tempExteriorBufferSize; // 074 + std::int32_t saveGridX; // 078 + std::int32_t saveGridY; // 07C + TACCallbackFunc_t* tacCallbackFunc; // 080 + void* tacCallbackData; // 088 + TESRegion* tacRegionFilter; // 090 + Sky* sky; // 098 + BSSimpleList> activeImageSpaceModifiers; // 0A0 + std::uint32_t totalToLoad; // 0B0 + std::uint32_t loaded; // 0B4 + std::uint64_t cellCaptureStartTime; // 0B8 + bool disablePercentageUpdate; // 0C0 + bool showLANDborders; // 0C1 + bool fadeWhenLoading; // 0C2 + bool forceUpdateMultiBoundExterior; // 0C3 + bool collisionBoxes; // 0C4 + bool runningCellTests; // 0C5 + bool runningCellTests2; // 0C6 + bool runningGraphicsTests; // 0C7 + bool runningCellListGraphicsTests; // 0C8 + bool runningSubmergedObjectTest; // 0C9 + bool allowUnusedPurge; // 0CA + float cellDeltaX; // 0D0 + float cellDeltaY; // 0D4 + TESWorldSpace* worldSpace; // 0D8 + BSTArray> deadCount; // 0E0 + NiPointer preloadedAddonNodes; // 0F8 + NiPointer bloodDecalPreload1; // 100 + NiPointer preloadedForms; // 108 + NiPointer preloadedDefaultModels; // 110 + TES::ParticleObjectCache* particleCacheHead; // 118 + std::uint32_t placeableWaterCount; // 120 + NavMeshInfoMap* navMeshInfoMap; // 128 + NiPointer loadedAreaBound; // 130 + }; + static_assert(sizeof(TES) == 0x138); +} diff --git a/CommonLibF4/include/RE/Bethesda/TESCondition.h b/CommonLibF4/include/RE/Bethesda/TESCondition.h index 5b83cc4b..006594d3 100644 --- a/CommonLibF4/include/RE/Bethesda/TESCondition.h +++ b/CommonLibF4/include/RE/Bethesda/TESCondition.h @@ -80,11 +80,18 @@ namespace RE [[nodiscard]] bool IsTrue(TESObjectREFR* a_actionRef, TESObjectREFR* a_targetRef) { - using func_t = decltype(&TESConditionItem::IsTrue); + using func_t = bool (*)(TESConditionItem*, TESObjectREFR*, TESObjectREFR*); static REL::Relocation func{ REL::ID(2212008) }; return func(this, a_actionRef, a_targetRef); } + [[nodiscard]] bool IsTrue(ConditionCheckParams& a_params) + { + using func_t = bool (*)(TESConditionItem*, ConditionCheckParams&); + static REL::Relocation func{ REL::ID(2212009) }; + return func(this, a_params); + } + // members TESConditionItem* next; // 00 CONDITION_ITEM_DATA data; // 08 diff --git a/CommonLibF4/include/RE/Bethesda/TESForms.h b/CommonLibF4/include/RE/Bethesda/TESForms.h index 869a922a..ad2782a4 100644 --- a/CommonLibF4/include/RE/Bethesda/TESForms.h +++ b/CommonLibF4/include/RE/Bethesda/TESForms.h @@ -1846,6 +1846,21 @@ namespace RE static constexpr auto VTABLE{ VTABLE::TESIdleForm }; static constexpr auto FORM_ID{ ENUM_FORM_ID::kIDLE }; + bool CheckConditions(TESObjectREFR* a_actionRef, TESObjectREFR* a_targetRef, bool a_recurseUp) + { + if (!conditions.IsTrue(a_actionRef, a_targetRef)) { + return false; + } + + if (a_recurseUp) { + if (parentIdle) { + return parentIdle->CheckConditions(a_actionRef, a_targetRef, a_recurseUp); + } + } + + return true; + } + // members TESCondition conditions; // 20 IDLE_DATA data; // 28 diff --git a/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h b/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h index c70908b7..bdc7297b 100644 --- a/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h +++ b/CommonLibF4/include/RE/Bethesda/TESObjectREFRs.h @@ -701,7 +701,7 @@ namespace RE bool a_interfaceEffect = false) { using func_t = decltype(&TESObjectREFR::ApplyArtObject); - static REL::Relocation func{ REL::ID(357908) }; + static REL::Relocation func{ REL::ID(2205200) }; return func(this, a_art, a_time, a_facingRef, a_attachToCamera, a_inheritRotation, a_3D, a_interfaceEffect); } @@ -715,7 +715,7 @@ namespace RE bool a_interfaceEffect = false) { using func_t = decltype(&TESObjectREFR::ApplyEffectShader); - static REL::Relocation func{ REL::ID(652173) }; + static REL::Relocation func{ REL::ID(2205201) }; return func(this, a_art, a_time, a_facingRef, a_attachToCamera, a_inheritRotation, a_3D, a_interfaceEffect); } diff --git a/CommonLibF4/include/RE/Bethesda/TLS.h b/CommonLibF4/include/RE/Bethesda/TLS.h new file mode 100644 index 00000000..fc90e1ab --- /dev/null +++ b/CommonLibF4/include/RE/Bethesda/TLS.h @@ -0,0 +1,18 @@ +#pragma once + +#include "REX/W32/NT.h" + +namespace RE +{ + struct TLS + { + [[nodiscard]] static TLS* GetSingleton() + { + return *static_cast(REX::W32::NtCurrentTeb()->threadLocalStoragePointer); + } + + // members + std::byte pad000[0x830]; // 000 + bool consoleMode; // 830 + }; +} diff --git a/CommonLibF4/include/RE/Bethesda/VATS.h b/CommonLibF4/include/RE/Bethesda/VATS.h index 21a0d33c..a47f5265 100644 --- a/CommonLibF4/include/RE/Bethesda/VATS.h +++ b/CommonLibF4/include/RE/Bethesda/VATS.h @@ -48,7 +48,7 @@ namespace RE [[nodiscard]] static VATS* GetSingleton() { - static REL::Relocation singleton{ REL::ID(570121) }; + static REL::Relocation singleton{ REL::ID(2690444) }; return *singleton; } diff --git a/CommonLibF4/include/RE/Fallout.h b/CommonLibF4/include/RE/Fallout.h index a83219ce..b52153d5 100644 --- a/CommonLibF4/include/RE/Fallout.h +++ b/CommonLibF4/include/RE/Fallout.h @@ -225,6 +225,7 @@ #include "RE/Bethesda/Settings.h" #include "RE/Bethesda/Sky.h" #include "RE/Bethesda/SplineUtils.h" +#include "RE/Bethesda/TES.h" #include "RE/Bethesda/TESBoundAnimObjects.h" #include "RE/Bethesda/TESBoundObjects.h" #include "RE/Bethesda/TESCamera.h" @@ -239,6 +240,7 @@ #include "RE/Bethesda/TESRace.h" #include "RE/Bethesda/TESWaterForm.h" #include "RE/Bethesda/TESWorldSpace.h" +#include "RE/Bethesda/TLS.h" #include "RE/Bethesda/TaskQueueInterface.h" #include "RE/Bethesda/UI.h" #include "RE/Bethesda/UIMessage.h" diff --git a/CommonLibF4/include/RE/RTTI.h b/CommonLibF4/include/RE/RTTI.h index 38d9a5be..dd029068 100644 --- a/CommonLibF4/include/RE/RTTI.h +++ b/CommonLibF4/include/RE/RTTI.h @@ -113,7 +113,7 @@ namespace RE inline void* RTDynamicCast(void* a_inptr, std::int32_t a_vfDelta, void* a_srcType, void* a_targetType, std::int32_t a_isReference) { using func_t = decltype(&RTDynamicCast); - REL::Relocation func{ REL::ID(84112) }; + REL::Relocation func{ REL::ID(2725673) }; return func(a_inptr, a_vfDelta, a_srcType, a_targetType, a_isReference); } diff --git a/CommonLibF4/include/RE/Scaleform/GFx/GFx_Player.h b/CommonLibF4/include/RE/Scaleform/GFx/GFx_Player.h index 5c28a4de..a0047da9 100644 --- a/CommonLibF4/include/RE/Scaleform/GFx/GFx_Player.h +++ b/CommonLibF4/include/RE/Scaleform/GFx/GFx_Player.h @@ -576,6 +576,20 @@ namespace RE::Scaleform::GFx return func(this, a_data, a_name, a_val, a_isdobj); } + bool GetElement(void* a_data, std::uint32_t a_idx, Value* a_val) const + { + using func_t = decltype(&ObjectInterface::GetElement); + static REL::Relocation func{ REL::ID(2285881) }; + return func(this, a_data, a_idx, a_val); + } + + bool SetElement(void* a_data, std::uint32_t a_idx, const Value& a_val) + { + using func_t = decltype(&ObjectInterface::SetElement); + static REL::Relocation func{ REL::ID(2286575) }; + return func(this, a_data, a_idx, a_val); + } + bool SetMember(void* a_data, const char* a_name, const Value& a_value, bool a_isdobj) { using func_t = decltype(&ObjectInterface::SetMember); @@ -914,6 +928,18 @@ namespace RE::Scaleform::GFx return _objectInterface->GetArraySize(_value.data); } + bool GetElement(std::uint32_t a_idx, Value* a_val) const + { + assert(IsArray()); + return _objectInterface->GetElement(_value.data, a_idx, a_val); + } + + bool SetElement(std::uint32_t a_idx, const Value& a_val) + { + assert(IsArray()); + return _objectInterface->SetElement(_value.data, a_idx, a_val); + } + bool GetMember(stl::zstring a_name, Value* a_val) const { assert(IsObject()); diff --git a/CommonLibF4/include/REL/Relocation.h b/CommonLibF4/include/REL/Relocation.h index 2a3bf789..b58f124a 100644 --- a/CommonLibF4/include/REL/Relocation.h +++ b/CommonLibF4/include/REL/Relocation.h @@ -300,28 +300,28 @@ namespace REL safe_write(address(), a_data.data(), a_data.size_bytes()); } - template + template std::uintptr_t write_branch(const std::uintptr_t a_dst) requires(std::same_as) { - return F4SE::GetTrampoline().write_branch(address(), a_dst); + return F4SE::GetTrampoline().write_branch(address() + O, a_dst); } - template + template std::uintptr_t write_branch(const F a_dst) requires(std::same_as) { - return F4SE::GetTrampoline().write_branch(address(), stl::unrestricted_cast(a_dst)); + return F4SE::GetTrampoline().write_branch(address() + O, stl::unrestricted_cast(a_dst)); } - template + template std::uintptr_t write_call(const std::uintptr_t a_dst) requires(std::same_as) { - return F4SE::GetTrampoline().write_call(address(), a_dst); + return F4SE::GetTrampoline().write_call(address() + O, a_dst); } - template + template std::uintptr_t write_call(const F a_dst) requires(std::same_as) { - return F4SE::GetTrampoline().write_call(address(), stl::unrestricted_cast(a_dst)); + return F4SE::GetTrampoline().write_call(address() + O, stl::unrestricted_cast(a_dst)); } void write_fill(const std::uint8_t a_value, const std::size_t a_count) requires(std::same_as) diff --git a/CommonLibF4/include/REL/Version.h b/CommonLibF4/include/REL/Version.h index f2d84167..b96100f4 100644 --- a/CommonLibF4/include/REL/Version.h +++ b/CommonLibF4/include/REL/Version.h @@ -116,7 +116,7 @@ template struct fmt::formatter : formatter { template - auto format(const REL::Version& a_version, FormatContext& a_ctx) + auto format(const REL::Version& a_version, FormatContext& a_ctx) const { return formatter::format(a_version.string(), a_ctx); } diff --git a/CommonLibF4/include/REX/REX.h b/CommonLibF4/include/REX/REX.h index b7b8aa04..e16baae6 100644 --- a/CommonLibF4/include/REX/REX.h +++ b/CommonLibF4/include/REX/REX.h @@ -1,5 +1,70 @@ #pragma once +namespace REX +{ + template < + class E, + class U = std::underlying_type_t> + class Enum + { + public: + using enum_type = E; + using underlying_type = U; + + static_assert(std::is_enum_v, "Enum must be an enum"); + static_assert(std::is_integral_v, "Enum<..., U> must be an integral"); + + constexpr Enum() noexcept = default; + constexpr Enum(const Enum&) noexcept = default; + constexpr Enum(Enum&&) noexcept = default; + + template // NOLINTNEXTLINE(google-explicit-constructor) + constexpr Enum(Enum a_rhs) noexcept : + _impl(static_cast(a_rhs.get())) + {} + + constexpr Enum(E a_value) noexcept : + _impl(static_cast(a_value)) + {} + + ~Enum() noexcept = default; + + constexpr Enum& operator=(const Enum&) noexcept = default; + constexpr Enum& operator=(Enum&&) noexcept = default; + + template + constexpr Enum& operator=(Enum a_rhs) noexcept + { + _impl = static_cast(a_rhs.get()); + } + + constexpr Enum& operator=(E a_value) noexcept + { + _impl = static_cast(a_value); + return *this; + } + + public: + [[nodiscard]] explicit constexpr operator bool() const noexcept { return _impl != static_cast(0); } + [[nodiscard]] constexpr E operator*() const noexcept { return get(); } + [[nodiscard]] constexpr E get() const noexcept { return static_cast(_impl); } + [[nodiscard]] constexpr U underlying() const noexcept { return _impl; } + + public: + friend constexpr bool operator==(Enum a_lhs, Enum a_rhs) noexcept { return a_lhs.underlying() == a_rhs.underlying(); } + friend constexpr bool operator==(Enum a_lhs, E a_rhs) noexcept { return a_lhs.underlying() == static_cast(a_rhs); } + friend constexpr bool operator==(E a_lhs, Enum a_rhs) noexcept { return static_cast(a_lhs) == a_rhs.underlying(); } + + private: + U _impl{ 0 }; + }; + template + Enum(Args...) -> Enum< + std::common_type_t, + std::underlying_type_t< + std::common_type_t>>; +} + namespace REX { template < diff --git a/CommonLibF4/include/REX/W32.h b/CommonLibF4/include/REX/W32.h index 6deadaa1..b11a7f6e 100644 --- a/CommonLibF4/include/REX/W32.h +++ b/CommonLibF4/include/REX/W32.h @@ -21,6 +21,7 @@ #include "REX/W32/DXGI_5.h" #include "REX/W32/DXGI_6.h" #include "REX/W32/KERNEL32.h" +#include "REX/W32/NT.h" #include "REX/W32/OLE32.h" #include "REX/W32/USER32.h" #include "REX/W32/VERSION.h" diff --git a/CommonLibF4/include/REX/W32/BASE.h b/CommonLibF4/include/REX/W32/BASE.h index 13cce382..1196560a 100644 --- a/CommonLibF4/include/REX/W32/BASE.h +++ b/CommonLibF4/include/REX/W32/BASE.h @@ -162,6 +162,7 @@ namespace REX::W32 }; std::int64_t value; }; + static_assert(sizeof(LARGE_INTEGER) == 0x8); union ULARGE_INTEGER { @@ -172,6 +173,15 @@ namespace REX::W32 }; std::uint64_t value; }; + static_assert(sizeof(ULARGE_INTEGER) == 0x8); + + struct UNICODE_STRING + { + std::uint16_t length; + std::uint16_t maxLength; + wchar_t* buffer; + }; + static_assert(sizeof(UNICODE_STRING) == 0x10); } namespace REX::W32 diff --git a/CommonLibF4/include/REX/W32/NT.h b/CommonLibF4/include/REX/W32/NT.h new file mode 100644 index 00000000..9a410f64 --- /dev/null +++ b/CommonLibF4/include/REX/W32/NT.h @@ -0,0 +1,92 @@ +#pragma once + +#include "REX/W32/BASE.h" + +namespace REX::W32 +{ + struct EXCEPTION_REGISTRATION_RECORD; + struct PEB_LDR_DATA; + struct RTL_USER_PROCESS_PARAMETERS; + struct UNICODE_STRING; + + using PS_POST_PROCESS_INIT_ROUTINE = void (*)(); + + struct LIST_ENTRY + { + struct LIST_ENTRY* fLink; + struct LIST_ENTRY* bLink; + }; + + struct NT_TIB + { + EXCEPTION_REGISTRATION_RECORD* exceptionList; + void* stackBase; + void* stackLimit; + void* subSystemTib; + union + { + void* fiberData; + std::uint32_t version; + }; + void* arbitraryUserPointer; + struct NT_TIB* self; + }; + + struct PEB + { + std::byte reserved1[2]; + std::byte beingDebugged; + std::byte reserved2[1]; + void* reserved3[2]; + PEB_LDR_DATA* ldr; + RTL_USER_PROCESS_PARAMETERS* processParameters; + void* reserved4[3]; + void* atlThunkSListPtr; + void* reserved5; + std::uint32_t reserved6; + void* reserved7; + std::uint32_t reserved8; + std::uint32_t atlThunkSListPtr32; + void* reserved9[45]; + std::byte reserved10[96]; + PS_POST_PROCESS_INIT_ROUTINE postProcessInitRoutine; + std::byte reserved11[128]; + void* reserved12[1]; + std::uint32_t sessionID; + }; + + struct PEB_LDR_DATA + { + std::byte reserved1[8]; + void* reserved2[3]; + LIST_ENTRY inMemoryOrderModuleList; + }; + + struct RTL_USER_PROCESS_PARAMETERS + { + std::byte reserved1[16]; + void* reserved2[10]; + UNICODE_STRING imagePathName; + UNICODE_STRING commandLine; + }; + + struct TEB + { + void* reserved1[11]; + void* threadLocalStoragePointer; + PEB* processEnvironmentBlock; + void* reserved2[399]; + std::byte reserved3[1952]; + void* tlsSlots[64]; + std::byte reserved4[8]; + void* reserved5[26]; + void* reservedForOle; + void* reserved6[4]; + void* tlsExpansionSlots; + }; +} + +namespace REX::W32 +{ + TEB* NtCurrentTeb() noexcept; +} diff --git a/CommonLibF4/src/REX/W32.cpp b/CommonLibF4/src/REX/W32.cpp index 27d40a73..7249caba 100644 --- a/CommonLibF4/src/REX/W32.cpp +++ b/CommonLibF4/src/REX/W32.cpp @@ -5,6 +5,7 @@ #include "REX/W32/DBGHELP.h" #include "REX/W32/DXGI.h" #include "REX/W32/KERNEL32.h" +#include "REX/W32/NT.h" #include "REX/W32/OLE32.h" #include "REX/W32/SHELL32.h" #include "REX/W32/USER32.h" @@ -796,6 +797,16 @@ namespace REX::W32 } } +// NT + +namespace REX::W32 +{ + TEB* NtCurrentTeb() noexcept + { + return reinterpret_cast(__readgsqword(offsetof(NT_TIB, self))); + } +} + // OLE32 REX_W32_IMPORT(void, CoTaskMemFree, void*); diff --git a/CommonLibF4/xmake.lua b/CommonLibF4/xmake.lua index 1d7dc92d..c262d388 100644 --- a/CommonLibF4/xmake.lua +++ b/CommonLibF4/xmake.lua @@ -5,10 +5,18 @@ option("f4se_xbyak", function() add_defines("F4SE_SUPPORT_XBYAK=1") end) +-- require packages +if has_config("f4se_xbyak") then + add_requires("xbyak") +end + -- define targets target("commonlibf4", function() set_kind("static") + -- set build by default + set_default(path.directory(os.scriptdir()) == os.projectdir()) + -- set build group set_group("commonlibf4") @@ -141,6 +149,15 @@ rule("commonlibf4.plugin") target:set("arch", "x64") target:set("kind", "shared") + target:add("installfiles", target:targetfile(), { prefixdir = "F4SE/Plugins" }) + target:add("installfiles", target:symbolfile(), { prefixdir = "F4SE/Plugins" }) + + if os.getenv("XSE_FO4_MODS_PATH") then + target:set("installdir", path.join(os.getenv("XSE_FO4_MODS_PATH"), target:name())) + elseif os.getenv("XSE_FO4_GAME_PATH") then + target:set("installdir", path.join(os.getenv("XSE_FO4_GAME_PATH"), "Data")) + end + local conf = target:extraconf("rules", "commonlibf4.plugin") local conf_dir = path.join(target:autogendir(), "rules", "commonlibf4", "plugin") @@ -186,3 +203,52 @@ rule("commonlibf4.plugin") add_file("plugin.cpp", PLUGIN_FILE) add_file("version.rc", PLUGIN_RC_FILE) end) + + on_install(function(target) + local srcfiles, dstfiles = target:installfiles() + if srcfiles and #srcfiles > 0 and dstfiles and #dstfiles > 0 then + for idx, srcfile in ipairs(srcfiles) do + os.trycp(srcfile, dstfiles[idx]) + end + end + end) + + on_package(function(target) + import("core.project.config") + import("core.project.project") + import("utils.archive") + + local archive_name = target:name() .. "-" .. (target:version() or "0.0.0") .. ".zip" + print("packing %s .. ", archive_name) + + local root_dir = path.join(os.tmpdir(), "packages", project.name() or "", target:name()) + os.tryrm(root_dir) + + local srcfiles, dstfiles = target:installfiles(path.join(root_dir, "Data")) + if srcfiles and #srcfiles > 0 and dstfiles and #dstfiles > 0 then + for idx, srcfile in ipairs(srcfiles) do + os.trycp(srcfile, dstfiles[idx]) + end + else + return + end + + local archive_path = path.join(config.buildir(), "packages", archive_name) + local old_dir = os.cd(root_dir) + local archive_files = os.files("**") + os.cd(old_dir) + archive.archive(path.absolute(archive_path), archive_files, { curdir = root_dir }) + end) + + after_build(function(target) + import("core.project.depend") + import("core.project.project") + import("core.project.task") + + depend.on_changed(function() + local srcfiles, dstfiles = target:installfiles() + if srcfiles and #srcfiles > 0 and dstfiles and #dstfiles > 0 then + task.run("install") + end + end, { changed = target:is_rebuilt(), files = { target:targetfile() } }) + end) diff --git a/xmake.lua b/xmake.lua index 6627ef28..5c4f5c03 100644 --- a/xmake.lua +++ b/xmake.lua @@ -11,7 +11,7 @@ set_encodings("utf-8") add_rules("mode.debug", "mode.releasedbg") -- require packages -add_requires("rsm-binary-io", "rsm-mmio", "xbyak") +add_requires("rsm-binary-io", "rsm-mmio") add_requires("spdlog", { configs = { header_only = false, wchar = true, std_format = true } }) -- include subprojects