Skip to content

Vehicle audio settings #2350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 9 additions & 24 deletions Client/game_sa/CAEVehicleAudioEntitySA.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#pragma once

#include "CVehicleAudioSettingsEntrySA.h"
#include <game/CAEVehicleAudioEntity.h>
#include "CAudioEngineSA.h"

Expand All @@ -20,28 +21,7 @@
#define FUNC_CAEVehicleAudioEntity__ProcessAIProp 0x4FDFD0
#define FUNC_CAEVehicleAudioEntity__ProcessAIHeli 0x4FEE20

struct tVehicleAudioSettings
{
char m_nVehicleSoundType;
char unk1;
short m_wEngineOnSoundBankId;
short m_wEngineOffSoundBankId;
char m_nStereo;
char unk2;
int unk3;
int unk4;
char m_bHornTon;
char unk5[3];
float m_fHornHigh;
char m_nDoorSound;
char unk6;
char m_nRadioNum;
char m_nRadioType;
char unk7;
char unk8[3];
float m_fHornVolumeDelta;
};
static_assert(sizeof(tVehicleAudioSettings) == 0x24, "Invalid size for tVehicleAudioSettings");
class CVehicleSAInterface;

struct tVehicleSound
{
Expand Down Expand Up @@ -73,9 +53,13 @@ static_assert(sizeof(CAETwinLoopSoundEntity) == 0xA8, "Invalid size for CAETwinL
class CAEVehicleAudioEntitySAInterface : public CAEAudioEntity
{
public:
void AddAudioEvent(int eventId, float volume)
void AddAudioEvent(int eventId, float volume) { ((void(__thiscall*)(CAEVehicleAudioEntitySAInterface*, int, float))0x4F6420)(this, eventId, volume); }
bool TerminateAudio() { return ((bool(__thiscall*)(CAEVehicleAudioEntitySAInterface*))0x4FB8C0)(this); }
bool SoundJoin() { return ((bool(__thiscall*)(CAEVehicleAudioEntitySAInterface*))0x4F5700)(this); }

int16_t InitAudio(CVehicleSAInterface* vehicle)
{
((void(__thiscall*)(CAEVehicleAudioEntitySAInterface*, int, float))0x4F6420)(this, eventId, volume);
return ((int16_t(__thiscall*)(CAEVehicleAudioEntitySAInterface*, CVehicleSAInterface*))0x4F7670)(this, vehicle);
}

short unk1; // +124
Expand Down Expand Up @@ -157,6 +141,7 @@ class CAEVehicleAudioEntitySA : public CAEVehicleAudioEntity
void JustGotOutOfVehicleAsDriver();
void TurnOnRadioForVehicle();
void StopVehicleEngineSound(unsigned char ucSlot);
CAEVehicleAudioEntitySAInterface* GetInterface() { return m_pInterface; };

private:
CAEVehicleAudioEntitySAInterface* m_pInterface;
Expand Down
2 changes: 2 additions & 0 deletions Client/game_sa/CGameSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ CGameSA::CGameSA()
m_pCoverManager = new CCoverManagerSA();
m_pPlantManager = new CPlantManagerSA();
m_pBuildingRemoval = new CBuildingRemovalSA();
m_pVehicleAudioSettingsManager = std::make_unique<CVehicleAudioSettingsManagerSA>();

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

Expand Down Expand Up @@ -247,6 +248,7 @@ CGameSA::CGameSA()
CCheckpointSA::StaticSetHooks();
CHudSA::StaticSetHooks();
CPtrNodeSingleLinkPoolSA::StaticSetHooks();
CVehicleAudioSettingsManagerSA::StaticSetHooks();
}
catch (const std::bad_alloc& e)
{
Expand Down
10 changes: 9 additions & 1 deletion Client/game_sa/CGameSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "CCoverManagerSA.h"
#include "CPlantManagerSA.h"
#include "CRendererSA.h"
#include "CVehicleAudioSettingsManagerSA.h"

class CAnimBlendClumpDataSAInterface;
class CObjectGroupPhysicalPropertiesSA;
Expand Down Expand Up @@ -174,7 +175,12 @@ class CGameSA : public CGame
CPlantManagerSA* GetPlantManager() const noexcept { return m_pPlantManager; };
CBuildingRemoval* GetBuildingRemoval() { return m_pBuildingRemoval; }
CRenderer* GetRenderer() const noexcept override { return m_pRenderer.get(); }


CVehicleAudioSettingsManager* GetVehicleAudioSettingsManager() const noexcept override
{
return m_pVehicleAudioSettingsManager.get();
}

CWeaponInfo* GetWeaponInfo(eWeaponType weapon, eWeaponSkill skill = WEAPONSKILL_STD);
CModelInfo* GetModelInfo(DWORD dwModelID, bool bCanBeInvalid = false);
CObjectGroupPhysicalProperties* GetObjectGroupPhysicalProperties(unsigned char ucObjectGroup);
Expand Down Expand Up @@ -351,6 +357,8 @@ class CGameSA : public CGame
CPlantManagerSA* m_pPlantManager;
CBuildingRemoval* m_pBuildingRemoval;

std::unique_ptr<CVehicleAudioSettingsManagerSA> m_pVehicleAudioSettingsManager;

std::unique_ptr<CRendererSA> m_pRenderer;

CPad* m_pPad;
Expand Down
81 changes: 81 additions & 0 deletions Client/game_sa/CVehicleAudioSettingsEntrySA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* LICENSE: See LICENSE in the top level directory
* FILE: game_sa/CVehicleAudioSettingsEntrySA.h
* PURPOSE: Header file for vehicle audio settings entry class
*
* Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#pragma once

#include "game/CVehicleAudioSettingsEntry.h"
#include <game/Common.h>

// SA interface
struct tVehicleAudioSettings
{
eVehicleSoundType m_eVehicleSoundType;
int16 m_nEngineOnSoundBankId;
int16 m_nEngineOffSoundBankId;
int8 m_nBassSetting; // 0 or 1 or 2
float m_fBassEq;
float field_C;
int8 m_nHornToneSoundInBank;
float m_fHornHigh;
char m_nDoorSound;
char m_EngineUpgrade;
char m_nRadioID;
char m_nRadioType;
char m_nVehTypeForAudio;
float m_fHornVolumeDelta;
};
static_assert(sizeof(tVehicleAudioSettings) == 0x24, "Invalid size for tVehicleAudioSettings");

class CVehicleAudioSettingsEntrySA final : public CVehicleAudioSettingsEntry
{
public:
CVehicleAudioSettingsEntrySA(): m_Settings{} {};
CVehicleAudioSettingsEntrySA(tVehicleAudioSettings* pSettings) { m_Settings = *pSettings; };
~CVehicleAudioSettingsEntrySA() = default;

const tVehicleAudioSettings& GetInterface() const noexcept { return m_Settings; };

void Assign(const tVehicleAudioSettings& settings) noexcept { m_Settings = settings; }
void Assign(const CVehicleAudioSettingsEntry& settings) noexcept { m_Settings = static_cast<const CVehicleAudioSettingsEntrySA&>(settings).GetInterface(); };

eVehicleSoundType GetSoundType() const noexcept override { return m_Settings.m_eVehicleSoundType; };
short GetEngineOnSoundBankID() const noexcept override { return m_Settings.m_nEngineOnSoundBankId; };
short GetEngineOffSoundBankID() const noexcept override { return m_Settings.m_nEngineOffSoundBankId; };
char GetBassSetting() const noexcept override { return m_Settings.m_nBassSetting; };
float GetBassEq() const noexcept override { return m_Settings.m_fBassEq; };
float GetFieldC() const noexcept override { return m_Settings.field_C; };
char GetHornTon() const noexcept override { return m_Settings.m_nHornToneSoundInBank; };
float GetHornHign() const noexcept override { return m_Settings.m_fHornHigh; };
char GetEngineUpgrade() const noexcept override { return m_Settings.m_EngineUpgrade; };
char GetDoorSound() const noexcept override { return m_Settings.m_nDoorSound; };
char GetRadioNum() const noexcept override { return m_Settings.m_nRadioID; };
char GetRadioType() const noexcept override { return m_Settings.m_nRadioType; };
char GetVehicleTypeForAudio() const noexcept override { return m_Settings.m_nVehTypeForAudio; };
float GetHornVolumeDelta() const noexcept override { return m_Settings.m_fHornVolumeDelta; };

void SetSoundType(eVehicleSoundType value) noexcept override { m_Settings.m_eVehicleSoundType = value; };
void SetEngineOnSoundBankID(short value) noexcept override { m_Settings.m_nEngineOnSoundBankId = value; };
void SetEngineOffSoundBankID(short value) noexcept override { m_Settings.m_nEngineOffSoundBankId = value; };
void SetBassSetting(char value) noexcept override { m_Settings.m_nBassSetting = value; };
void SetBassEq(float value) noexcept override { m_Settings.m_fBassEq = value; };
void SetFieldC(float value) noexcept override { m_Settings.field_C = value; };
void SetHornTon(char value) noexcept override { m_Settings.m_nHornToneSoundInBank = value; };
void SetHornHign(float value) noexcept override { m_Settings.m_fHornHigh = value; };
void SetEngineUpgrade(char value) noexcept override { m_Settings.m_EngineUpgrade = value; };
void SetDoorSound(char value) noexcept override { m_Settings.m_nDoorSound = value; };
void SetRadioNum(char value) noexcept override { m_Settings.m_nRadioID = value; };
void SetRadioType(char value) noexcept override { m_Settings.m_nRadioType = value; };
void SetVehicleTypeForAudio(char value) noexcept override { m_Settings.m_nVehTypeForAudio = value; };
void SetHornVolumeDelta(float value) noexcept override { m_Settings.m_fHornVolumeDelta = value; };

private:
tVehicleAudioSettings m_Settings;
};
68 changes: 68 additions & 0 deletions Client/game_sa/CVehicleAudioSettingsManagerSA.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* LICENSE: See LICENSE in the top level directory
* FILE: game_sa/CVehicleAudioSettingsEntry.cpp
* PURPOSE: Implementation file for vehicle audio settings manager class
*
* Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#include "StdInc.h"
#include "CVehicleAudioSettingsManagerSA.h"
#include <array>

const auto (&ORIGINAL_AUDIO_SETTINGS)[VEHICLES_COUNT] = *reinterpret_cast<const tVehicleAudioSettings (*)[VEHICLES_COUNT]>(0x860AF0);
tVehicleAudioSettings const * pNextVehicleAudioSettings = nullptr;

CVehicleAudioSettingsManagerSA::CVehicleAudioSettingsManagerSA()
{
ResetAudioSettingsData();
}

std::unique_ptr<CVehicleAudioSettingsEntry> CVehicleAudioSettingsManagerSA::CreateVehicleAudioSettingsData(uint32_t modelId)
{
auto settings = std::make_unique<CVehicleAudioSettingsEntrySA>();
const auto& fromSetting = GetVehicleModelAudioSettingsData(modelId);
settings->Assign(fromSetting);
return settings;
}

CVehicleAudioSettingsEntry& CVehicleAudioSettingsManagerSA::GetVehicleModelAudioSettingsData(uint32_t modelId) noexcept
{
return m_modelEntrys[GetVehicleModelAudioSettingsID(modelId)];
}

void CVehicleAudioSettingsManagerSA::SetNextSettings(CVehicleAudioSettingsEntry const* pSettings) noexcept
{
pNextVehicleAudioSettings = &static_cast<CVehicleAudioSettingsEntrySA const*>(pSettings)->GetInterface();
}

void CVehicleAudioSettingsManagerSA::SetNextSettings(uint32_t modelId) noexcept
{
pNextVehicleAudioSettings = &m_modelEntrys[GetVehicleModelAudioSettingsID(modelId)].GetInterface();
}

void CVehicleAudioSettingsManagerSA::ResetModelSettings(uint32_t modelId) noexcept
{
size_t index = GetVehicleModelAudioSettingsID(modelId);
m_modelEntrys[index].Assign(ORIGINAL_AUDIO_SETTINGS[index]);
}

void CVehicleAudioSettingsManagerSA::ResetAudioSettingsData() noexcept
{
for (size_t i = 0; i < VEHICLES_COUNT; i++)
m_modelEntrys[i].Assign(ORIGINAL_AUDIO_SETTINGS[i]);
}

void CVehicleAudioSettingsManagerSA::StaticSetHooks() noexcept
{
// Replace
// 8D 34 B5 F0 0A 86 00 ; lea esi, _VehicleAudioProperties.m_eVehicleSoundType[esi*4]
// to
// 8b 35 XX XX XX XX ; mov esi, [pNextVehicleAudioSettings]
// 90 ; nop
MemCpy((void*)0x4F77CA, "\x8B\x35\x00\x00\x00\x00\x90", 7);
MemPut(0x4F77CA + 2, (std::uint32_t)&pNextVehicleAudioSettings);
}
43 changes: 43 additions & 0 deletions Client/game_sa/CVehicleAudioSettingsManagerSA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*****************************************************************************
*
* PROJECT: Multi Theft Auto v1.0
* LICENSE: See LICENSE in the top level directory
* FILE: game_sa/CVehicleAudioSettingsManagerSA.h
* PURPOSE: Header file for vehicle audio settings manager class
*
* Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#pragma once

#include <game/CVehicleAudioSettingsManager.h>
#include "CVehicleAudioSettingsEntrySA.h"
#include "CAEVehicleAudioEntitySA.h"
#include <array>

constexpr size_t VEHICLES_COUNT = 212;

class CVehicleAudioSettingsManagerSA final : public CVehicleAudioSettingsManager
{
public:
CVehicleAudioSettingsManagerSA();

std::unique_ptr<CVehicleAudioSettingsEntry> CreateVehicleAudioSettingsData(uint32_t modelId) override;
CVehicleAudioSettingsEntry& GetVehicleModelAudioSettingsData(uint32_t modelId) noexcept override;

void ResetModelSettings(uint32_t modelId) noexcept override;
void ResetAudioSettingsData() noexcept override;

void SetNextSettings(CVehicleAudioSettingsEntry const* pSettings) noexcept override;
void SetNextSettings(uint32_t modelId) noexcept override;

static void StaticSetHooks() noexcept;

private:
size_t GetVehicleModelAudioSettingsID(uint32_t modelId) const noexcept { return modelId - 400; };

private:
// Array with the model audio settings entries
std::array<CVehicleAudioSettingsEntrySA, VEHICLES_COUNT> m_modelEntrys;
};
13 changes: 13 additions & 0 deletions Client/game_sa/CVehicleSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2381,3 +2381,16 @@ bool CVehicleSA::SetWindowOpenFlagState(unsigned char ucWindow, bool bState)
}
return bReturn;
}

void CVehicleSA::ReinitAudio()
{
auto* audioInterface = m_pVehicleAudioEntity->GetInterface();

audioInterface->TerminateAudio();
audioInterface->InitAudio(GetVehicleInterface());

CPed* pLocalPlayer = pGame->GetPedContext();

if (IsPassenger(pLocalPlayer) || GetDriver() == pLocalPlayer)
audioInterface->SoundJoin();
}
8 changes: 8 additions & 0 deletions Client/game_sa/CVehicleSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "CPhysicalSA.h"
#include "CPoolsSA.h"
#include "CHandlingManagerSA.h"
#include "CVehicleAudioSettingsManagerSA.h"
#include "CDamageManagerSA.h"
#include "CDoorSA.h"
#include "CColPointSA.h"
Expand All @@ -35,6 +36,7 @@ struct RwTexture;
#define FUNC_CVehicle_GetBaseVehicleType 0x411D50
#define FUNC_CVehicle_IsUpsideDown 0x6D1D90
#define FUNC_CVehicle_SetEngineOn 0x41BDD0
#define FUNC_CVehicle_IsPassenger 0x6D1BD0
#define FUNC_CTrain_FindPositionOnTrackFromCoors 0x6F6CC0

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

bool IsPassenger(CPedSAInterface* ped) const noexcept {
return ((bool(__thiscall*)(CVehicleSAInterface const*, CPedSAInterface*))0x6D1BD0)(this, ped);
}

CAEVehicleAudioEntitySAInterface m_VehicleAudioEntity; // 312

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

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

void UpdateLandingGearPosition();

Expand Down
3 changes: 3 additions & 0 deletions Client/mods/deathmatch/logic/CClientGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <game/CBuildingRemoval.h>
#include "game/CClock.h"
#include <game/CProjectileInfo.h>
#include <game/CVehicleAudioSettingsManager.h>
#include <windowsx.h>
#include "CServerInfo.h"

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

g_pGame->GetVehicleAudioSettingsManager()->ResetAudioSettingsData();

// Tell doggy we got the game running
WatchDogCompletedSection("L1");
}
Expand Down
Loading
Loading