Skip to content

Commit

Permalink
MWR/AW Streamed Audio
Browse files Browse the repository at this point in the history
  • Loading branch information
Scobalula committed Dec 13, 2018
1 parent fc49ca9 commit 9e8114a
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 62 deletions.
1 change: 1 addition & 0 deletions src/WraithXCOD/WraithXCOD/CoDAssetType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ CoDSound_t::CoDSound_t()
FrameCount = 0;
ChannelsCount = 0;
PackageIndex = 0;
Length = 0;
IsLocalized = false;
DataType = SoundDataTypes::WAV_WithHeader;
// Set type
Expand Down
3 changes: 2 additions & 1 deletion src/WraithXCOD/WraithXCOD/CoDAssetType.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ class CoDSound_t : public CoDAsset_t
uint32_t FrameCount;
// Channels count
uint8_t ChannelsCount;

// Channels count
uint32_t Length;
// The index of the sound package for this entry
uint16_t PackageIndex;
// Whether or not this is a localized entry
Expand Down
8 changes: 2 additions & 6 deletions src/WraithXCOD/WraithXCOD/CoDAssets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,13 +514,9 @@ bool CoDAssets::SortAssets(const CoDAsset_t* lhs, const CoDAsset_t* rhs)
auto Compare1 = (CoDSound_t*)lhs;
auto Compare2 = (CoDSound_t*)rhs;

// Get Time
auto Time1 = (float)Compare1->FrameCount / (float)Compare1->FrameRate;
auto Time2 = (float)Compare2->FrameCount / (float)Compare2->FrameRate;

// Sort by duration
if (Time1 < Time2) return false;
if (Time2 < Time1) return true;
if (Compare1->Length < Compare2->Length) return false;
if (Compare2->Length < Compare1->Length) return true;

// Done
break;
Expand Down
86 changes: 86 additions & 0 deletions src/WraithXCOD/WraithXCOD/DBGameAssets.h
Original file line number Diff line number Diff line change
Expand Up @@ -2093,6 +2093,49 @@ struct AWLoadedSound
};
#pragma pack(pop)

#pragma pack(push, 1)
struct AWSoundAlias
{
uint64_t NamePtr;
uint64_t EntriesPtr;
uint64_t Unknown1;
uint8_t EntryCount;
uint8_t Padding[0x7];
};
#pragma pack(pop)

#pragma pack(push, 1)
struct AWSoundAliasEntry
{
uint64_t NamePtr;
uint8_t Padding[0x18];
uint64_t FileSpecPtr;
uint8_t Padding2[0xC8];
};
#pragma pack(pop)

#pragma pack(push, 1)
struct AWSoundAliasFileSpec
{
uint8_t Type;
uint8_t Padding[0x7];
};
#pragma pack(pop)

#pragma pack(push, 1)
struct AWStreamedSound
{
uint8_t Padding[2];
uint16_t PackageIndex;
uint32_t Exists;
uint64_t Offset;
uint64_t Size;
uint32_t Length;
uint32_t Padding3;
uint64_t Padding4;
};
#pragma pack(pop)

#pragma endregion

#pragma region Modern Warfare RM
Expand Down Expand Up @@ -2299,6 +2342,49 @@ struct MWRXAnimDeltaParts
};
#pragma pack(pop)

#pragma pack(push, 1)
struct MWRSoundAlias
{
uint64_t NamePtr;
uint64_t EntriesPtr;
uint64_t Unknown1;
uint8_t EntryCount;
uint8_t Padding[0x7];
};
#pragma pack(pop)

#pragma pack(push, 1)
struct MWRSoundAliasEntry
{
uint64_t NamePtr;
uint8_t Padding[0x18];
uint64_t FileSpecPtr;
uint8_t Padding2[0xD0];
};
#pragma pack(pop)

#pragma pack(push, 1)
struct MWRSoundAliasFileSpec
{
uint8_t Type;
uint8_t Padding[0x7];
};
#pragma pack(pop)

#pragma pack(push, 1)
struct MWRStreamedSound
{
uint8_t Padding[2];
uint16_t PackageIndex;
uint32_t Exists;
uint64_t Offset;
uint64_t Size;
uint32_t Length;
uint32_t Padding3;
uint64_t Padding4;
};
#pragma pack(pop)

#pragma endregion

#pragma region InfiniteWarfare
Expand Down
105 changes: 78 additions & 27 deletions src/WraithXCOD/WraithXCOD/GameAdvancedWarfare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ bool GameAdvancedWarfare::LoadOffsets()
CoDAssets::GameOffsetInfos.emplace_back(CoDAssets::GameInstance->Read<uint64_t>(GameOffsets.DBAssetPools + (8 * 5)));
CoDAssets::GameOffsetInfos.emplace_back(CoDAssets::GameInstance->Read<uint64_t>(GameOffsets.DBAssetPools + (8 * 7)));
CoDAssets::GameOffsetInfos.emplace_back(CoDAssets::GameInstance->Read<uint64_t>(GameOffsets.DBAssetPools + (8 * 0x10)));
CoDAssets::GameOffsetInfos.emplace_back(CoDAssets::GameInstance->Read<uint64_t>(GameOffsets.DBAssetPools + (8 * 0x17)));
CoDAssets::GameOffsetInfos.emplace_back(CoDAssets::GameInstance->Read<uint64_t>(GameOffsets.DBAssetPools + (8 * 0x11)));
// Verify via first xmodel asset
auto FirstXModelName = CoDAssets::GameInstance->ReadNullTerminatedString(CoDAssets::GameInstance->Read<uint64_t>(CoDAssets::GameOffsetInfos[1] + 8));
// Check
Expand All @@ -77,7 +77,7 @@ bool GameAdvancedWarfare::LoadOffsets()
CoDAssets::GamePoolSizes.emplace_back(CoDAssets::GameInstance->Read<uint32_t>(GameOffsets.DBPoolSizes + (4 * 5)));
CoDAssets::GamePoolSizes.emplace_back(CoDAssets::GameInstance->Read<uint32_t>(GameOffsets.DBPoolSizes + (4 * 7)));
CoDAssets::GamePoolSizes.emplace_back(CoDAssets::GameInstance->Read<uint32_t>(GameOffsets.DBPoolSizes + (4 * 0x10)));
CoDAssets::GamePoolSizes.emplace_back(CoDAssets::GameInstance->Read<uint32_t>(GameOffsets.DBPoolSizes + (4 * 0x17)));
CoDAssets::GamePoolSizes.emplace_back(CoDAssets::GameInstance->Read<uint32_t>(GameOffsets.DBPoolSizes + (4 * 0x11)));
// Return success
return true;
}
Expand Down Expand Up @@ -112,7 +112,7 @@ bool GameAdvancedWarfare::LoadOffsets()
CoDAssets::GameOffsetInfos.emplace_back(CoDAssets::GameInstance->Read<uint64_t>(GameOffsets.DBAssetPools + (8 * 5)));
CoDAssets::GameOffsetInfos.emplace_back(CoDAssets::GameInstance->Read<uint64_t>(GameOffsets.DBAssetPools + (8 * 7)));
CoDAssets::GameOffsetInfos.emplace_back(CoDAssets::GameInstance->Read<uint64_t>(GameOffsets.DBAssetPools + (8 * 0x10)));
CoDAssets::GameOffsetInfos.emplace_back(CoDAssets::GameInstance->Read<uint64_t>(GameOffsets.DBAssetPools + (8 * 0x17)));
CoDAssets::GameOffsetInfos.emplace_back(CoDAssets::GameInstance->Read<uint64_t>(GameOffsets.DBAssetPools + (8 * 0x11)));
// Verify via first xmodel asset
auto FirstXModelName = CoDAssets::GameInstance->ReadNullTerminatedString(CoDAssets::GameInstance->Read<uint64_t>(CoDAssets::GameOffsetInfos[1] + 8));
// Check
Expand All @@ -129,7 +129,7 @@ bool GameAdvancedWarfare::LoadOffsets()
CoDAssets::GamePoolSizes.emplace_back(CoDAssets::GameInstance->Read<uint32_t>(GameOffsets.DBPoolSizes + (4 * 5)));
CoDAssets::GamePoolSizes.emplace_back(CoDAssets::GameInstance->Read<uint32_t>(GameOffsets.DBPoolSizes + (4 * 7)));
CoDAssets::GamePoolSizes.emplace_back(CoDAssets::GameInstance->Read<uint32_t>(GameOffsets.DBPoolSizes + (4 * 0x10)));
CoDAssets::GamePoolSizes.emplace_back(CoDAssets::GameInstance->Read<uint32_t>(GameOffsets.DBPoolSizes + (4 * 0x17)));
CoDAssets::GamePoolSizes.emplace_back(CoDAssets::GameInstance->Read<uint32_t>(GameOffsets.DBPoolSizes + (4 * 0x11)));
// Return success
return true;
}
Expand Down Expand Up @@ -353,56 +353,107 @@ bool GameAdvancedWarfare::LoadAssets()
ImageOffset += sizeof(AWGfxImage);
}
}

if (NeedsSounds)
{
// A temporary table for duplicates, since we are tracing from alias entries...
std::set<uint64_t> UniqueEntries;

// Sounds are the fourth offset and fourth pool, skip 8 byte pointer to free head
auto LoadedSoundOffset = CoDAssets::GameOffsetInfos[3] + 8;
auto LoadedSoundCount = CoDAssets::GamePoolSizes[3];

// Calculate maximum pool size
auto MaximumPoolOffset = (LoadedSoundCount * sizeof(AWLoadedSound)) + LoadedSoundOffset;
auto MaximumPoolOffset = (LoadedSoundCount * sizeof(AWSoundAlias)) + LoadedSoundOffset;
// Store original offset
auto MinimumPoolOffset = CoDAssets::GameOffsetInfos[3];

// Loop and read
for (uint32_t i = 0; i < LoadedSoundCount; i++)
{
// Read
auto SoundResult = CoDAssets::GameInstance->Read<AWLoadedSound>(LoadedSoundOffset);
auto SoundResult = CoDAssets::GameInstance->Read<AWSoundAlias>(LoadedSoundOffset);

// Check whether or not to skip, if the handle is 0, or, if the handle is a pointer within the current pool
if ((SoundResult.NamePtr > MinimumPoolOffset && SoundResult.NamePtr < MaximumPoolOffset) || SoundResult.NamePtr == 0)
{
// Advance
LoadedSoundOffset += sizeof(AWLoadedSound);
LoadedSoundOffset += sizeof(AWSoundAlias);
// Skip this asset
continue;
}

// Validate and load if need be
auto SoundName = CoDAssets::GameInstance->ReadNullTerminatedString(SoundResult.NamePtr);


// Make and add
auto LoadedSound = new CoDSound_t();
// Set
LoadedSound->AssetName = FileSystems::GetFileName(SoundName);
LoadedSound->AssetPointer = SoundResult.SoundDataPtr;
LoadedSound->FrameRate = SoundResult.FrameRate;
LoadedSound->FrameCount = SoundResult.FrameCount;
LoadedSound->AssetSize = SoundResult.SoundDataSize;
LoadedSound->ChannelsCount = SoundResult.Channels;
LoadedSound->IsFileEntry = false;
LoadedSound->FullPath = FileSystems::GetDirectoryName(SoundName);
LoadedSound->DataType = (SoundResult.Format == 7 || SoundResult.Format == 6) ? SoundDataTypes::FLAC_WithHeader : SoundDataTypes::WAV_NeedsHeader;
LoadedSound->AssetStatus = WraithAssetStatus::Loaded;

// Add
CoDAssets::GameAssets->LoadedAssets.push_back(LoadedSound);

for (uint32_t j = 0; j < SoundResult.EntryCount; j++)
{
// Load Alias
auto SoundAliasEntry = CoDAssets::GameInstance->Read<AWSoundAliasEntry>(SoundResult.EntriesPtr + (j * sizeof(AWSoundAliasEntry)));
// Load File Spec
auto SoundFileSpec = CoDAssets::GameInstance->Read<AWSoundAliasFileSpec>(SoundAliasEntry.FileSpecPtr);
// Check type
if (SoundFileSpec.Type == 1)
{
// Read Pointer to Sound
auto LoadedSoundPtr = CoDAssets::GameInstance->Read<uint64_t>(SoundAliasEntry.FileSpecPtr + 8);
// Validate uniqueness
if (UniqueEntries.insert(LoadedSoundPtr).second == false)
continue;
// Read Sound
auto LoadedSoundInfo = CoDAssets::GameInstance->Read<AWLoadedSound>(LoadedSoundPtr);

// Validate and load if need be
auto LoadedSoundName = CoDAssets::GameInstance->ReadNullTerminatedString(LoadedSoundInfo.NamePtr);

// Make and add
auto LoadedSound = new CoDSound_t();
// Set
LoadedSound->AssetName = FileSystems::GetFileName(LoadedSoundName);
LoadedSound->AssetPointer = LoadedSoundInfo.SoundDataPtr;
LoadedSound->FrameRate = LoadedSoundInfo.FrameRate;
LoadedSound->FrameCount = LoadedSoundInfo.FrameCount;
LoadedSound->AssetSize = LoadedSoundInfo.SoundDataSize;
LoadedSound->ChannelsCount = LoadedSoundInfo.Channels;
LoadedSound->IsFileEntry = false;
LoadedSound->FullPath = FileSystems::GetDirectoryName(LoadedSoundName);
LoadedSound->DataType = (LoadedSoundInfo.Format == 7 || LoadedSoundInfo.Format == 6) ? SoundDataTypes::FLAC_WithHeader : SoundDataTypes::WAV_NeedsHeader;
LoadedSound->AssetStatus = WraithAssetStatus::Loaded;
LoadedSound->Length = (uint32_t)(1000.0f * (float)(LoadedSound->FrameCount / (float)(LoadedSound->FrameRate)));
// Add
CoDAssets::GameAssets->LoadedAssets.push_back(LoadedSound);
}
else if (SoundFileSpec.Type == 2)
{
// Read Data
auto StreamedSoundInfo = CoDAssets::GameInstance->Read<AWStreamedSound>(SoundAliasEntry.FileSpecPtr + 8);
// Check does it exist
{
// Make and add
auto LoadedSound = new CoDSound_t();
// Set (we'll use the alias names since streamed audio is nameless)
LoadedSound->AssetName = Strings::Format("%s_%i", Strings::ToLower(SoundName).c_str(), j);
LoadedSound->IsFileEntry = true;
LoadedSound->DataType = SoundDataTypes::FLAC_WithHeader;
LoadedSound->AssetStatus = WraithAssetStatus::Loaded;
LoadedSound->PackageIndex = StreamedSoundInfo.PackageIndex;
LoadedSound->AssetPointer = StreamedSoundInfo.Offset;
LoadedSound->AssetSize = StreamedSoundInfo.Size;
LoadedSound->Length = StreamedSoundInfo.Length;
LoadedSound->IsLocalized = StreamedSoundInfo.Exists > 0;
// Add
CoDAssets::GameAssets->LoadedAssets.push_back(LoadedSound);
}
}
else
{
#if _DEBUG
// Log on debug
printf("Unknown sound type: %d\n", SoundFileSpec.Type);
#endif
}
}
// Advance
LoadedSoundOffset += sizeof(AWLoadedSound);
LoadedSoundOffset += sizeof(AWSoundAlias);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/WraithXCOD/WraithXCOD/GameGhosts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ bool GameGhosts::LoadAssets()
LoadedSound->FullPath = FileSystems::GetDirectoryName(SoundName);
LoadedSound->DataType = SoundDataTypes::WAV_NeedsHeader;
LoadedSound->AssetStatus = WraithAssetStatus::Loaded;
LoadedSound->Length = (uint32_t)(1000.0f * (float)(LoadedSound->FrameCount / (float)(LoadedSound->FrameRate)));

// Add
CoDAssets::GameAssets->LoadedAssets.push_back(LoadedSound);
Expand Down
Loading

0 comments on commit 9e8114a

Please sign in to comment.