Skip to content

Commit 23b1754

Browse files
committed
LargoWinchEmpireUnderThreat: Made the fix calculate aspect ratio automatically from the in-game resolution
1 parent 5dade20 commit 23b1754

2 files changed

Lines changed: 38 additions & 35 deletions

File tree

project/LargoWinchEmpireUnderThreatFOVFix.vcxproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
</PropertyGroup>
3535
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
3636
<ConfigurationType>DynamicLibrary</ConfigurationType>
37-
<UseDebugLibraries>true</UseDebugLibraries>
37+
<UseDebugLibraries>false</UseDebugLibraries>
3838
<PlatformToolset>v145</PlatformToolset>
3939
<WholeProgramOptimization>true</WholeProgramOptimization>
4040
<CharacterSet>Unicode</CharacterSet>
@@ -108,9 +108,9 @@
108108
<LanguageStandard>stdcpplatest</LanguageStandard>
109109
<LanguageStandard_C>stdclatest</LanguageStandard_C>
110110
<DebugInformationFormat>None</DebugInformationFormat>
111-
<Optimization>Disabled</Optimization>
111+
<Optimization>MaxSpeed</Optimization>
112112
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
113-
<WholeProgramOptimization>false</WholeProgramOptimization>
113+
<WholeProgramOptimization>true</WholeProgramOptimization>
114114
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
115115
<PrecompiledHeader>NotUsing</PrecompiledHeader>
116116
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>

source/fixes/LargoWinchEmpireUnderThreatFOVFix/dllmain.cpp

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ HMODULE thisModule;
2626

2727
// Fix details
2828
std::string sFixName = "LargoWinchEmpireUnderThreatFOVFix";
29-
std::string sFixVersion = "1.3";
29+
std::string sFixVersion = "1.4";
3030
std::filesystem::path sFixPath;
3131

3232
// Ini
@@ -44,8 +44,6 @@ constexpr float fOldAspectRatio = 4.0f / 3.0f;
4444

4545
// Ini variables
4646
bool bFixActive;
47-
int iCurrentResX;
48-
int iCurrentResY;
4947
float fFOVFactor;
5048

5149
// Variables
@@ -64,8 +62,8 @@ enum class Game
6462

6563
enum CameraFOVInstructionsIndices
6664
{
67-
GameplayFOV,
68-
CutscenesFOV
65+
Gameplay,
66+
Cutscenes
6967
};
7068

7169
struct GameInfo
@@ -155,25 +153,9 @@ void Configuration()
155153
spdlog_confparse(bFixActive);
156154

157155
// Load resolution from ini
158-
inipp::get_value(ini.sections["Settings"], "Width", iCurrentResX);
159-
inipp::get_value(ini.sections["Settings"], "Height", iCurrentResY);
160156
inipp::get_value(ini.sections["Settings"], "FOVFactor", fFOVFactor);
161-
spdlog_confparse(iCurrentResX);
162-
spdlog_confparse(iCurrentResY);
163157
spdlog_confparse(fFOVFactor);
164158

165-
// If resolution not specified, use desktop resolution
166-
if (iCurrentResX <= 0 || iCurrentResY <= 0)
167-
{
168-
spdlog::info("Resolution not specified in ini file. Using desktop resolution.");
169-
// Implement Util::GetPhysicalDesktopDimensions() accordingly
170-
auto desktopDimensions = Util::GetPhysicalDesktopDimensions();
171-
iCurrentResX = desktopDimensions.first;
172-
iCurrentResY = desktopDimensions.second;
173-
spdlog_confparse(iCurrentResX);
174-
spdlog_confparse(iCurrentResY);
175-
}
176-
177159
spdlog::info("----------");
178160
}
179161

@@ -195,6 +177,7 @@ bool DetectGame()
195177
return false;
196178
}
197179

180+
static SafetyHookMid ResolutionInstructionsHook{};
198181
static SafetyHookMid AspectRatioInstructionHook{};
199182
static SafetyHookMid GameplayFOVInstructionHook{};
200183
static SafetyHookMid CutscenesFOVInstructionHook{};
@@ -203,9 +186,29 @@ void FOVFix()
203186
{
204187
if (eGameType == Game::LWEUT && bFixActive == true)
205188
{
206-
fNewAspectRatio = static_cast<float>(iCurrentResX) / static_cast<float>(iCurrentResY);
189+
std::uint8_t* ResolutionInstructionsScanResult = Memory::PatternScan(exeModule, "8B 44 24 ?? 8B 4C 24 ?? A3 ?? ?? ?? ?? 89 0D ?? ?? ?? ?? C3 90 90 90 90 90 90 90 90 90 90 90 90 A1");
190+
if (ResolutionInstructionsScanResult)
191+
{
192+
spdlog::info("Resolution Instructions Scan: Address is {:s}+{:x}", sExeName.c_str(), ResolutionInstructionsScanResult - (std::uint8_t*)exeModule);
193+
194+
ResolutionInstructionsHook = safetyhook::create_mid(ResolutionInstructionsScanResult, [](SafetyHookContext& ctx)
195+
{
196+
int& iCurrentWidth = Memory::ReadMem(ctx.esp + 0x4);
197+
198+
int& iCurrentHeight = Memory::ReadMem(ctx.esp + 0x8);
199+
200+
fNewAspectRatio = static_cast<float>(iCurrentWidth) / static_cast<float>(iCurrentHeight);
207201

208-
fAspectRatioScale = fNewAspectRatio / fOldAspectRatio;
202+
fAspectRatioScale = fNewAspectRatio / fOldAspectRatio;
203+
204+
ResolutionInstructionsHook.disable();
205+
});
206+
}
207+
else
208+
{
209+
spdlog::error("Failed to locate resolution instructions scan memory address.");
210+
return;
211+
}
209212

210213
std::uint8_t* AspectRatioInstructionScanResult = Memory::PatternScan(exeModule, "D9 44 24 ?? 8B 4C 24 ?? D9 58 ?? D9 44 24");
211214
if (AspectRatioInstructionScanResult)
@@ -216,7 +219,7 @@ void FOVFix()
216219

217220
AspectRatioInstructionHook = safetyhook::create_mid(AspectRatioInstructionScanResult, [](SafetyHookContext& ctx)
218221
{
219-
float& fCurrentHFOV = *(float*)(ctx.esp + 0x8);
222+
float& fCurrentHFOV = Memory::ReadMem(ctx.esp + 0x8);
220223

221224
fNewHFOV = Maths::CalculateNewHFOV_RadBased(fCurrentHFOV, fAspectRatioScale);
222225

@@ -232,13 +235,13 @@ void FOVFix()
232235
std::vector<std::uint8_t*> CameraFOVInstructionsScansResult = Memory::PatternScan(exeModule, "D9 41 ?? D9 54 24", "89 48 ?? C3 90 90 90 90 90 90 90 90 90 90 A0");
233236
if (Memory::AreAllSignaturesValid(CameraFOVInstructionsScansResult) == true)
234237
{
235-
spdlog::info("Gameplay FOV Instruction: Address is {:s}+{:x}", sExeName.c_str(), CameraFOVInstructionsScansResult[GameplayFOV] - (std::uint8_t*)exeModule);
238+
spdlog::info("Gameplay FOV Instruction: Address is {:s}+{:x}", sExeName.c_str(), CameraFOVInstructionsScansResult[Gameplay] - (std::uint8_t*)exeModule);
236239

237-
spdlog::info("Cutscenes FOV Instruction: Address is {:s}+{:x}", sExeName.c_str(), CameraFOVInstructionsScansResult[CutscenesFOV] - (std::uint8_t*)exeModule);
240+
spdlog::info("Cutscenes FOV Instruction: Address is {:s}+{:x}", sExeName.c_str(), CameraFOVInstructionsScansResult[Cutscenes] - (std::uint8_t*)exeModule);
238241

239-
Memory::WriteNOPs(CameraFOVInstructionsScansResult[GameplayFOV], 3);
242+
Memory::WriteNOPs(CameraFOVInstructionsScansResult[Gameplay], 3);
240243

241-
GameplayFOVInstructionHook = safetyhook::create_mid(CameraFOVInstructionsScansResult[GameplayFOV], [](SafetyHookContext& ctx)
244+
GameplayFOVInstructionHook = safetyhook::create_mid(CameraFOVInstructionsScansResult[Gameplay], [](SafetyHookContext& ctx)
242245
{
243246
float& fCurrentGameplayFOV = Memory::ReadMem(ctx.ecx + 0x5C);
244247

@@ -247,15 +250,15 @@ void FOVFix()
247250
FPU::FLD(fNewGameplayFOV);
248251
});
249252

250-
Memory::WriteNOPs(CameraFOVInstructionsScansResult[CutscenesFOV], 3);
253+
Memory::WriteNOPs(CameraFOVInstructionsScansResult[Cutscenes], 3);
251254

252-
CutscenesFOVInstructionHook = safetyhook::create_mid(CameraFOVInstructionsScansResult[CutscenesFOV], [](SafetyHookContext& ctx)
255+
CutscenesFOVInstructionHook = safetyhook::create_mid(CameraFOVInstructionsScansResult[Cutscenes], [](SafetyHookContext& ctx)
253256
{
254-
const float& fCurrentCutscenesFOV = std::bit_cast<float>(ctx.ecx);
257+
const float& fCurrentCutscenesFOV = Memory::ReadRegister(ctx.ecx);
255258

256259
fNewCutscenesFOV = fCurrentCutscenesFOV / fFOVFactor;
257260

258-
Memory::ReadMem(ctx.eax + 0x5C) = fNewCutscenesFOV;
261+
*reinterpret_cast<float*>(ctx.eax + 0x5C) = fNewCutscenesFOV;
259262
});
260263
}
261264
}

0 commit comments

Comments
 (0)