Skip to content

Commit 53ee579

Browse files
authored
Vehicle audio settings (#2350)
1 parent cc8a637 commit 53ee579

22 files changed

+643
-80
lines changed

Client/game_sa/CAEVehicleAudioEntitySA.h

+9-24
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#pragma once
1313

14+
#include "CVehicleAudioSettingsEntrySA.h"
1415
#include <game/CAEVehicleAudioEntity.h>
1516
#include "CAudioEngineSA.h"
1617

@@ -20,28 +21,7 @@
2021
#define FUNC_CAEVehicleAudioEntity__ProcessAIProp 0x4FDFD0
2122
#define FUNC_CAEVehicleAudioEntity__ProcessAIHeli 0x4FEE20
2223

23-
struct tVehicleAudioSettings
24-
{
25-
char m_nVehicleSoundType;
26-
char unk1;
27-
short m_wEngineOnSoundBankId;
28-
short m_wEngineOffSoundBankId;
29-
char m_nStereo;
30-
char unk2;
31-
int unk3;
32-
int unk4;
33-
char m_bHornTon;
34-
char unk5[3];
35-
float m_fHornHigh;
36-
char m_nDoorSound;
37-
char unk6;
38-
char m_nRadioNum;
39-
char m_nRadioType;
40-
char unk7;
41-
char unk8[3];
42-
float m_fHornVolumeDelta;
43-
};
44-
static_assert(sizeof(tVehicleAudioSettings) == 0x24, "Invalid size for tVehicleAudioSettings");
24+
class CVehicleSAInterface;
4525

4626
struct tVehicleSound
4727
{
@@ -73,9 +53,13 @@ static_assert(sizeof(CAETwinLoopSoundEntity) == 0xA8, "Invalid size for CAETwinL
7353
class CAEVehicleAudioEntitySAInterface : public CAEAudioEntity
7454
{
7555
public:
76-
void AddAudioEvent(int eventId, float volume)
56+
void AddAudioEvent(int eventId, float volume) { ((void(__thiscall*)(CAEVehicleAudioEntitySAInterface*, int, float))0x4F6420)(this, eventId, volume); }
57+
bool TerminateAudio() { return ((bool(__thiscall*)(CAEVehicleAudioEntitySAInterface*))0x4FB8C0)(this); }
58+
bool SoundJoin() { return ((bool(__thiscall*)(CAEVehicleAudioEntitySAInterface*))0x4F5700)(this); }
59+
60+
int16_t InitAudio(CVehicleSAInterface* vehicle)
7761
{
78-
((void(__thiscall*)(CAEVehicleAudioEntitySAInterface*, int, float))0x4F6420)(this, eventId, volume);
62+
return ((int16_t(__thiscall*)(CAEVehicleAudioEntitySAInterface*, CVehicleSAInterface*))0x4F7670)(this, vehicle);
7963
}
8064

8165
short unk1; // +124
@@ -157,6 +141,7 @@ class CAEVehicleAudioEntitySA : public CAEVehicleAudioEntity
157141
void JustGotOutOfVehicleAsDriver();
158142
void TurnOnRadioForVehicle();
159143
void StopVehicleEngineSound(unsigned char ucSlot);
144+
CAEVehicleAudioEntitySAInterface* GetInterface() { return m_pInterface; };
160145

161146
private:
162147
CAEVehicleAudioEntitySAInterface* m_pInterface;

Client/game_sa/CGameSA.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ CGameSA::CGameSA()
147147
m_pCoverManager = new CCoverManagerSA();
148148
m_pPlantManager = new CPlantManagerSA();
149149
m_pBuildingRemoval = new CBuildingRemovalSA();
150+
m_pVehicleAudioSettingsManager = std::make_unique<CVehicleAudioSettingsManagerSA>();
150151

151152
m_pRenderer = std::make_unique<CRendererSA>();
152153

@@ -247,6 +248,7 @@ CGameSA::CGameSA()
247248
CCheckpointSA::StaticSetHooks();
248249
CHudSA::StaticSetHooks();
249250
CPtrNodeSingleLinkPoolSA::StaticSetHooks();
251+
CVehicleAudioSettingsManagerSA::StaticSetHooks();
250252
}
251253
catch (const std::bad_alloc& e)
252254
{

Client/game_sa/CGameSA.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "CCoverManagerSA.h"
1919
#include "CPlantManagerSA.h"
2020
#include "CRendererSA.h"
21+
#include "CVehicleAudioSettingsManagerSA.h"
2122

2223
class CAnimBlendClumpDataSAInterface;
2324
class CObjectGroupPhysicalPropertiesSA;
@@ -174,7 +175,12 @@ class CGameSA : public CGame
174175
CPlantManagerSA* GetPlantManager() const noexcept { return m_pPlantManager; };
175176
CBuildingRemoval* GetBuildingRemoval() { return m_pBuildingRemoval; }
176177
CRenderer* GetRenderer() const noexcept override { return m_pRenderer.get(); }
177-
178+
179+
CVehicleAudioSettingsManager* GetVehicleAudioSettingsManager() const noexcept override
180+
{
181+
return m_pVehicleAudioSettingsManager.get();
182+
}
183+
178184
CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD);
179185
CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false);
180186
CObjectGroupPhysicalProperties* GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup);
@@ -351,6 +357,8 @@ class CGameSA : public CGame
351357
CPlantManagerSA* m_pPlantManager;
352358
CBuildingRemoval* m_pBuildingRemoval;
353359

360+
std::unique_ptr<CVehicleAudioSettingsManagerSA> m_pVehicleAudioSettingsManager;
361+
354362
std::unique_ptr<CRendererSA> m_pRenderer;
355363

356364
CPad* m_pPad;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*****************************************************************************
2+
*
3+
* PROJECT: Multi Theft Auto v1.0
4+
* LICENSE: See LICENSE in the top level directory
5+
* FILE: game_sa/CVehicleAudioSettingsEntrySA.h
6+
* PURPOSE: Header file for vehicle audio settings entry class
7+
*
8+
* Multi Theft Auto is available from http://www.multitheftauto.com/
9+
*
10+
*****************************************************************************/
11+
12+
#pragma once
13+
14+
#include "game/CVehicleAudioSettingsEntry.h"
15+
#include <game/Common.h>
16+
17+
// SA interface
18+
struct tVehicleAudioSettings
19+
{
20+
eVehicleSoundType m_eVehicleSoundType;
21+
int16 m_nEngineOnSoundBankId;
22+
int16 m_nEngineOffSoundBankId;
23+
int8 m_nBassSetting; // 0 or 1 or 2
24+
float m_fBassEq;
25+
float field_C;
26+
int8 m_nHornToneSoundInBank;
27+
float m_fHornHigh;
28+
char m_nDoorSound;
29+
char m_EngineUpgrade;
30+
char m_nRadioID;
31+
char m_nRadioType;
32+
char m_nVehTypeForAudio;
33+
float m_fHornVolumeDelta;
34+
};
35+
static_assert(sizeof(tVehicleAudioSettings) == 0x24, "Invalid size for tVehicleAudioSettings");
36+
37+
class CVehicleAudioSettingsEntrySA final : public CVehicleAudioSettingsEntry
38+
{
39+
public:
40+
CVehicleAudioSettingsEntrySA(): m_Settings{} {};
41+
CVehicleAudioSettingsEntrySA(tVehicleAudioSettings* pSettings) { m_Settings = *pSettings; };
42+
~CVehicleAudioSettingsEntrySA() = default;
43+
44+
const tVehicleAudioSettings& GetInterface() const noexcept { return m_Settings; };
45+
46+
void Assign(const tVehicleAudioSettings& settings) noexcept { m_Settings = settings; }
47+
void Assign(const CVehicleAudioSettingsEntry& settings) noexcept { m_Settings = static_cast<const CVehicleAudioSettingsEntrySA&>(settings).GetInterface(); };
48+
49+
eVehicleSoundType GetSoundType() const noexcept override { return m_Settings.m_eVehicleSoundType; };
50+
short GetEngineOnSoundBankID() const noexcept override { return m_Settings.m_nEngineOnSoundBankId; };
51+
short GetEngineOffSoundBankID() const noexcept override { return m_Settings.m_nEngineOffSoundBankId; };
52+
char GetBassSetting() const noexcept override { return m_Settings.m_nBassSetting; };
53+
float GetBassEq() const noexcept override { return m_Settings.m_fBassEq; };
54+
float GetFieldC() const noexcept override { return m_Settings.field_C; };
55+
char GetHornTon() const noexcept override { return m_Settings.m_nHornToneSoundInBank; };
56+
float GetHornHign() const noexcept override { return m_Settings.m_fHornHigh; };
57+
char GetEngineUpgrade() const noexcept override { return m_Settings.m_EngineUpgrade; };
58+
char GetDoorSound() const noexcept override { return m_Settings.m_nDoorSound; };
59+
char GetRadioNum() const noexcept override { return m_Settings.m_nRadioID; };
60+
char GetRadioType() const noexcept override { return m_Settings.m_nRadioType; };
61+
char GetVehicleTypeForAudio() const noexcept override { return m_Settings.m_nVehTypeForAudio; };
62+
float GetHornVolumeDelta() const noexcept override { return m_Settings.m_fHornVolumeDelta; };
63+
64+
void SetSoundType(eVehicleSoundType value) noexcept override { m_Settings.m_eVehicleSoundType = value; };
65+
void SetEngineOnSoundBankID(short value) noexcept override { m_Settings.m_nEngineOnSoundBankId = value; };
66+
void SetEngineOffSoundBankID(short value) noexcept override { m_Settings.m_nEngineOffSoundBankId = value; };
67+
void SetBassSetting(char value) noexcept override { m_Settings.m_nBassSetting = value; };
68+
void SetBassEq(float value) noexcept override { m_Settings.m_fBassEq = value; };
69+
void SetFieldC(float value) noexcept override { m_Settings.field_C = value; };
70+
void SetHornTon(char value) noexcept override { m_Settings.m_nHornToneSoundInBank = value; };
71+
void SetHornHign(float value) noexcept override { m_Settings.m_fHornHigh = value; };
72+
void SetEngineUpgrade(char value) noexcept override { m_Settings.m_EngineUpgrade = value; };
73+
void SetDoorSound(char value) noexcept override { m_Settings.m_nDoorSound = value; };
74+
void SetRadioNum(char value) noexcept override { m_Settings.m_nRadioID = value; };
75+
void SetRadioType(char value) noexcept override { m_Settings.m_nRadioType = value; };
76+
void SetVehicleTypeForAudio(char value) noexcept override { m_Settings.m_nVehTypeForAudio = value; };
77+
void SetHornVolumeDelta(float value) noexcept override { m_Settings.m_fHornVolumeDelta = value; };
78+
79+
private:
80+
tVehicleAudioSettings m_Settings;
81+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*****************************************************************************
2+
*
3+
* PROJECT: Multi Theft Auto v1.0
4+
* LICENSE: See LICENSE in the top level directory
5+
* FILE: game_sa/CVehicleAudioSettingsEntry.cpp
6+
* PURPOSE: Implementation file for vehicle audio settings manager class
7+
*
8+
* Multi Theft Auto is available from http://www.multitheftauto.com/
9+
*
10+
*****************************************************************************/
11+
12+
#include "StdInc.h"
13+
#include "CVehicleAudioSettingsManagerSA.h"
14+
#include <array>
15+
16+
const auto (&ORIGINAL_AUDIO_SETTINGS)[VEHICLES_COUNT] = *reinterpret_cast<const tVehicleAudioSettings (*)[VEHICLES_COUNT]>(0x860AF0);
17+
tVehicleAudioSettings const * pNextVehicleAudioSettings = nullptr;
18+
19+
CVehicleAudioSettingsManagerSA::CVehicleAudioSettingsManagerSA()
20+
{
21+
ResetAudioSettingsData();
22+
}
23+
24+
std::unique_ptr<CVehicleAudioSettingsEntry> CVehicleAudioSettingsManagerSA::CreateVehicleAudioSettingsData(uint32_t modelId)
25+
{
26+
auto settings = std::make_unique<CVehicleAudioSettingsEntrySA>();
27+
const auto& fromSetting = GetVehicleModelAudioSettingsData(modelId);
28+
settings->Assign(fromSetting);
29+
return settings;
30+
}
31+
32+
CVehicleAudioSettingsEntry& CVehicleAudioSettingsManagerSA::GetVehicleModelAudioSettingsData(uint32_t modelId) noexcept
33+
{
34+
return m_modelEntrys[GetVehicleModelAudioSettingsID(modelId)];
35+
}
36+
37+
void CVehicleAudioSettingsManagerSA::SetNextSettings(CVehicleAudioSettingsEntry const* pSettings) noexcept
38+
{
39+
pNextVehicleAudioSettings = &static_cast<CVehicleAudioSettingsEntrySA const*>(pSettings)->GetInterface();
40+
}
41+
42+
void CVehicleAudioSettingsManagerSA::SetNextSettings(uint32_t modelId) noexcept
43+
{
44+
pNextVehicleAudioSettings = &m_modelEntrys[GetVehicleModelAudioSettingsID(modelId)].GetInterface();
45+
}
46+
47+
void CVehicleAudioSettingsManagerSA::ResetModelSettings(uint32_t modelId) noexcept
48+
{
49+
size_t index = GetVehicleModelAudioSettingsID(modelId);
50+
m_modelEntrys[index].Assign(ORIGINAL_AUDIO_SETTINGS[index]);
51+
}
52+
53+
void CVehicleAudioSettingsManagerSA::ResetAudioSettingsData() noexcept
54+
{
55+
for (size_t i = 0; i < VEHICLES_COUNT; i++)
56+
m_modelEntrys[i].Assign(ORIGINAL_AUDIO_SETTINGS[i]);
57+
}
58+
59+
void CVehicleAudioSettingsManagerSA::StaticSetHooks() noexcept
60+
{
61+
// Replace
62+
// 8D 34 B5 F0 0A 86 00 ; lea esi, _VehicleAudioProperties.m_eVehicleSoundType[esi*4]
63+
// to
64+
// 8b 35 XX XX XX XX ; mov esi, [pNextVehicleAudioSettings]
65+
// 90 ; nop
66+
MemCpy((void*)0x4F77CA, "\x8B\x35\x00\x00\x00\x00\x90", 7);
67+
MemPut(0x4F77CA + 2, (std::uint32_t)&pNextVehicleAudioSettings);
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*****************************************************************************
2+
*
3+
* PROJECT: Multi Theft Auto v1.0
4+
* LICENSE: See LICENSE in the top level directory
5+
* FILE: game_sa/CVehicleAudioSettingsManagerSA.h
6+
* PURPOSE: Header file for vehicle audio settings manager class
7+
*
8+
* Multi Theft Auto is available from http://www.multitheftauto.com/
9+
*
10+
*****************************************************************************/
11+
12+
#pragma once
13+
14+
#include <game/CVehicleAudioSettingsManager.h>
15+
#include "CVehicleAudioSettingsEntrySA.h"
16+
#include "CAEVehicleAudioEntitySA.h"
17+
#include <array>
18+
19+
constexpr size_t VEHICLES_COUNT = 212;
20+
21+
class CVehicleAudioSettingsManagerSA final : public CVehicleAudioSettingsManager
22+
{
23+
public:
24+
CVehicleAudioSettingsManagerSA();
25+
26+
std::unique_ptr<CVehicleAudioSettingsEntry> CreateVehicleAudioSettingsData(uint32_t modelId) override;
27+
CVehicleAudioSettingsEntry& GetVehicleModelAudioSettingsData(uint32_t modelId) noexcept override;
28+
29+
void ResetModelSettings(uint32_t modelId) noexcept override;
30+
void ResetAudioSettingsData() noexcept override;
31+
32+
void SetNextSettings(CVehicleAudioSettingsEntry const* pSettings) noexcept override;
33+
void SetNextSettings(uint32_t modelId) noexcept override;
34+
35+
static void StaticSetHooks() noexcept;
36+
37+
private:
38+
size_t GetVehicleModelAudioSettingsID(uint32_t modelId) const noexcept { return modelId - 400; };
39+
40+
private:
41+
// Array with the model audio settings entries
42+
std::array<CVehicleAudioSettingsEntrySA, VEHICLES_COUNT> m_modelEntrys;
43+
};

Client/game_sa/CVehicleSA.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -2381,3 +2381,16 @@ bool CVehicleSA::SetWindowOpenFlagState(unsigned char ucWindow, bool bState)
23812381
}
23822382
return bReturn;
23832383
}
2384+
2385+
void CVehicleSA::ReinitAudio()
2386+
{
2387+
auto* audioInterface = m_pVehicleAudioEntity->GetInterface();
2388+
2389+
audioInterface->TerminateAudio();
2390+
audioInterface->InitAudio(GetVehicleInterface());
2391+
2392+
CPed* pLocalPlayer = pGame->GetPedContext();
2393+
2394+
if (IsPassenger(pLocalPlayer) || GetDriver() == pLocalPlayer)
2395+
audioInterface->SoundJoin();
2396+
}

Client/game_sa/CVehicleSA.h

+8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "CPhysicalSA.h"
1818
#include "CPoolsSA.h"
1919
#include "CHandlingManagerSA.h"
20+
#include "CVehicleAudioSettingsManagerSA.h"
2021
#include "CDamageManagerSA.h"
2122
#include "CDoorSA.h"
2223
#include "CColPointSA.h"
@@ -35,6 +36,7 @@ struct RwTexture;
3536
#define FUNC_CVehicle_GetBaseVehicleType 0x411D50
3637
#define FUNC_CVehicle_IsUpsideDown 0x6D1D90
3738
#define FUNC_CVehicle_SetEngineOn 0x41BDD0
39+
#define FUNC_CVehicle_IsPassenger 0x6D1BD0
3840
#define FUNC_CTrain_FindPositionOnTrackFromCoors 0x6F6CC0
3941

4042
#define FUNC_CVehicle_QueryPickedUpEntityWithWinch 0x6d3cf0
@@ -282,6 +284,10 @@ class CVehicleSAInterface : public CPhysicalSAInterface
282284
((void(__thiscall*)(CVehicleSAInterface*, RwFrame*, std::uint32_t))0x6D2700)(this, component, state);
283285
}
284286

287+
bool IsPassenger(CPedSAInterface* ped) const noexcept {
288+
return ((bool(__thiscall*)(CVehicleSAInterface const*, CPedSAInterface*))0x6D1BD0)(this, ped);
289+
}
290+
285291
CAEVehicleAudioEntitySAInterface m_VehicleAudioEntity; // 312
286292

287293
tHandlingDataSA* pHandlingData; // +900
@@ -477,6 +483,7 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA
477483
void SetRailTrack(BYTE ucTrackID);
478484
float GetTrainPosition();
479485
void SetTrainPosition(float fPosition, bool bRecalcOnRailDistance = true);
486+
bool IsPassenger(CPed* pPed) noexcept { return GetVehicleInterface()->IsPassenger(pPed->GetPedInterface()); };
480487

481488
void AddVehicleUpgrade(DWORD dwModelID);
482489
void RemoveVehicleUpgrade(DWORD dwModelID);
@@ -691,6 +698,7 @@ class CVehicleSA : public virtual CVehicle, public virtual CPhysicalSA
691698
bool SetWindowOpenFlagState(unsigned char ucWindow, bool bState);
692699
float GetWheelScale() override { return GetVehicleInterface()->m_fWheelScale; }
693700
void SetWheelScale(float fWheelScale) override { GetVehicleInterface()->m_fWheelScale = fWheelScale; }
701+
void ReinitAudio();
694702

695703
void UpdateLandingGearPosition();
696704

Client/mods/deathmatch/logic/CClientGame.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <game/CBuildingRemoval.h>
3636
#include "game/CClock.h"
3737
#include <game/CProjectileInfo.h>
38+
#include <game/CVehicleAudioSettingsManager.h>
3839
#include <windowsx.h>
3940
#include "CServerInfo.h"
4041

@@ -3490,6 +3491,8 @@ void CClientGame::Event_OnIngame()
34903491
// Make sure we never get tired
34913492
g_pGame->GetPlayerInfo()->SetDoesNotGetTired(true);
34923493

3494+
g_pGame->GetVehicleAudioSettingsManager()->ResetAudioSettingsData();
3495+
34933496
// Tell doggy we got the game running
34943497
WatchDogCompletedSection("L1");
34953498
}

0 commit comments

Comments
 (0)