From 70489f2b3091ecc497b63f6d588fcd4da89ac325 Mon Sep 17 00:00:00 2001 From: Eddoursul Date: Mon, 11 Dec 2023 09:53:57 +0100 Subject: [PATCH] Interruptible cutscenes --- SKSE/Plugins/EnderalSE.dll | 4 +- SKSE/Plugins/EnderalSE.ini | 1 + source/Enderal DLL/src/BinkInterruptPatch.h | 42 +++++++++++++++++++++ source/Enderal DLL/src/Main.cpp | 9 ++++- 4 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 source/Enderal DLL/src/BinkInterruptPatch.h diff --git a/SKSE/Plugins/EnderalSE.dll b/SKSE/Plugins/EnderalSE.dll index d7e9b50e..91fdcee0 100644 --- a/SKSE/Plugins/EnderalSE.dll +++ b/SKSE/Plugins/EnderalSE.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f434a341dd7afe4d276460075a77e297f9d8952b38c9940cd09a4ea5d0fb868d -size 731648 +oid sha256:9e5fea3850113301eb73a3e71e93e383969a09e1d86bc1a0cbc5f719304ca627 +size 733184 diff --git a/SKSE/Plugins/EnderalSE.ini b/SKSE/Plugins/EnderalSE.ini index 41d5266f..fe08a136 100644 --- a/SKSE/Plugins/EnderalSE.ini +++ b/SKSE/Plugins/EnderalSE.ini @@ -2,3 +2,4 @@ FlatMapMarkers = true StayAtSystemPage = true MapMarkerPlacementFixes = true AchievementFix = true +VideoInterruptPatch = true diff --git a/source/Enderal DLL/src/BinkInterruptPatch.h b/source/Enderal DLL/src/BinkInterruptPatch.h new file mode 100644 index 00000000..1af3751c --- /dev/null +++ b/source/Enderal DLL/src/BinkInterruptPatch.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#pragma comment(lib, "XInput.lib") + +namespace BinkInterruptPatch +{ + struct BinkListener + { + static bool thunk() + { + auto result = func(); + + if (SKSE::WinAPI::GetKeyState(VK_SPACE) & 0x8000 || SKSE::WinAPI::GetKeyState(VK_ESCAPE) & 0x8000 || SKSE::WinAPI::GetKeyState(VK_LBUTTON) & 0x8000 || SKSE::WinAPI::GetKeyState(VK_RBUTTON) & 0x8000) { + return false; + } + + if (RE::BSInputDeviceManager::GetSingleton()->IsGamepadEnabled()) { + for (DWORD index = 0; index < XUSER_MAX_COUNT; index++) { + XINPUT_STATE state; + if (XInputGetState(index, &state) == ERROR_SUCCESS) { + if ((state.Gamepad.wButtons & XINPUT_GAMEPAD_A) || (state.Gamepad.wButtons & XINPUT_GAMEPAD_START)) { + return false; + } + } + } + } + + return result; + } + static inline REL::Relocation func; + }; + + void Install() + { + REL::Relocation target{ REL::RelocationID(87887, 90256), REL::Relocate(0x9F, 0x16F) }; + auto& trampoline = SKSE::GetTrampoline(); + + SKSE::AllocTrampoline(14); + BinkListener::func = trampoline.write_call<5>(target.address(), BinkListener::thunk); + } +} diff --git a/source/Enderal DLL/src/Main.cpp b/source/Enderal DLL/src/Main.cpp index 0aea79b6..14d6c53e 100644 --- a/source/Enderal DLL/src/Main.cpp +++ b/source/Enderal DLL/src/Main.cpp @@ -5,6 +5,7 @@ #include "StayAtSystemPage.h" #include "MapMarkerPlacement.h" #include "AchievementFix.h" +#include "BinkInterruptPatch.h" using namespace SKSE; @@ -12,7 +13,8 @@ static std::map g_settings{ { "FlatMapMarkers", true }, { "StayAtSystemPage", true }, { "MapMarkerPlacementFixes", true }, - { "AchievementFix", true } + { "AchievementFix", true }, + { "VideoInterruptPatch", true } }; namespace { @@ -161,6 +163,11 @@ SKSEPluginLoad(const LoadInterface* skse) { GetPapyrusInterface()->Register(Papyrus::Bind); + if (g_settings.at("VideoInterruptPatch")) { + logger::info("Making videos interruptible..."); + BinkInterruptPatch::Install(); + } + if (g_settings.at("AchievementFix")) { logger::info("Patching achievements..."); AchievementFix::Install();