From 8c593f666f259acb7e034351adc654bb3f07ca5c Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sat, 16 Mar 2024 11:47:59 +0100 Subject: [PATCH] Miles: add global type and prevent non-existent banks from loading This patch adds miles globals and additional code to prevent banks from loading that don't exist. It falls back to "english" if requested language isn't installed. --- r5dev/codecs/Miles/miles_impl.cpp | 38 +++++++++++++++++++++++-- r5dev/codecs/Miles/miles_impl.h | 47 ++++++++++++++++++++++++++++++- r5dev/public/tier1/stringpool.h | 4 +-- 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/r5dev/codecs/Miles/miles_impl.cpp b/r5dev/codecs/Miles/miles_impl.cpp index e083da56..ed56aa71 100644 --- a/r5dev/codecs/Miles/miles_impl.cpp +++ b/r5dev/codecs/Miles/miles_impl.cpp @@ -1,9 +1,11 @@ #include "core/stdafx.h" #include "miles_impl.h" #include "tier0/fasttimer.h" +#include "tier0/commandline.h" #include "tier1/cvar.h" +#include "filesystem/filesystem.h" -ConVar miles_debug("miles_debug", "0", FCVAR_RELEASE, "Enables debug prints for the Miles Sound System", "1 = print; 0 (zero) = no print"); +static ConVar miles_debug("miles_debug", "0", FCVAR_RELEASE, "Enables debug prints for the Miles Sound System", "1 = print; 0 (zero) = no print"); //----------------------------------------------------------------------------- // Purpose: logs debug output emitted from the Miles Sound System @@ -24,8 +26,24 @@ bool Miles_Initialize() { const char* pszLanguage = miles_language->GetString(); if (!pszLanguage[0]) - { pszLanguage = MILES_DEFAULT_LANGUAGE; + + const bool isEnglishLanguage = _stricmp(pszLanguage, "english") == 0; + + if (!isEnglishLanguage) + { + const bool useShipSound = !CommandLine()->FindParm("-devsound") || CommandLine()->FindParm("-shipsound"); + + const std::string baseStreamFilePath = Format("%s/general_%s.mstr", useShipSound ? "audio/ship" : "audio/dev", pszLanguage); + + // if the requested language for miles does not have a MSTR file present, throw a non-fatal error and force english as a fallback + // if we are loading english and the file is still not found, we can let it hit the regular engine error, since that is not recoverable + if (!FileSystem()->FileExists(baseStreamFilePath.c_str())) + { + Error(eDLL_T::AUDIO, NO_ERROR, "%s: attempted to load language '%s' but the required stream bank (%s) was not found. falling back to english...\n", pszLanguage, baseStreamFilePath.c_str()); + + pszLanguage = MILES_DEFAULT_LANGUAGE; + } } Msg(eDLL_T::AUDIO, "%s: initializing MSS with language: '%s'\n", __FUNCTION__, pszLanguage); @@ -53,6 +71,21 @@ void MilesBankPatch(Miles::Bank* bank, char* streamPatch, char* localizedStreamP v_MilesBankPatch(bank, streamPatch, localizedStreamPatch); } +void CSOM_AddEventToQueue(const char* eventName) +{ + if (miles_debug.GetBool()) + Msg(eDLL_T::AUDIO, "%s: queuing audio event '%s'\n", __FUNCTION__, eventName); + + v_CSOM_AddEventToQueue(eventName); + + if (g_milesGlobals->queuedEventHash == 1) + Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; invalid event name '%s'\n", __FUNCTION__, eventName); + + if (g_milesGlobals->queuedEventHash == 2) + Warning(eDLL_T::AUDIO, "%s: failed to add event to queue; event '%s' not found.\n", __FUNCTION__, eventName); +}; + + /////////////////////////////////////////////////////////////////////////////// void MilesCore::Detour(const bool bAttach) const { @@ -60,4 +93,5 @@ void MilesCore::Detour(const bool bAttach) const DetourSetup(&v_Miles_Initialize, &Miles_Initialize, bAttach); DetourSetup(&v_MilesQueueEventRun, &MilesQueueEventRun, bAttach); DetourSetup(&v_MilesBankPatch, &MilesBankPatch, bAttach); + DetourSetup(&v_CSOM_AddEventToQueue, &CSOM_AddEventToQueue, bAttach); } diff --git a/r5dev/codecs/Miles/miles_impl.h b/r5dev/codecs/Miles/miles_impl.h index 322be48b..74c4483c 100644 --- a/r5dev/codecs/Miles/miles_impl.h +++ b/r5dev/codecs/Miles/miles_impl.h @@ -6,6 +6,44 @@ inline void(*v_AIL_LogFunc)(int64_t nLogLevel, const char* pszMessage); inline bool(*v_Miles_Initialize)(); inline void(*v_MilesQueueEventRun)(Miles::Queue*, const char*); inline void(*v_MilesBankPatch)(Miles::Bank*, char*, char*); +inline void(*v_CSOM_AddEventToQueue)(const char* eventName); + +struct MilesBankList_t +{ + char banks[64][16]; + int bankCount; +}; + +struct MilesGlobalState_t +{ + char gap0[24]; + bool mismatchedBuildTag; + char gap19[63]; + uintptr_t queuedEventHash; + char gap60[4]; + Vector3D queuedSoundPosition; + char gap70[24]; + float soundMasterVolume; + char gap8c[28]; + void* samplesXlogType; + char gapB0[8]; + void* dumpXlogType; + char gapC0[48]; + void* driver; + void* queue; + char gap100[40]; + MilesBankList_t bankList; + char gap52c[4]; + void* loadedBanks[16]; + char gap5b0[290448]; + HANDLE milesInitializedEvent; + HANDLE milesThread; + char gap47450[272]; + char milesOutputBuffer[1024]; + char unk[96]; +}; + +inline MilesGlobalState_t* g_milesGlobals; /////////////////////////////////////////////////////////////////////////////// class MilesCore : public IDetour @@ -16,11 +54,18 @@ class MilesCore : public IDetour LogFunAdr("Miles_Initialize", v_Miles_Initialize); LogFunAdr("MilesQueueEventRun", v_MilesQueueEventRun); LogFunAdr("MilesBankPatch", v_MilesBankPatch); + LogFunAdr("CSOM_AddEventToQueue", v_CSOM_AddEventToQueue); + LogVarAdr("g_milesGlobals", g_milesGlobals); } virtual void GetFun(void) const { g_GameDll.FindPatternSIMD("40 53 48 83 EC 20 48 8B DA 48 8D 15 ?? ?? ?? ??").GetPtr(v_AIL_LogFunc); - g_GameDll.FindPatternSIMD("40 53 56 57 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ??").GetPtr(v_Miles_Initialize); + g_GameDll.FindPatternSIMD("0F B6 11 4C 8B C1").GetPtr(v_CSOM_AddEventToQueue); + + CMemory milesInitializeFunc = g_GameDll.FindPatternSIMD("40 53 56 57 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ??"); + milesInitializeFunc.GetPtr(v_Miles_Initialize); + + g_milesGlobals = milesInitializeFunc.FindPatternSelf("48 8D", CMemory::Direction::DOWN, 0x50).ResolveRelativeAddressSelf(0x3, 0x7).RCast<MilesGlobalState_t*>(); g_RadAudioSystemDll.GetExportedSymbol("MilesQueueEventRun").GetPtr(v_MilesQueueEventRun); g_RadAudioSystemDll.GetExportedSymbol("MilesBankPatch").GetPtr(v_MilesBankPatch); diff --git a/r5dev/public/tier1/stringpool.h b/r5dev/public/tier1/stringpool.h index 3ff006cf..7f753e1a 100644 --- a/r5dev/public/tier1/stringpool.h +++ b/r5dev/public/tier1/stringpool.h @@ -345,10 +345,10 @@ inline void CCountedStringPoolBase<T>::SpewStrings() char* pString = m_Elements[i].pString; NOTE_UNUSED(pString); - DevMsg("String %d: ref:%hhu %s\n", i, m_Elements[i].nReferenceCount, pString == NULL? "EMPTY - ok for slot zero only!" : pString); + DevMsg(eDLL_T::COMMON, "String %d: ref:%hhu %s\n", i, m_Elements[i].nReferenceCount, pString == NULL? "EMPTY - ok for slot zero only!" : pString); } - DevMsg("\n%d total counted strings.", m_Elements.Count()); + DevMsg(eDLL_T::COMMON, "\n%d total counted strings.", m_Elements.Count()); } #define STRING_POOL_VERSION MAKEID( 'C', 'S', 'P', '1' )