diff --git a/SilentHillF/SDK/WBP_Cutscene_classes.hpp b/SilentHillF/SDK/WBP_Cutscene_classes.hpp new file mode 100644 index 0000000..42dbb7b --- /dev/null +++ b/SilentHillF/SDK/WBP_Cutscene_classes.hpp @@ -0,0 +1,98 @@ +#pragma once + +/* +* SDK generated by Dumper-7 +* +* https://github.com/Encryqed/Dumper-7 +*/ + +// Package: WBP_Cutscene + +#include "Basic.hpp" + +#include "Engine_structs.hpp" +#include "GameNoce_structs.hpp" +#include "GameNoce_classes.hpp" +#include "NeoAudio_structs.hpp" +#include "UMG_structs.hpp" + + +namespace SDK +{ + +// WidgetBlueprintGeneratedClass WBP_Cutscene.WBP_Cutscene_C +// 0x0160 (0x0530 - 0x03D0) +class UWBP_Cutscene_C final : public UNoceCutsceneWidget +{ +public: + struct FPointerToUberGraphFrame UberGraphFrame; // 0x03D0(0x0008)(ZeroConstructor, Transient, DuplicateTransient) + class UOverlay* GuideOverlay; // 0x03D8(0x0008)(BlueprintVisible, ExportObject, BlueprintReadOnly, ZeroConstructor, DisableEditOnInstance, InstancedReference, RepSkip, NoDestructor, PersistentInstance, HasGetValueTypeHash) + class UCanvasPanel* LeftGroup; // 0x03E0(0x0008)(BlueprintVisible, ExportObject, BlueprintReadOnly, ZeroConstructor, DisableEditOnInstance, InstancedReference, RepSkip, NoDestructor, PersistentInstance, HasGetValueTypeHash) + class UCanvasPanel* LeftGroup_1; // 0x03E8(0x0008)(BlueprintVisible, ExportObject, BlueprintReadOnly, ZeroConstructor, DisableEditOnInstance, InstancedReference, RepSkip, NoDestructor, PersistentInstance, HasGetValueTypeHash) + class UCanvasPanel* LeftGroup_2; // 0x03F0(0x0008)(BlueprintVisible, ExportObject, BlueprintReadOnly, ZeroConstructor, DisableEditOnInstance, InstancedReference, RepSkip, NoDestructor, PersistentInstance, HasGetValueTypeHash) + class UOverlay* PauseOverlay; // 0x03F8(0x0008)(BlueprintVisible, ExportObject, BlueprintReadOnly, ZeroConstructor, DisableEditOnInstance, InstancedReference, RepSkip, NoDestructor, PersistentInstance, HasGetValueTypeHash) + class UCanvasPanel* RightGroup; // 0x0400(0x0008)(BlueprintVisible, ExportObject, BlueprintReadOnly, ZeroConstructor, DisableEditOnInstance, InstancedReference, RepSkip, NoDestructor, PersistentInstance, HasGetValueTypeHash) + class UCanvasPanel* RightGroup_1; // 0x0408(0x0008)(BlueprintVisible, ExportObject, BlueprintReadOnly, ZeroConstructor, DisableEditOnInstance, InstancedReference, RepSkip, NoDestructor, PersistentInstance, HasGetValueTypeHash) + class UCanvasPanel* RightGroup_2; // 0x0410(0x0008)(BlueprintVisible, ExportObject, BlueprintReadOnly, ZeroConstructor, DisableEditOnInstance, InstancedReference, RepSkip, NoDestructor, PersistentInstance, HasGetValueTypeHash) + class UWBP_CommonGuideItem_C* WBP_CommonGuideItem; // 0x0418(0x0008)(BlueprintVisible, ExportObject, BlueprintReadOnly, ZeroConstructor, DisableEditOnInstance, InstancedReference, RepSkip, NoDestructor, PersistentInstance, HasGetValueTypeHash) + class UWBP_SkipIcon_C* WBP_SkipIcon; // 0x0420(0x0008)(BlueprintVisible, ExportObject, BlueprintReadOnly, ZeroConstructor, DisableEditOnInstance, InstancedReference, RepSkip, NoDestructor, PersistentInstance, HasGetValueTypeHash) + TSoftClassPtr CSSkipWidgetPath; // 0x0428(0x0028)(Edit, BlueprintVisible, DisableEditOnInstance, HasGetValueTypeHash) + struct FTimerHandle HideGuideTimer; // 0x0450(0x0008)(Edit, BlueprintVisible, DisableEditOnInstance, NoDestructor, HasGetValueTypeHash) + class ALevelSequenceActor* SequenceActor; // 0x0458(0x0008)(Edit, BlueprintVisible, ZeroConstructor, DisableEditOnTemplate, DisableEditOnInstance, NoDestructor, HasGetValueTypeHash) + class FName CutsceneName; // 0x0460(0x0008)(Edit, BlueprintVisible, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash) + bool IsNew; // 0x0468(0x0001)(Edit, BlueprintVisible, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash) + uint8 Pad_469[0x7]; // 0x0469(0x0007)(Fixing Size After Last Property [ Dumper-7 ]) + class UNoceCutsceneSkipWidget* CutsceneWidget; // 0x0470(0x0008)(Edit, BlueprintVisible, ZeroConstructor, DisableEditOnInstance, InstancedReference, NoDestructor, HasGetValueTypeHash) + struct FNeoAudioTriggerIdHandle PopWindowFadeInSound; // 0x0478(0x0008)(Edit, BlueprintVisible, DisableEditOnInstance, NoDestructor) + struct FNeoAudioTriggerIdHandle PopWindowConfirmSound; // 0x0480(0x0008)(Edit, BlueprintVisible, DisableEditOnInstance, NoDestructor) + struct FNeoAudioTriggerIdHandle PopWindowCancelSound; // 0x0488(0x0008)(Edit, BlueprintVisible, DisableEditOnInstance, NoDestructor) + struct FNeoAudioTriggerIdHandle PauseTriggerId; // 0x0490(0x0008)(Edit, BlueprintVisible, DisableEditOnInstance, NoDestructor) + struct FNeoAudioTriggerIdHandle ResumeTriggerId; // 0x0498(0x0008)(Edit, BlueprintVisible, DisableEditOnInstance, NoDestructor) + bool IsPausedByMessage; // 0x04A0(0x0001)(Edit, BlueprintVisible, ZeroConstructor, DisableEditOnInstance, IsPlainOldData, NoDestructor, HasGetValueTypeHash) + uint8 Pad_4A1[0x7]; // 0x04A1(0x0007)(Fixing Size After Last Property [ Dumper-7 ]) + TArray BinkPlayToolList; // 0x04A8(0x0010)(Edit, BlueprintVisible, DisableEditOnTemplate, DisableEditOnInstance) + class UNeoAudioDataTable* Audio_CSPauseDataTable; // 0x04B8(0x0008)(Edit, BlueprintVisible, ZeroConstructor, DisableEditOnInstance, NoDestructor, HasGetValueTypeHash) + struct FNeoAudioPostEventParam Audio_StopCSPauseSilence; // 0x04C0(0x0070)(Edit, BlueprintVisible, DisableEditOnInstance) + +public: + void Audio_HandleCSPause(); + void Audio_PostCSPauseSilence(const struct FNeoAudioPostEventParam& InAudioPostEventParam); + void BinkPlay(bool IsPlay); + void BP_HideCommon(bool* NoUse); + void BP_ShowCommon(bool* NoUse); + void ExecuteUbergraph_WBP_Cutscene(int32 EntryPoint); + void GetPopWindowWidget(); + bool HandleNotRepeatKeys(const struct FInputEvent& InInputEvent, const struct FKey& InKey); + void HideGuides(); + void OnInitialized(); + struct FEventReply OnKeyUp(const struct FGeometry& MyGeometry, const struct FKeyEvent& InKeyEvent); + void OnPopWindowClose(); + void OnSkipHoldComplete(); + void Pause(); + void Resume(); + void SetAutoHideTimer(); + void SetCanSkip(bool InCanSkip, bool* NoUse); + void SetHasCamera(bool InHasCamera, bool* NoUse); + void SetSequenceActor(class ALevelSequenceActor* InActor, bool* NoUse); + void ShowGuides(bool NeedCancel, bool NeedPause, bool NeedHold); + void StopAndReleaseBinkTool(); + void Tick(const struct FGeometry& MyGeometry, float InDeltaTime); + +public: + static class UClass* StaticClass() + { + BP_STATIC_CLASS_IMPL("WBP_Cutscene_C") + } + static const class FName& StaticName() + { + STATIC_NAME_IMPL(L"WBP_Cutscene_C") + } + static class UWBP_Cutscene_C* GetDefaultObj() + { + return GetDefaultObjImpl(); + } +}; +DUMPER7_ASSERTS_UWBP_Cutscene_C; + +} + diff --git a/SilentHillF/dllmain.cpp b/SilentHillF/dllmain.cpp index 3fdcc03..aaed0d9 100644 --- a/SilentHillF/dllmain.cpp +++ b/SilentHillF/dllmain.cpp @@ -10,6 +10,7 @@ #include "UEngine.hpp"; #include "SDK/Basic.hpp" #include "SDK/Engine_classes.hpp" +#include "SDK/WBP_Cutscene_classes.hpp" using namespace SDK; // Unreal Engine variables @@ -36,6 +37,8 @@ static bool g_Volumetric_Fog_fix_enabled = false; static bool g_Fog_Density_fix_enabled = false; static bool g_Fog_Max_Opacity_fix_enabled = false; static bool g_Camera_fix_enabled = false; +static bool g_Cutscenes_fix_enabled = false; +static bool g_Cutscenes_FPS_fix_enabled = false; static int g_AdditionalFOVValue = 0; static float g_CameraDistance = 1.f; static float g_FogDensity = 0.4f; @@ -67,6 +70,10 @@ static uint8_t* VolumetricFogEngineaddress_2 = nullptr; static uint8_t* FogDensityEngineaddress = nullptr; static uint8_t* FogOpacityEngineaddress = nullptr; static uint8_t* Cameraaddress = nullptr; +static uint8_t* Cutscenesaddress = nullptr; +static uint8_t* CutscenesFPSaddress = nullptr; +static uint8_t* ConstrainAspectRatioaddress = nullptr; +static uint8_t* AspectRatioAxisConstraintaddress = nullptr; // Hooking static SafetyHookMid FOVHook{}; @@ -75,6 +82,10 @@ static SafetyHookMid VolumetricFogHook{}; static SafetyHookMid FogDensityHook{}; static SafetyHookMid FogMaxOpacityHook{}; static SafetyHookMid CameraHook{}; +static SafetyHookMid CutscenesHook{}; +static SafetyHookMid CutscenesFPSHook{}; +static SafetyHookMid ConstrainAspectRatioHook{}; +static SafetyHookMid AspectRatioAxisConstraintHook{}; // Prototypes static void FOVFixEnabled(); @@ -87,6 +98,8 @@ static void FogDensityFixEnabled(); static void FogOpacityFixEnabled(); static void CameraFixEnabled(); static void EnableConsole(); +static void CutscenesFixEnabled(); +static void CutscenesFPSFixEnabled(); extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled) { @@ -104,9 +117,8 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled) if (!FOVaddress) logger->warn("FOV signature not found. Maybe your game has been updated and is no more compatible with this plugin."); - else { + else logger->info("FOV signature found at address: 0x{:X}.", reinterpret_cast(FOVaddress)); - } } if (DOFaddress == nullptr) { @@ -120,9 +132,8 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled) if (!DOFaddress) logger->warn("DOF signature not found. Maybe your game has been updated and is no more compatible with this plugin."); - else { + else logger->info("DOF signature found at address: 0x{:X}.", reinterpret_cast(DOFaddress)); - } } if (CAaddress == nullptr) { @@ -136,9 +147,8 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled) if (!CAaddress) logger->warn("Chromatic aberrations signature not found. Maybe your game has been updated and is no more compatible with this plugin."); - else { + else logger->info("Chromatic aberrations signature found at address: 0x{:X}.", reinterpret_cast(CAaddress)); - } } if (Vignettingaddress == nullptr) { @@ -203,9 +213,8 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled) if (!VolumetricFogEngineaddress_2) logger->warn("Volumetric fog signature not found. Maybe your game has been updated and is no more compatible with this plugin."); - else { + else logger->info("Volumetric Fog signature found at address: 0x{:X}.", reinterpret_cast(VolumetricFogEngineaddress_2)); - } } if (FogDensityEngineaddress == nullptr) { @@ -253,12 +262,55 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled) if (!Cameraaddress) logger->warn("Camera signature not found. Maybe your game has been updated and is no more compatible with this plugin."); - else { + else logger->info("Camera signature found at address: 0x{:X}.", reinterpret_cast(Cameraaddress)); + } + + if (!Cutscenesaddress) { + constexpr auto Cutscenes1StringObfuscated = make_obfuscated<0x4A>("48 ?? ?? ?? ?? ?? ?? 48 8B ?? 48 8B ?? 8D ?? 01 89 ?? ?? ?? ?? ?? 3B ?? ?? ?? ?? ?? 76 ?? 8B ?? 48 81 ?? ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 8B ?? ?? ?? ?? ?? 48 8D"); + Cutscenesaddress = Memory::AOBScan(gameExecutable, Cutscenes1StringObfuscated.decrypt(), PAGE_EXECUTE_READ); + + if (!Cutscenesaddress) + logger->warn("Cutscenes signature not found. Maybe your game has been updated and is no more compatible with this plugin."); + else + logger->info("Cutscenes signature found at address: 0x{:X}.", reinterpret_cast(Cutscenesaddress)); + } + + if (!ConstrainAspectRatioaddress) { + constexpr auto ConstrainAspectRatioaddressStringObfuscated = make_obfuscated<0x4A>("89 ?? ?? 0F B6 ?? ?? ?? ?? ?? D1 ?? 33 ?? 83 ?? 02 33 ?? 89"); + ConstrainAspectRatioaddress = Memory::AOBScan(gameExecutable, ConstrainAspectRatioaddressStringObfuscated.decrypt(), PAGE_EXECUTE_READ); + + if (!ConstrainAspectRatioaddress) + logger->warn("Constrain aspect ratio signature not found. Maybe your game has been updated and is no more compatible with this plugin."); + else + logger->info("Constrain aspect ratio signature found at address: 0x{:X}.", reinterpret_cast(ConstrainAspectRatioaddress)); + } + + if (!AspectRatioAxisConstraintaddress) { + constexpr auto AspectRatioAxisConstraintaddressStringObfuscated = make_obfuscated<0x4A>("48 ?? ?? ?? ?? 00 00 4C ?? ?? 4D ?? ?? E8 ?? ?? ?? ?? 48 8B"); + AspectRatioAxisConstraintaddress = Memory::AOBScan(gameExecutable, AspectRatioAxisConstraintaddressStringObfuscated.decrypt(), PAGE_EXECUTE_READ); + + if (!AspectRatioAxisConstraintaddress) + logger->warn("Aspect Ratio Axis Constraint signature not found. Maybe your game has been updated and is no more compatible with this plugin."); + else + logger->info("Aspect Ratio Axis Constraint signature found at address: 0x{:X}.", reinterpret_cast(AspectRatioAxisConstraintaddress)); + } + + if (!CutscenesFPSaddress) { + constexpr auto CutscenesFPSStringObfuscated = make_obfuscated<0x4A>("FF 50 ?? 40 38 ?? ?? ?? ?? ?? 75 ?? 40 38 ?? ?? ?? ?? ?? 75"); + CutscenesFPSaddress = Memory::AOBScan(gameExecutable, CutscenesFPSStringObfuscated.decrypt(), PAGE_EXECUTE_READ); + + if (!CutscenesFPSaddress) + logger->warn("Cutscenes framerate signature not found. Maybe your game has been updated and is no more compatible with this plugin."); + else { + logger->info("Cutscenes framerate signature found at address: 0x{:X}.", reinterpret_cast(CutscenesFPSaddress)); + CutscenesFPSaddress += 0x3; } } - if (FOVaddress && Cameraaddress && DOFaddress && CAaddress && Vignettingaddress && Fogaddress) { + if (FOVaddress && Cameraaddress && DOFaddress && CAaddress && Vignettingaddress && Fogaddress && VolumetricFogEngineaddress_1 && + VolumetricFogEngineaddress_2 && FogDensityEngineaddress && FogOpacityEngineaddress && Cutscenesaddress && ConstrainAspectRatioaddress && + AspectRatioAxisConstraintaddress && CutscenesFPSaddress) { logger->info("All AOB signatures found. Ready to patch..."); AOBScanDone = true; } @@ -324,6 +376,10 @@ extern "C" __declspec(dllexport) void SetFixEnabled(bool enabled) if (Fogaddress && VolumetricFogEngineaddress_1 && VolumetricFogEngineaddress_2) VolumetricFogFixEnabled(); if (Fogaddress && FogDensityEngineaddress) FogDensityFixEnabled(); if (Fogaddress && FogOpacityEngineaddress) FogOpacityFixEnabled(); + if (Cutscenesaddress && ConstrainAspectRatioaddress) + CutscenesFixEnabled(); + if (CutscenesFPSaddress) + CutscenesFPSFixEnabled(); if (!g_Console_Enabled && GObjectsaddress && GNamesaddress && AppendStringaddress && ProcessEventaddress) EnableConsole(); } @@ -386,6 +442,18 @@ extern "C" __declspec(dllexport) void SetCameraFixEnabled(bool enabled, bool ini if (!init) CameraFixEnabled(); } +extern "C" __declspec(dllexport) void SetCutscenesFixEnabled(bool enabled, bool init) +{ + g_Cutscenes_fix_enabled = enabled; + if (!init) CutscenesFixEnabled(); +} + +extern "C" __declspec(dllexport) void SetCutscenesFPSFixEnabled(bool enabled, bool init) +{ + g_Cutscenes_FPS_fix_enabled = enabled; + if (!init) CutscenesFPSFixEnabled(); +} + extern "C" __declspec(dllexport) void SetFOV(int fov) { g_AdditionalFOVValue = fov; @@ -548,6 +616,52 @@ static void FogOpacityFixEnabled() { } } +static void CutscenesFixEnabled() { + if (!CutscenesHook) + CutscenesHook = safetyhook::create_mid(Cutscenesaddress, + [](SafetyHookContext& ctx) { + auto object = reinterpret_cast(ctx.rdx); + if (!object || !object->Class || !object->Class->Class) return; + + if (object->GetName().contains("WBP_Cutscene_C") && object->IsA(UWBP_Cutscene_C::StaticClass())) { + auto cutscene = static_cast(object); + + if (cutscene) { + cutscene->LeftGroup->SetVisibility(g_fix_enabled && g_Cutscenes_fix_enabled ? ESlateVisibility::Collapsed : ESlateVisibility::SelfHitTestInvisible); + cutscene->LeftGroup_1->SetVisibility(g_fix_enabled && g_Cutscenes_fix_enabled ? ESlateVisibility::Collapsed : ESlateVisibility::SelfHitTestInvisible); + cutscene->LeftGroup_2->SetVisibility(g_fix_enabled && g_Cutscenes_fix_enabled ? ESlateVisibility::Collapsed : ESlateVisibility::SelfHitTestInvisible); + cutscene->RightGroup->SetVisibility(g_fix_enabled && g_Cutscenes_fix_enabled ? ESlateVisibility::Collapsed : ESlateVisibility::SelfHitTestInvisible); + cutscene->RightGroup_1->SetVisibility(g_fix_enabled && g_Cutscenes_fix_enabled ? ESlateVisibility::Collapsed : ESlateVisibility::SelfHitTestInvisible); + cutscene->RightGroup_2->SetVisibility(g_fix_enabled && g_Cutscenes_fix_enabled ? ESlateVisibility::Collapsed : ESlateVisibility::SelfHitTestInvisible); + } + } + }); + // Force cutscenes rendering full screeen + if (g_fix_enabled && g_Cutscenes_fix_enabled && !ConstrainAspectRatioHook) { + ConstrainAspectRatioHook = safetyhook::create_mid(ConstrainAspectRatioaddress, + [](SafetyHookContext& ctx) { + ctx.rcx = 0; // bConstrainAspectRatio + }); + logger->info("Cutscenes ultrawide fix enabled"); + } + // FOV compensation + if (g_fix_enabled && g_Cutscenes_fix_enabled && !AspectRatioAxisConstraintHook) + AspectRatioAxisConstraintHook = safetyhook::create_mid(AspectRatioAxisConstraintaddress, + [](SafetyHookContext& ctx) { + ctx.rdx = 0; // AspectRatioAxisConstraint Y + }); +} + +static void CutscenesFPSFixEnabled() { + if (g_fix_enabled && g_Cutscenes_FPS_fix_enabled) { + CutscenesFPSHook = safetyhook::create_mid(CutscenesFPSaddress, + [](SafetyHookContext& ctx) { + *reinterpret_cast(ctx.rbx + 0x310) = 1; + }); + logger->info("Cutscenes FPS unlocker fix enabled"); + } +} + // Memory patch fixes static void DOFFixEnabled() { if (g_fix_enabled && g_DOF_fix_enabled && DOFaddress) {