private static void ConvertSounds(ProjectFile pf) { var dataAssets = ((GMChunkSOND)pf.DataHandle.Chunks["SOND"]).List; var agrp = (GMChunkAGRP)pf.DataHandle.Chunks["AGRP"]; var groups = agrp.List; bool updatedVersion = pf.DataHandle.VersionInfo.IsNumberAtLeast(1, 0, 0, 9999); // First, sort sounds alphabetically List <AssetSound> sortedSounds = updatedVersion ? pf.Sounds.OrderBy(x => x.Name).ToList() : pf.Sounds; // Get all the AUDO chunk handles in the game GMChunkAUDO defaultChunk = (GMChunkAUDO)pf.DataHandle.Chunks["AUDO"]; defaultChunk.List.Clear(); Dictionary <string, GMChunkAUDO> audioChunks = new Dictionary <string, GMChunkAUDO>(); Dictionary <string, int> audioChunkIndices = new Dictionary <string, int>(); if (agrp.AudioData != null) { for (int i = 1; i < groups.Count; i++) { if (agrp.AudioData.ContainsKey(i)) { var currChunk = (GMChunkAUDO)agrp.AudioData[i].Chunks["AUDO"]; currChunk.List.Clear(); audioChunks.Add(groups[i].Name.Content, currChunk); audioChunkIndices.Add(groups[i].Name.Content, i); } } } dataAssets.Clear(); Dictionary <AssetSound, GMSound> finalMap = new Dictionary <AssetSound, GMSound>(); for (int i = 0; i < sortedSounds.Count; i++) { AssetSound asset = sortedSounds[i]; GMSound dataAsset = new GMSound() { Name = pf.DataHandle.DefineString(asset.Name), Volume = asset.Volume, Flags = GMSound.AudioEntryFlags.Regular, Effects = 0, Pitch = asset.Pitch, File = pf.DataHandle.DefineString(asset.OriginalSoundFile), Type = (asset.Type != null) ? pf.DataHandle.DefineString(asset.Type) : null }; finalMap[asset] = dataAsset; switch (asset.Attributes) { case AssetSound.Attribute.CompressedStreamed: if (updatedVersion) { dataAsset.AudioID = -1; } else { dataAsset.AudioID = defaultChunk.List.Count - 1; } dataAsset.GroupID = pf.DataHandle.VersionInfo.BuiltinAudioGroupID; // might be wrong File.WriteAllBytes(Path.Combine(pf.DataHandle.Directory, asset.SoundFile), asset.SoundFileBuffer); break; case AssetSound.Attribute.UncompressOnLoad: case AssetSound.Attribute.Uncompressed: dataAsset.Flags |= GMSound.AudioEntryFlags.IsEmbedded; goto case AssetSound.Attribute.CompressedNotStreamed; case AssetSound.Attribute.CompressedNotStreamed: if (asset.Attributes != AssetSound.Attribute.Uncompressed) { dataAsset.Flags |= GMSound.AudioEntryFlags.IsCompressed; } int ind; GMChunkAUDO chunk; if (!audioChunkIndices.TryGetValue(asset.AudioGroup, out ind)) { ind = pf.DataHandle.VersionInfo.BuiltinAudioGroupID; // might be wrong chunk = defaultChunk; } else { chunk = audioChunks[asset.AudioGroup]; } dataAsset.GroupID = ind; dataAsset.AudioID = chunk.List.Count; chunk.List.Add(new GMAudio() { Data = asset.SoundFileBuffer }); break; } } // Actually add sounds to the data foreach (AssetSound snd in pf.Sounds) { dataAssets.Add(finalMap[snd]); } }
public override void ConvertProject(ProjectFile pf) { var dataAssets = pf.DataHandle.GetChunk <GMChunkSOND>().List; var agrp = pf.DataHandle.GetChunk <GMChunkAGRP>(); var groups = agrp.List; bool updatedVersion = pf.DataHandle.VersionInfo.IsNumberAtLeast(1, 0, 0, 9999); // First, sort sounds alphabetically List <AssetRef <AssetSound> > sortedSounds = updatedVersion ? pf.Sounds.OrderBy(x => x.Name).ToList() : pf.Sounds; // Get all the AUDO chunk handles in the game GMChunkAUDO defaultChunk = pf.DataHandle.GetChunk <GMChunkAUDO>(); defaultChunk.List.Clear(); Dictionary <string, GMChunkAUDO> audioChunks = new Dictionary <string, GMChunkAUDO>(); Dictionary <string, int> audioChunkIndices = new Dictionary <string, int>(); if (agrp.AudioData != null) { for (int i = 1; i < groups.Count; i++) { if (agrp.AudioData.ContainsKey(i)) { var currChunk = agrp.AudioData[i].GetChunk <GMChunkAUDO>(); currChunk.List.Clear(); audioChunks.Add(groups[i].Name.Content, currChunk); audioChunkIndices.Add(groups[i].Name.Content, i); } } } dataAssets.Clear(); Dictionary <AssetRef <AssetSound>, GMSound> finalMap = new Dictionary <AssetRef <AssetSound>, GMSound>(); for (int i = 0; i < sortedSounds.Count; i++) { AssetSound asset = sortedSounds[i].Asset; if (asset == null) { // This asset was never converted, so handle references and re-add it GMSound s = (GMSound)sortedSounds[i].DataAsset; // Get the group name from the cache var cachedData = (CachedSoundRefData)sortedSounds[i].CachedData; // Potentially handle the internal sound buffer if (cachedData.SoundBuffer != null) { string groupName = cachedData.AudioGroupName; int ind; GMChunkAUDO chunk; if (!audioChunkIndices.TryGetValue(groupName, out ind)) { ind = pf.DataHandle.VersionInfo.BuiltinAudioGroupID; // might be wrong chunk = defaultChunk; } else { chunk = audioChunks[groupName]; } s.GroupID = ind; s.AudioID = chunk.List.Count; chunk.List.Add(new GMAudio() { Data = cachedData.SoundBuffer }); } finalMap[sortedSounds[i]] = s; continue; } GMSound dataAsset = new GMSound() { Name = pf.DataHandle.DefineString(asset.Name), Volume = asset.Volume, Flags = GMSound.AudioEntryFlags.Regular, Effects = 0, Pitch = asset.Pitch, File = pf.DataHandle.DefineString(asset.OriginalSoundFile), Type = (asset.Type != null) ? pf.DataHandle.DefineString(asset.Type) : null }; finalMap[sortedSounds[i]] = dataAsset; switch (asset.Attributes) { case AssetSound.Attribute.CompressedStreamed: if (updatedVersion) { dataAsset.AudioID = -1; } else { dataAsset.AudioID = defaultChunk.List.Count - 1; } dataAsset.GroupID = pf.DataHandle.VersionInfo.BuiltinAudioGroupID; // might be wrong if (asset.SoundFileBuffer != null) { pf.DataHandle.Logger?.Invoke($"Writing sound file \"{asset.SoundFile}\"..."); pf.DataHandle.FileWrites.Post(new (Path.Combine(pf.DataHandle.Directory, asset.SoundFile), asset.SoundFileBuffer)); } break; case AssetSound.Attribute.UncompressOnLoad: case AssetSound.Attribute.Uncompressed: dataAsset.Flags |= GMSound.AudioEntryFlags.IsEmbedded; goto case AssetSound.Attribute.CompressedNotStreamed; case AssetSound.Attribute.CompressedNotStreamed: if (asset.Attributes != AssetSound.Attribute.Uncompressed) { dataAsset.Flags |= GMSound.AudioEntryFlags.IsCompressed; } int ind; GMChunkAUDO chunk; if (!audioChunkIndices.TryGetValue(asset.AudioGroup, out ind)) { ind = pf.DataHandle.VersionInfo.BuiltinAudioGroupID; // might be wrong chunk = defaultChunk; } else { chunk = audioChunks[asset.AudioGroup]; } dataAsset.GroupID = ind; dataAsset.AudioID = chunk.List.Count; chunk.List.Add(new GMAudio() { Data = asset.SoundFileBuffer }); break; } } // Actually add sounds to the data foreach (var assetRef in pf.Sounds) { dataAssets.Add(finalMap[assetRef]); } }