Skip to content

Commit 162505e

Browse files
committed
PowerSpikeProBeachVolleyball:
- Added support for running multiple game instances at once and skipping the intro splash screen and video
1 parent 9154df2 commit 162505e

1 file changed

Lines changed: 63 additions & 21 deletions

File tree

  • source/fixes/PowerSpikeProBeachVolleyballWidescreenFix

source/fixes/PowerSpikeProBeachVolleyballWidescreenFix/dllmain.cpp

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

120153
private:
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

Comments
 (0)