From 66c8581fea673d665361adff807b35f45734fbd2 Mon Sep 17 00:00:00 2001 From: powerof3 <32599957+powerof3@users.noreply.github.com> Date: Fri, 15 Sep 2023 03:16:49 +0530 Subject: [PATCH] feat: `PlayerCamera` RE (#48) --- .../include/RE/B/BSInputEventReceiver.h | 19 ++++ CommonLibSF/include/RE/P/PlayerCamera.h | 86 +++++++++++++++++++ CommonLibSF/include/RE/T/TESCamera.h | 36 ++++++++ CommonLibSF/src/RE/P/PlayerCamera.cpp | 48 +++++++++++ CommonLibSF/src/RE/T/TESCamera.cpp | 5 ++ 5 files changed, 194 insertions(+) create mode 100644 CommonLibSF/include/RE/B/BSInputEventReceiver.h create mode 100644 CommonLibSF/include/RE/P/PlayerCamera.h create mode 100644 CommonLibSF/include/RE/T/TESCamera.h create mode 100644 CommonLibSF/src/RE/P/PlayerCamera.cpp create mode 100644 CommonLibSF/src/RE/T/TESCamera.cpp diff --git a/CommonLibSF/include/RE/B/BSInputEventReceiver.h b/CommonLibSF/include/RE/B/BSInputEventReceiver.h new file mode 100644 index 00000000..def64e81 --- /dev/null +++ b/CommonLibSF/include/RE/B/BSInputEventReceiver.h @@ -0,0 +1,19 @@ +#pragma once + +namespace RE +{ + class InputEvent; + + class BSInputEventReceiver + { + public: + virtual ~BSInputEventReceiver() = default; // 00 + + // add + virtual void PerformInputProcessing(const InputEvent* a_queueHead) = 0; // 01 + + // members + std::uint32_t currInputTimeCount; // 08 + }; + static_assert(sizeof(BSInputEventReceiver) == 0x10); +} diff --git a/CommonLibSF/include/RE/P/PlayerCamera.h b/CommonLibSF/include/RE/P/PlayerCamera.h new file mode 100644 index 00000000..f01b1d3f --- /dev/null +++ b/CommonLibSF/include/RE/P/PlayerCamera.h @@ -0,0 +1,86 @@ +#pragma once + +#include "RE/B/BSInputEventReceiver.h" +#include "RE/B/BSTEvent.h" +#include "RE/T/TESCamera.h" + +namespace RE +{ + class BSWorldOriginShiftEvent; + class OtherEventEnabledEvent; + class UserEventEnabledEvent; + struct IdleInputEvent; + + namespace Spaceship + { + struct TakeOffEvent; + struct DockEvent; + struct LandedSetEvent; + } + + struct CameraStates + { + enum CameraState : std::uint32_t + { + kFirstPerson = 0, + kAutoVanity, + kVATS, + kIronSights, + kPCTransition, + kTween, + kUnk06, + kFlightCamera, + kShipFarTravel, + kShipAction, + kShipTargeting, + kShipCombatOrbit, + kFreeWalk, + kFreeAdvanced, + kFreeFly, + kFreeTethered, + kDialogue, + kWorkshopIsometric, + kPhotoMode, + kThirdPerson, + kFurniture, + kHorse, + kBleedout + }; + }; + using CameraState = CameraStates::CameraState; + + class PlayerCamera : + public TESCamera, // 00 + public BSInputEventReceiver, // 48 + public BSTEventSink, // 58 + public BSTEventSink, // 60 + public BSTEventSink, // 68 + public BSTEventSink, // 70 + public BSTEventSink, // 78 + public BSTEventSink, // 80 + public BSTEventSink // 88 + { + public: + SF_RTTI_VTABLE(PlayerCamera); + + ~PlayerCamera() override; // 00 + + // override (TESCamera) + void SetCameraRoot(NiNode* a_root) override; // 01 + void SetEnabled(bool a_enabled) override; // 02 + void Unk_04() override; // 04 + + static PlayerCamera* GetSingleton(); + + void ForceFirstPerson(); + void ForceThirdPerson(); + bool IsInFirstPerson() const; + bool IsInThirdPerson() const; + void SetCameraState(CameraState a_cameraState); + + // More... + + private: + bool QCameraEquals(CameraState a_cameraState) const; + }; +} diff --git a/CommonLibSF/include/RE/T/TESCamera.h b/CommonLibSF/include/RE/T/TESCamera.h new file mode 100644 index 00000000..dd93f87c --- /dev/null +++ b/CommonLibSF/include/RE/T/TESCamera.h @@ -0,0 +1,36 @@ +#pragma once + +namespace RE +{ + class NiNode; + + class TESCamera + { + public: + SF_RTTI(TESCamera); + + virtual ~TESCamera(); // 00 + + // add + virtual void SetCameraRoot(NiNode* a_cameraRoot); // 01 + virtual void SetEnabled(bool a_enabled); // 02 + virtual void Update(); // 03 + virtual void Unk_04(); // 04 + + // members + void* cameraRoot; // 08 - NiPointer + void* currentState; // 10 - BSTSmartPointer + std::uint64_t unk18; // 18 + bool enabled; // 20 + float unk24; // 24 + float unk28; // 28 + float unk2C; // 2C + float unk30; // 30 + float unk34; // 34 + float unk38; // 38 + float unk3C; // 3C + float unk40; // 40 + std::uint32_t pad44; // 44 + }; + static_assert(sizeof(TESCamera) == 0x48); +} diff --git a/CommonLibSF/src/RE/P/PlayerCamera.cpp b/CommonLibSF/src/RE/P/PlayerCamera.cpp new file mode 100644 index 00000000..b5f0be44 --- /dev/null +++ b/CommonLibSF/src/RE/P/PlayerCamera.cpp @@ -0,0 +1,48 @@ +#include "RE/P/PlayerCamera.h" + +namespace RE +{ + PlayerCamera* PlayerCamera::GetSingleton() + { + REL::Relocation singleton{ REL::Offset(0x058F1978) }; + return *singleton; + } + + void PlayerCamera::ForceFirstPerson() + { + using func_t = decltype(&PlayerCamera::ForceFirstPerson); + REL::Relocation func{ REL::Offset(0x0286A798) }; + return func(this); + } + + void PlayerCamera::ForceThirdPerson() + { + using func_t = decltype(&PlayerCamera::ForceThirdPerson); + REL::Relocation func{ REL::Offset(0x0286A850) }; + return func(this); + } + + bool PlayerCamera::IsInFirstPerson() const + { + return QCameraEquals(CameraState::kFirstPerson); + } + + bool PlayerCamera::IsInThirdPerson() const + { + return QCameraEquals(CameraState::kThirdPerson); + } + + void PlayerCamera::SetCameraState(CameraState a_cameraState) + { + using func_t = decltype(&PlayerCamera::SetCameraState); + REL::Relocation func{ REL::Offset(0x0286BCBC) }; + return func(this, a_cameraState); + } + + bool PlayerCamera::QCameraEquals(CameraState a_cameraState) const + { + using func_t = decltype(&PlayerCamera::QCameraEquals); + REL::Relocation func{ REL::Offset(0x0286BDC8) }; + return func(this, a_cameraState); + } +} diff --git a/CommonLibSF/src/RE/T/TESCamera.cpp b/CommonLibSF/src/RE/T/TESCamera.cpp new file mode 100644 index 00000000..9fffa87c --- /dev/null +++ b/CommonLibSF/src/RE/T/TESCamera.cpp @@ -0,0 +1,5 @@ +#include "RE/T/TESCamera.h" +namespace RE +{ +} +