From afa68ffd257b43450d7a4f6f47deb19fc1585040 Mon Sep 17 00:00:00 2001 From: Eddoursul Date: Sat, 20 Jan 2024 19:27:05 +0100 Subject: [PATCH] Force borderless mode with INI toggle, a workaround for freezing during Bink playback --- README.md | 5 ++-- SKSE/Plugins/EnderalSE.ini | 1 + source/Enderal DLL/src/Main.cpp | 11 +++++-- .../Enderal DLL/src/Patches/AchievementFix.h | 2 +- .../Enderal DLL/src/Patches/ForceBorderless.h | 30 +++++++++++++++++++ 5 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 source/Enderal DLL/src/Patches/ForceBorderless.h diff --git a/README.md b/README.md index 81f7c486..11847ced 100644 --- a/README.md +++ b/README.md @@ -12,15 +12,16 @@ - [Scrambled Bugs](https://www.nexusmods.com/skyrimspecialedition/mods/43532) - [powerofthree's Tweaks](https://www.nexusmods.com/skyrimspecialedition/mods/51073) - [Fix Note icon for SkyUI](https://www.nexusmods.com/skyrimspecialedition/mods/32561) -- [.NET Script Framework](https://www.nexusmods.com/skyrimspecialedition/mods/21294) (SE) or [Crash Logger](https://www.nexusmods.com/skyrimspecialedition/mods/59596) (AE) +- [Crash Logger](https://www.nexusmods.com/skyrimspecialedition/mods/59818) (SE/AE/VR) -## How to play +## How to run - Add a new Skyrim SE instance to Mod Organizer 2. - Creation Club mods must be moved to a separate mod and disabled. - In MO2, create an empty mod, name it `Enderal SE - Media`, and copy `E - Sounds.bsa`, `L - Voices.bsa`, and the `Video` directory to it. - This repository uses LFS to store binary files, run `git lfs install` before cloning it. - Clone this repository, move it to `mods` in your MO2 instance. - You should now have two custom mods in MO2, `Enderal SE - Media` and Enderal itself. +- Build EnderalSE.dll. - Configure the game through Skyrim Launcher. - Run it with skse64_loader.exe through MO2. diff --git a/SKSE/Plugins/EnderalSE.ini b/SKSE/Plugins/EnderalSE.ini index fe08a136..d19e623b 100644 --- a/SKSE/Plugins/EnderalSE.ini +++ b/SKSE/Plugins/EnderalSE.ini @@ -3,3 +3,4 @@ StayAtSystemPage = true MapMarkerPlacementFixes = true AchievementFix = true VideoInterruptPatch = true +ForceBorderless = true diff --git a/source/Enderal DLL/src/Main.cpp b/source/Enderal DLL/src/Main.cpp index ce9a0cf7..20c00262 100644 --- a/source/Enderal DLL/src/Main.cpp +++ b/source/Enderal DLL/src/Main.cpp @@ -10,6 +10,7 @@ #include "Patches/TweenMenuPatch.h" #include "Patches/HeroMenuPatch.h" #include "Patches/HUDMenuPatch.h" +#include "Patches/ForceBorderless.h" using namespace SKSE; @@ -18,7 +19,8 @@ static std::map g_settings{ { "StayAtSystemPage", true }, { "MapMarkerPlacementFixes", true }, { "AchievementFix", true }, - { "VideoInterruptPatch", true } + { "VideoInterruptPatch", true }, + { "ForceBorderless", true } }; namespace { @@ -63,9 +65,9 @@ namespace { MapMarkerPlacement::Install(); } } else if (message->type == MessagingInterface::kDataLoaded) { - if (GetLoadInterface()->RuntimeVersion().minor() > 5) { + if (REL::Module::get().version() > REL::Version(1, 5, 97, 0)) { RE::INIPrefSettingCollection::GetSingleton()->GetSetting("bFreebiesSeen:General")->data.b = true; - if (GetLoadInterface()->RuntimeVersion().minor() > 6 || GetLoadInterface()->RuntimeVersion().patch() >= 1130) { + if (REL::Module::get().version() >= REL::Version(1, 6, 1130, 0)) { RE::INIPrefSettingCollection::GetSingleton()->GetSetting("bUpsellOwned:General")->data.b = true; } } @@ -187,6 +189,9 @@ SKSEPluginLoad(const LoadInterface* skse) { } if (!REL::Module::IsVR()) { + if (g_settings.at("ForceBorderless")) { + ForceBorderless::Install(); + } if (g_settings.at("FlatMapMarkers")) { logger::info("Initializing Flat Map Markers..."); FlatMapMarkers::Install(); diff --git a/source/Enderal DLL/src/Patches/AchievementFix.h b/source/Enderal DLL/src/Patches/AchievementFix.h index 72f7c81f..64c1e9e4 100644 --- a/source/Enderal DLL/src/Patches/AchievementFix.h +++ b/source/Enderal DLL/src/Patches/AchievementFix.h @@ -6,7 +6,7 @@ namespace AchievementFix { REL::Relocation target; - if (GetLoadInterface()->RuntimeVersion().minor() > 6 || GetLoadInterface()->RuntimeVersion().patch() >= 1130) { + if (REL::Module::get().version() >= REL::Version(1, 6, 1130, 0)) { // Checked: 1.6.1130 target = REL::ID(441528); } else { diff --git a/source/Enderal DLL/src/Patches/ForceBorderless.h b/source/Enderal DLL/src/Patches/ForceBorderless.h new file mode 100644 index 00000000..b4b48cdd --- /dev/null +++ b/source/Enderal DLL/src/Patches/ForceBorderless.h @@ -0,0 +1,30 @@ +#pragma once + +// Bink playback is prone to freezing in bordered window, we enforce borderless mode here +namespace ForceBorderless +{ + void Install() + { + if (REL::Module::IsVR()) { + return; + } + + std::uint8_t code[] = { 0xB8, 0x01, 0x00, 0x00, 0x00, REL::NOP, REL::NOP }; // mov eax,0x1 + auto version = REL::Module::get().version(); + + if (version >= REL::Version(1, 6, 1130, 0) && version <= REL::Version(1, 6, 1170, 0)) { + logger::info("Initializing borderless mode..."); + REL::Relocation target{ REL::ID(36547), 0xBEA }; + REL::safe_write(target.address(), code, sizeof(code)); + + } else if (version >= REL::Version(1, 5, 97, 0) && version < REL::Version(1, 6, 1130, 0)) { + logger::info("Initializing borderless mode..."); + REL::Relocation target{ REL::RelocationID(35548, 36547), REL::Relocate(0x83A, version >= REL::Version(1, 6, 342, 0) ? version >= REL::Version(1, 6, 629, 0) ? 0xCFA : 0xCDA : 0xCBB) }; + REL::safe_write(target.address(), code, sizeof(code)); + + } else { + logger::info("Untested version of Skyrim, skipping borderless mode..."); + return; + } + } +}