@@ -189,6 +189,8 @@ bool DetectGame()
189189}
190190
191191static SafetyHookMid CameraFOVInstructionHook{};
192+ static SafetyHookMid ProjectionMatrixPreHook{};
193+ static SafetyHookMid ProjectionMatrixPostHook{};
192194
193195int32_t ConvertFOV (int32_t baseFOV, double baseAR, double newAR)
194196{
@@ -210,7 +212,11 @@ void FOVFix()
210212 fAspectRatioScale = fNewAspectRatio / fOldAspectRatio ;
211213
212214 std::uint8_t * CameraFOVInstructionScanResult = Memory::PatternScan (exeModule, " DB 05 ?? ?? ?? ?? DC 0D" );
213- if (CameraFOVInstructionScanResult)
215+ if (!CameraFOVInstructionScanResult)
216+ {
217+ spdlog::error (" Failed to locate camera FOV instruction memory address." );
218+ }
219+ else
214220 {
215221 spdlog::info (" Camera FOV Instruction: Address is {:s}+{:x}" , sExeName .c_str (), CameraFOVInstructionScanResult - (std::uint8_t *)exeModule);
216222
@@ -227,10 +233,69 @@ void FOVFix()
227233 FPU::FILD (iNewFOV);
228234 });
229235 }
236+
237+ std::uint8_t * ProjectionSetTransformScanResult = Memory::PatternScan (
238+ exeModule,
239+ " 8B 51 64 56 6A 03 50 FF D2"
240+ );
241+
242+ if (!ProjectionSetTransformScanResult)
243+ {
244+ spdlog::error (" Failed to locate projection matrix SetTransform call." );
245+ }
230246 else
231247 {
232- spdlog::error (" Failed to locate camera FOV instruction memory address." );
233- return ;
248+ std::uint8_t * ProjectionSetTransformPreHookAddress =
249+ ProjectionSetTransformScanResult + 3 ;
250+
251+ std::uint8_t * ProjectionSetTransformPostHookAddress =
252+ ProjectionSetTransformScanResult + 9 ;
253+
254+ spdlog::info (
255+ " Projection matrix SetTransform call: Address is {:s}+{:x}" ,
256+ sExeName .c_str (),
257+ ProjectionSetTransformPreHookAddress - reinterpret_cast <std::uint8_t *>(exeModule)
258+ );
259+
260+ static float fOriginalProjectionM00 = 0 .0f ;
261+ static float fOriginalProjectionM11 = 0 .0f ;
262+ static float * pCurrentProjectionMatrix = nullptr ;
263+
264+ ProjectionMatrixPreHook = safetyhook::create_mid (
265+ ProjectionSetTransformPreHookAddress,
266+ [](SafetyHookContext& ctx)
267+ {
268+ pCurrentProjectionMatrix = reinterpret_cast <float *>(ctx.esi );
269+
270+ if (pCurrentProjectionMatrix == nullptr )
271+ {
272+ return ;
273+ }
274+
275+ fOriginalProjectionM00 = pCurrentProjectionMatrix[0 ];
276+ fOriginalProjectionM11 = pCurrentProjectionMatrix[5 ];
277+
278+ const float projectionScale = 1 .0f / fAspectRatioScale ;
279+
280+ pCurrentProjectionMatrix[0 ] *= projectionScale;
281+ pCurrentProjectionMatrix[5 ] *= projectionScale;
282+ }
283+ );
284+
285+ ProjectionMatrixPostHook = safetyhook::create_mid (
286+ ProjectionSetTransformPostHookAddress,
287+ [](SafetyHookContext& ctx)
288+ {
289+ if (pCurrentProjectionMatrix == nullptr )
290+ {
291+ return ;
292+ }
293+
294+ pCurrentProjectionMatrix[0 ] = fOriginalProjectionM00 ;
295+ pCurrentProjectionMatrix[5 ] = fOriginalProjectionM11 ;
296+ pCurrentProjectionMatrix = nullptr ;
297+ }
298+ );
234299 }
235300 }
236301}
0 commit comments