diff --git a/CUE4Parse b/CUE4Parse index e63d6ee9..afccc891 160000 --- a/CUE4Parse +++ b/CUE4Parse @@ -1 +1 @@ -Subproject commit e63d6ee96fba5e5742dcd9bdf7f834e95c3e4f8f +Subproject commit afccc8919be266a63d68125a87a5171615cfc1d2 diff --git a/FModel/ViewModels/AudioPlayerViewModel.cs b/FModel/ViewModels/AudioPlayerViewModel.cs index e8264f83..ec65f5cb 100644 --- a/FModel/ViewModels/AudioPlayerViewModel.cs +++ b/FModel/ViewModels/AudioPlayerViewModel.cs @@ -569,6 +569,7 @@ public class AudioPlayerViewModel : ViewModel, ISource, IDisposable case "wem": case "at9": case "raw": + case "hca": { if (TryConvert(out var wavFilePath)) { diff --git a/FModel/ViewModels/CUE4ParseViewModel.cs b/FModel/ViewModels/CUE4ParseViewModel.cs index c462e975..f7987da6 100644 --- a/FModel/ViewModels/CUE4ParseViewModel.cs +++ b/FModel/ViewModels/CUE4ParseViewModel.cs @@ -24,6 +24,7 @@ using CUE4Parse.UE4.AssetRegistry; using CUE4Parse.UE4.Assets; using CUE4Parse.UE4.Assets.Exports; using CUE4Parse.UE4.Assets.Exports.Animation; +using CUE4Parse.UE4.Assets.Exports.CriWare; using CUE4Parse.UE4.Assets.Exports.Fmod; using CUE4Parse.UE4.Assets.Exports.Material; using CUE4Parse.UE4.Assets.Exports.SkeletalMesh; @@ -33,6 +34,8 @@ using CUE4Parse.UE4.Assets.Exports.Texture; using CUE4Parse.UE4.Assets.Exports.Verse; using CUE4Parse.UE4.Assets.Exports.Wwise; using CUE4Parse.UE4.BinaryConfig; +using CUE4Parse.UE4.CriWare; +using CUE4Parse.UE4.CriWare.Readers; using CUE4Parse.UE4.FMod; using CUE4Parse.UE4.IO; using CUE4Parse.UE4.Localization; @@ -134,7 +137,9 @@ public class CUE4ParseViewModel : ViewModel private Lazy _wwiseProviderLazy; public WwiseProvider WwiseProvider => _wwiseProviderLazy.Value; private Lazy _fmodProviderLazy; - public FModProvider FmodProvider => _fmodProviderLazy?.Value; + public FModProvider FmodProvider => _fmodProviderLazy?.Value; + private Lazy _criWareProviderLazy; + public CriWareProvider CriWareProvider => _criWareProviderLazy?.Value; public ConcurrentBag UnknownExtensions = []; public CUE4ParseViewModel() @@ -288,7 +293,8 @@ public class CUE4ParseViewModel : ViewModel Provider.Initialize(); _wwiseProviderLazy = new Lazy(() => new WwiseProvider(Provider, UserSettings.Default.WwiseMaxBnkPrefetch)); - _fmodProviderLazy = new Lazy(() => new FModProvider(Provider, UserSettings.Default.GameDirectory)); + _fmodProviderLazy = new Lazy(() => new FModProvider(Provider, UserSettings.Default.GameDirectory)); + _criWareProviderLazy = new Lazy(() => new CriWareProvider(Provider, UserSettings.Default.GameDirectory)); Log.Information($"{Provider.Versions.Game} ({Provider.Versions.Platform}) | Archives: x{Provider.UnloadedVfs.Count} | AES: x{Provider.RequiredKeys.Count} | Loose Files: x{Provider.Files.Count}"); }); } @@ -769,7 +775,36 @@ public class CUE4ParseViewModel : ViewModel } break; - } + } + case "awb": + { + var archive = entry.CreateReader(); + var awbReader = new AwbReader(archive); + + var extractedSounds = CriWareProvider.ExtractCriWareSounds(awbReader, archive.Name); + foreach (var sound in extractedSounds) + { + SaveAndPlaySound(Path.Combine("/Criware/", sound.Name), sound.Extension, sound.Data, saveAudio); + } + + break; + } + + case "acb": + { + var archive = entry.CreateReader(); + var acbReader = new AcbReader(archive); + + TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(acbReader, Formatting.Indented), saveProperties, updateUi); + + var extractedSounds = CriWareProvider.ExtractCriWareSounds(acbReader, archive.Name); + foreach (var sound in extractedSounds) + { + SaveAndPlaySound(Path.Combine("/Criware/", sound.Name), sound.Extension, sound.Data, saveAudio); + } + + break; + } case "xvag": case "flac": case "at9": @@ -994,8 +1029,28 @@ public class CUE4ParseViewModel : ViewModel SaveAndPlaySound(Path.Combine(directory, sound.Name), sound.Extension, sound.Data, saveAudio); } return false; - } - case UAkMediaAssetData when isNone || saveAudio: + } + case USoundAtomCueSheet when isNone && pointer.Object.Value is USoundAtomCueSheet atomCueSheet: + { + var extractedSounds = CriWareProvider.ExtractCriWareSounds(atomCueSheet); + var directory = Path.GetDirectoryName(atomCueSheet.Owner?.Name) ?? "/Criware/"; + foreach (var sound in extractedSounds) + { + SaveAndPlaySound(Path.Combine(directory, sound.Name), sound.Extension, sound.Data, saveAudio); + } + return false; + } + case UAtomCueSheet when isNone && pointer.Object.Value is UAtomCueSheet atomCueSheet: + { + var extractedSounds = CriWareProvider.ExtractCriWareSounds(atomCueSheet); + var directory = Path.GetDirectoryName(atomCueSheet.Owner?.Name) ?? "/Criware/"; + foreach (var sound in extractedSounds) + { + SaveAndPlaySound(Path.Combine(directory, sound.Name), sound.Extension, sound.Data, saveAudio); + } + return false; + } + case UAkMediaAssetData when isNone || saveAudio: case USoundWave when isNone || saveAudio: { var shouldDecompress = UserSettings.Default.CompressedAudioMode == ECompressedAudio.PlayDecompressed; @@ -1216,4 +1271,4 @@ public class CUE4ParseViewModel : ViewModel { return (a & b) == b; } -} +}