Skip to content

Commit f5dfe06

Browse files
committed
Added late loading option for ASI files
1 parent 5e73f8e commit f5dfe06

5 files changed

Lines changed: 79 additions & 4 deletions

File tree

‎OptiScaler.ini‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,11 @@ Path=auto
929929
; true or false - Default (auto) is false
930930
LoadAsiPlugins=auto
931931

932+
; Delay before loading late-load *.asi files in plugins folder
933+
; To set an ASI plugin to load late, add -loadlate to the it's filename before the extension, for example "myplugin-loadlate.asi"
934+
; Integer value in seconds - Default (auto) is 30
935+
LateAsiPluginsDelay=auto
936+
932937
; Loads SpecialK64.dll from game's exe folder
933938
; Please create an empty SpecialK.dxgi file next to SpecialK64.dll
934939
; to set SpecialK's working mode, otherwise it will not be activated

‎OptiScaler/Config.cpp‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ bool Config::Reload(std::filesystem::path iniPath)
652652
LoadSpecialK.set_from_config(readBool("Plugins", "LoadSpecialK"));
653653
LoadReShade.set_from_config(readBool("Plugins", "LoadReShade"));
654654
LoadAsiPlugins.set_from_config(readBool("Plugins", "LoadAsiPlugins"));
655+
LateAsiPluginsDelay.set_from_config(readInt("Plugins", "LateAsiPluginsDelay"));
655656
}
656657

657658
// HDR
@@ -1322,6 +1323,8 @@ bool Config::SaveIni()
13221323
ini.SetValue("Plugins", "LoadSpecialK", GetBoolValue(Instance()->LoadSpecialK.value_for_config()).c_str());
13231324
ini.SetValue("Plugins", "LoadReShade", GetBoolValue(Instance()->LoadReShade.value_for_config()).c_str());
13241325
ini.SetValue("Plugins", "LoadAsiPlugins", GetBoolValue(Instance()->LoadAsiPlugins.value_for_config()).c_str());
1326+
ini.SetValue("Plugins", "LateAsiPluginsDelay",
1327+
GetIntValue(Instance()->LateAsiPluginsDelay.value_for_config()).c_str());
13251328
}
13261329

13271330
// inputs

‎OptiScaler/Config.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ class Config
462462
CustomOptional<bool> LoadSpecialK { false };
463463
CustomOptional<bool> LoadReShade { false };
464464
CustomOptional<bool> LoadAsiPlugins { false };
465+
CustomOptional<int> LateAsiPluginsDelay { 30 };
465466

466467
// Frame Generation
467468
CustomOptional<FGInput> FGInput { FGInput::NoFG };

‎OptiScaler/dllmain.cpp‎

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include <version_check.h>
5050

5151
static std::vector<HMODULE> _asiHandles;
52+
static std::vector<std::filesystem::directory_entry> _lateLoadingEntries;
5253
static bool _passThruMode = false;
5354

5455
typedef const char*(CDECL* PFN_wine_get_version)(void);
@@ -226,7 +227,16 @@ void LoadAsiPlugins()
226227

227228
if (ext == L".asi")
228229
{
229-
HMODULE hMod = NtdllProxy::LoadLibraryExW_Ldr(entry.path().c_str(), NULL, 0);
230+
std::wstring fileName = entry.path().filename().wstring();
231+
std::transform(fileName.begin(), fileName.end(), fileName.begin(),
232+
[](wchar_t c) { return std::towlower(c); });
233+
234+
HMODULE hMod = nullptr;
235+
236+
if (fileName.rfind(L"-loadlate") != std::wstring::npos)
237+
_lateLoadingEntries.push_back(entry);
238+
else
239+
hMod = NtdllProxy::LoadLibraryExW_Ldr(entry.path().c_str(), NULL, 0);
230240

231241
if (hMod != nullptr)
232242
{
@@ -266,6 +276,63 @@ void LoadAsiPlugins()
266276
DWORD err = GetLastError();
267277
LOG_ERROR(L"Failed to load: {}, error {:X}", entry.path().wstring(), err);
268278
}
279+
280+
if (_lateLoadingEntries.size() > 0)
281+
{
282+
std::thread(
283+
[]()
284+
{
285+
auto delay = Config::Instance()->LateAsiPluginsDelay.value_or_default();
286+
LOG_INFO("Waiting {} seconds before loading late-load plugins...", delay);
287+
std::this_thread::sleep_for(std::chrono::seconds(delay));
288+
289+
for (const auto& entry : _lateLoadingEntries)
290+
{
291+
HMODULE hMod = NtdllProxy::LoadLibraryExW_Ldr(entry.path().c_str(), NULL, 0);
292+
293+
if (hMod != nullptr)
294+
{
295+
LOG_INFO(L"Loaded late: {}", entry.path().wstring());
296+
_asiHandles.push_back(hMod);
297+
298+
auto init =
299+
(PFN_InitializeASI) KernelBaseProxy::GetProcAddress_()(hMod, "InitializeASI");
300+
301+
auto patchResult =
302+
(PFN_PatchResult) KernelBaseProxy::GetProcAddress_()(hMod, "PatchResult");
303+
304+
if (init != nullptr)
305+
init();
306+
307+
if (patchResult != nullptr)
308+
{
309+
auto pr = patchResult();
310+
if (pr)
311+
{
312+
LOG_INFO("Game patching is successful");
313+
State::Instance().isOptiPatcherSucceed = true;
314+
LOG_INFO("Disabling spoofing");
315+
316+
if (!Config::Instance()->DxgiSpoofing.has_value())
317+
Config::Instance()->DxgiSpoofing.set_volatile_value(false);
318+
319+
if (!Config::Instance()->VulkanSpoofing.has_value())
320+
Config::Instance()->VulkanSpoofing.set_volatile_value(false);
321+
322+
if (!Config::Instance()->VulkanExtensionSpoofing.has_value())
323+
Config::Instance()->VulkanExtensionSpoofing.set_volatile_value(false);
324+
}
325+
}
326+
}
327+
else
328+
{
329+
DWORD err = GetLastError();
330+
LOG_ERROR(L"Failed to load: {}, error {:X}", entry.path().wstring(), err);
331+
}
332+
}
333+
})
334+
.detach();
335+
}
269336
}
270337
}
271338
}

‎OptiScaler/inputs/FG/Streamline_Inputs_Dx12.cpp‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ bool Sl_Inputs_Dx12::setConstants(const sl::Constants& values, uint32_t frameId)
129129

130130
if (!config->FGEnabled.value_or_default())
131131
{
132-
LOG_TRACE("FG not active or paused");
132+
LOG_TRACE("FG not enabled");
133133
return true;
134134
}
135135
else
@@ -140,13 +140,12 @@ bool Sl_Inputs_Dx12::setConstants(const sl::Constants& values, uint32_t frameId)
140140
}
141141
else if (!fgOutput->IsActive() || fgOutput->IsPaused())
142142
{
143-
LOG_TRACE("FG not active or paused");
143+
LOG_TRACE("FG not active or paused (A:{}, P:{})", fgOutput->IsActive(), fgOutput->IsPaused());
144144
return true;
145145
}
146146
}
147147

148148
// Frame data part
149-
150149
// Nukem's function, licensed under GPLv3
151150
auto loadCameraMatrix = [&]()
152151
{

0 commit comments

Comments
 (0)