@@ -24,7 +24,7 @@ class PowerSpikeFix final : public FixBase
2424
2525 const char * FixVersion () const override
2626 {
27- return " 1.3 " ;
27+ return " 1.4 " ;
2828 }
2929
3030 const char * TargetName () const override
@@ -34,8 +34,8 @@ class PowerSpikeFix final : public FixBase
3434
3535 InitMode GetInitMode () const override
3636 {
37- // return InitMode::Direct;
38- return InitMode::WorkerThread;
37+ return InitMode::Direct;
38+ // return InitMode::WorkerThread;
3939 // return InitMode::ExportedOnly;
4040 }
4141
@@ -47,7 +47,11 @@ class PowerSpikeFix final : public FixBase
4747 void ParseFixConfig (inipp::Ini<char >& ini) override
4848 {
4949 inipp::get_value (ini.sections [" Settings" ], " FOVFactor" , m_fovFactor);
50+ inipp::get_value (ini.sections [" Settings" ], " RunMultipleInstances" , m_runMultipleInstances);
51+ inipp::get_value (ini.sections [" Settings" ], " SkipIntroVideos" , m_skipIntroVideos);
5052 spdlog_confparse (m_fovFactor);
53+ spdlog_confparse (m_runMultipleInstances);
54+ spdlog_confparse (m_skipIntroVideos);
5155 }
5256
5357 void ApplyFix () override
@@ -76,16 +80,16 @@ class PowerSpikeFix final : public FixBase
7680 return ;
7781 }
7882
79- std:: uint8_t * AspectRatioInstructionScanResult = Memory::PatternScan (ExeModule (), " DC 0D ?? ?? ?? ?? DB 05" );
80- if (AspectRatioInstructionScanResult )
83+ auto AspectRatioScanResult = Memory::PatternScan (ExeModule (), " DC 0D ?? ?? ?? ?? DB 05" );
84+ if (AspectRatioScanResult )
8185 {
82- spdlog::info (" Aspect Ratio Instruction Scan : Address is {:s}+{:x}" , ExeName ().c_str (), AspectRatioInstructionScanResult - (std::uint8_t *)ExeModule ());
86+ spdlog::info (" Aspect Ratio Instruction: Address is {:s}+{:x}" , ExeName ().c_str (), AspectRatioScanResult - (std::uint8_t *)ExeModule ());
8387
84- AspectRatioAddress = Memory::GetPointerFromAddress (AspectRatioInstructionScanResult + 2 , Memory::PointerMode::Absolute);
88+ m_aspectRatioAddress = Memory::GetPointerFromAddress (AspectRatioScanResult + 2 , Memory::PointerMode::Absolute);
8589
86- Memory::WriteNOPs (AspectRatioInstructionScanResult , 6 );
90+ Memory::WriteNOPs (AspectRatioScanResult , 6 );
8791
88- m_aspectRatioHook = safetyhook::create_mid (AspectRatioInstructionScanResult , [](SafetyHookContext& ctx)
92+ m_aspectRatioHook = safetyhook::create_mid (AspectRatioScanResult , [](SafetyHookContext& ctx)
8993 {
9094 s_instance_->AspectRatioMidHook (ctx);
9195 });
@@ -96,16 +100,16 @@ class PowerSpikeFix final : public FixBase
96100 return ;
97101 }
98102
99- std:: uint8_t * CameraFOVInstructionScanResult = Memory::PatternScan (ExeModule (), " D9 04 95 ?? ?? ?? ?? DC 0D" );
100- if (CameraFOVInstructionScanResult )
103+ auto CameraFOVScanResult = Memory::PatternScan (ExeModule (), " D9 04 95 ?? ?? ?? ?? DC 0D" );
104+ if (CameraFOVScanResult )
101105 {
102- spdlog::info (" Camera FOV Instruction: Address is {:s}+{:x}" , ExeName ().c_str (), CameraFOVInstructionScanResult - (std::uint8_t *)ExeModule ());
106+ spdlog::info (" Camera FOV Instruction: Address is {:s}+{:x}" , ExeName ().c_str (), CameraFOVScanResult - (std::uint8_t *)ExeModule ());
103107
104- CameraFOVOffset = Memory::GetPointerFromAddress (CameraFOVInstructionScanResult + 3 , Memory::PointerMode::Absolute);
108+ m_cameraFOVOffset = Memory::GetPointerFromAddress (CameraFOVScanResult + 3 , Memory::PointerMode::Absolute);
105109
106- Memory::WriteNOPs (CameraFOVInstructionScanResult , 7 );
110+ Memory::WriteNOPs (CameraFOVScanResult , 7 );
107111
108- m_cameraFOVHook = safetyhook::create_mid (CameraFOVInstructionScanResult , [](SafetyHookContext& ctx)
112+ m_cameraFOVHook = safetyhook::create_mid (CameraFOVScanResult , [](SafetyHookContext& ctx)
109113 {
110114 s_instance_->CameraFOVMidHook (ctx);
111115 });
@@ -115,34 +119,72 @@ class PowerSpikeFix final : public FixBase
115119 spdlog::info (" Cannot locate the camera FOV instruction memory address." );
116120 return ;
117121 }
122+
123+ if (m_runMultipleInstances == true )
124+ {
125+ auto RunMultipleInstancesCheckScanResult = Memory::PatternScan (ExeModule (), " 74 ?? 33 C0 E9 ?? ?? ?? ?? 68" );
126+ if (RunMultipleInstancesCheckScanResult)
127+ {
128+ spdlog::info (" Multiple Instance Check Instruction: Address is {:s}+{:x}" , ExeName ().c_str (), RunMultipleInstancesCheckScanResult - (std::uint8_t *)ExeModule ());
129+
130+ Memory::PatchBytes (RunMultipleInstancesCheckScanResult, " \xEB " );
131+ }
132+ else
133+ {
134+ spdlog::error (" Failed to locate multiple instance check instruction memory address." );
135+ return ;
136+ }
137+ }
138+
139+ if (m_skipIntroVideos == true )
140+ {
141+ auto SkipIntroVideoScanResult = Memory::PatternScan (ExeModule (), " 75 ?? 8B 85 ?? ?? ?? ?? 50 B9" , " 0F 84 ?? ?? ?? ?? 68 ?? ?? ?? ?? 68 ?? ?? ?? ?? 6A ?? 68" );
142+ if (Memory::AreAllSignaturesValid (SkipIntroVideoScanResult) == true )
143+ {
144+ spdlog::info (" Intro.avi Startup Video Instruction: Address is {:s}+{:x}" , ExeName ().c_str (), SkipIntroVideoScanResult[AVIVideo] - (std::uint8_t *)ExeModule ());
145+ spdlog::info (" Splash Screen Startup Intro Video Instruction: Address is {:s}+{:x}" , ExeName ().c_str (), SkipIntroVideoScanResult[SplashScreen] - (std::uint8_t *)ExeModule ());
146+
147+ Memory::PatchBytes (SkipIntroVideoScanResult[AVIVideo], " \xEB " );
148+ Memory::PatchBytes (SkipIntroVideoScanResult[SplashScreen], " \xE9\x10\x01\x00\x00\x90 " );
149+ }
150+ }
118151 }
119152
120153private:
154+ static constexpr float m_oldAspectRatio = 4 .0f / 3 .0f ;
155+
121156 SafetyHookMid m_resolutionHook{};
122157 SafetyHookMid m_aspectRatioHook{};
123158 SafetyHookMid m_cameraFOVHook{};
124159
125- uintptr_t AspectRatioAddress = 0 ;
126- uintptr_t CameraFOVOffset = 0 ;
160+ uintptr_t m_aspectRatioAddress = 0 ;
161+ uintptr_t m_cameraFOVOffset = 0 ;
127162
128- static constexpr float m_oldAspectRatio = 4 .0f / 3 .0f ;
163+ bool m_runMultipleInstances = false ;
164+ bool m_skipIntroVideos = false ;
129165
130- double m_newAspectRatio2 = 0 ;
166+ double m_newAspectRatio2 = 0.0 ;
131167
132168 void AspectRatioMidHook (SafetyHookContext& ctx)
133169 {
134- double & dCurrentAspectRatio = Memory::ReadMem (AspectRatioAddress );
170+ double & dCurrentAspectRatio = Memory::ReadMem (m_aspectRatioAddress );
135171 m_newAspectRatio2 = (dCurrentAspectRatio / (double )m_aspectRatioScale) / (double )m_aspectRatioScale;
136172 FPU::FMUL (m_newAspectRatio2);
137173 }
138174
139175 void CameraFOVMidHook (SafetyHookContext& ctx)
140176 {
141- float & fCurrentCameraFOV = Memory::ReadMem (ctx.edx * 0x4 + CameraFOVOffset );
177+ float & fCurrentCameraFOV = Memory::ReadMem (ctx.edx * 0x4 + m_cameraFOVOffset );
142178 m_newCameraFOV = fCurrentCameraFOV * m_fovFactor;
143179 FPU::FLD (m_newCameraFOV);
144180 }
145181
182+ enum SkipIntroVideoInstructionsIndex
183+ {
184+ AVIVideo,
185+ SplashScreen
186+ };
187+
146188 inline static PowerSpikeFix* s_instance_ = nullptr ;
147189};
148190
0 commit comments