예제 #1
0
        private void CompileMainSFX(TRVersion.Game version, bool onlyIndexed)
        {
            LevelSettings settings;
            var           sounds = Sounds.SoundInfos;

            if (sounds.Count == 0)
            {
                popup.ShowError(soundInfoEditor, "No sounds present. Nothing to compile!");
                return;
            }

            settings = new LevelSettings()
            {
                GameVersion = version
            };
            settings.WadSoundPaths.Clear();
            var samplePath = LevelFileDialog.BrowseFolder(this, null, _configuration.SoundTool_LastMainSFXSamplePath,
                                                          "Choose a path where all samples are stored", null);

            if (string.IsNullOrEmpty(samplePath))
            {
                return; // User cancelled path selection
            }
            settings.WadSoundPaths.Add(new WadSoundPath(samplePath));
            _configuration.SoundTool_LastMainSFXSamplePath = samplePath; // Update settings

            var mainSFXPath = LevelFileDialog.BrowseFile(this, null, _configuration.SoundTool_LastMainSFXPath,
                                                         "Choose a path to save MAIN.SFX", _fileFormatSfx, null, true);

            if (string.IsNullOrEmpty(mainSFXPath))
            {
                return; // User cancelled saving
            }
            bool missing;
            var  samples = WadSample.CompileSamples(sounds, settings, onlyIndexed, out missing);

            try
            {
                using (var writer = new BinaryWriterEx(new FileStream(mainSFXPath, FileMode.Create, FileAccess.Write, FileShare.None)))
                {
                    foreach (var sample in samples.Values)
                    {
                        writer.Write(sample.Data, 0, sample.Data.Length);
                    }
                }

                var message = "MAIN.SFX compiled successfully!";
                if (missing)
                {
                    message += "\n" + "Some samples weren't found and won't play in game.";
                }
                popup.ShowInfo(soundInfoEditor, message);
                _configuration.SoundTool_LastMainSFXPath = mainSFXPath;
            }
            catch (Exception ex)
            {
                popup.ShowError(soundInfoEditor, "There was a error writing MAIN.SFX. \nException: " + ex.Message);
            }
        }
예제 #2
0
        private void PrepareSoundsData()
        {
            // Step 1: create the real list of sounds and indices to compile

            _finalSoundInfosList = new List <WadSoundInfo>();

            if (_level.Settings.GameVersion.UsesMainSfx())
            {
                _finalSelectedSoundsList = new List <int>(_level.Settings.SelectedSounds);
            }
            else
            {
                _finalSelectedSoundsList = new List <int>(_level.Settings.SelectedAndAvailableSounds);
            }

            foreach (var soundInfo in _level.Settings.GlobalSoundMap)
            {
                if (_finalSelectedSoundsList.Contains(soundInfo.Id))
                {
                    // Check if sound is marked as indexed. If not, exclude it from processing.
                    if (_level.Settings.GameVersion.UsesMainSfx() && !soundInfo.Indexed)
                    {
                        _progressReporter.ReportWarn("Sound info #" + soundInfo.Id +
                                                     " was selected but was not set as included for TR2-3 MAIN.SFX in SoundTool. It was removed.");
                        _finalSelectedSoundsList.Remove(soundInfo.Id);
                    }
                    else
                    {
                        _finalSoundInfosList.Add(soundInfo);
                    }
                }
            }

            // Step 2: Prepare indices list to be written (needed only for TR2-3).
            // For that, we iterate through ALL sound infos available and count how many samples
            // each of them have. Then we build a list of needed sound IDs with appropriate
            // sample count, which is used later to store indices.
            // Indices are not necessary for TR4-5, but are for TR2-3 cause main.sfx is used.

            _finalSoundIndicesList = new List <int>();
            int currentIndex = 0;

            foreach (var sound in _level.Settings.GlobalSoundMap)
            {
                // Don't include indices for non-indexed sounds
                if (_level.Settings.GameVersion.UsesMainSfx() && !sound.Indexed)
                {
                    continue;
                }

                if (_finalSoundInfosList.Contains(sound))
                {
                    foreach (var sample in sound.Samples)
                    {
                        _finalSoundIndicesList.Add(currentIndex);
                        currentIndex++;
                    }
                }
                else
                {
                    currentIndex += sound.Samples.Count;
                }
            }

            // HACK: TRNG for some reason remaps certain legacy TR object sounds into extended soundmap array.
            // There is no other way of guessing it except looking if there is a specific object in any of wads.

            if (_level.Settings.GameVersion == TRVersion.Game.TRNG)
            {
                Action <int, int, int> AddRemappedNGSound = delegate(int moveableTypeToCheck, int originalId, int remappedId)
                {
                    if (_level.Settings.Wads.Any(w => w.Wad.Moveables.Any(m => (m.Value.Id.TypeId == moveableTypeToCheck))))
                    {
                        if (!_finalSelectedSoundsList.Contains(remappedId) && _finalSelectedSoundsList.Contains(originalId))
                        {
                            _progressReporter.ReportWarn("TRNG object with ID " + moveableTypeToCheck + " was found which uses missing hardcoded sound ID " + remappedId + " in embedded soundmap. Trying to remap sound ID from legacy ID (" + originalId + ").");
                            _finalSelectedSoundsList.Add(remappedId);

                            var oldSound = _finalSoundInfosList.FirstOrDefault(snd => snd.Id == originalId);
                            if (oldSound != null)
                            {
                                var newSound = new WadSoundInfo(oldSound);
                                newSound.Id = remappedId;
                                _finalSoundInfosList.Add(newSound);
                            }
                        }
                    }
                };

                // Motorboat
                AddRemappedNGSound(465, 308, 1053);
                AddRemappedNGSound(465, 307, 1055);

                // Rubber boat
                AddRemappedNGSound(467, 308, 1423);
                AddRemappedNGSound(467, 307, 1425);
            }

            // Step 3: create the sound map
            switch (_level.Settings.GameVersion)
            {
            case TRVersion.Game.TRNG:
                _soundMapSize = 2048;
                break;

            case TRVersion.Game.TR2:
            case TRVersion.Game.TR3:
            case TRVersion.Game.TR4:
                _soundMapSize = 370;
                break;

            case TRVersion.Game.TR5:
                _soundMapSize = 450;
                break;

            case TRVersion.Game.TR5Main:
                _soundMapSize = 4096;
                break;

            default:
                throw new Exception("Unknown game version " + _level.Settings.GameVersion);
            }

            _finalSoundMap = Enumerable.Repeat((short)-1, _soundMapSize).ToArray <short>();
            foreach (var sound in _finalSoundInfosList)
            {
                if (sound.Id >= _soundMapSize)
                {
                    _progressReporter.ReportWarn("Sound info #" + sound.Id + " wasn't included because max. ID for this game version is " + _soundMapSize + ".");
                    continue;
                }
                _finalSoundMap[sound.Id] = (short)_finalSoundInfosList.IndexOf(sound);
            }

            // Samples aren't needed for TR2-3, skip next step
            if (_level.Settings.GameVersion.UsesMainSfx())
            {
                // Additionally warn user if he uses several sound catalogs which is incompatible with MAIN.SFX workflow.
                if (_level.Settings.SoundsCatalogs.Count > 1)
                {
                    _progressReporter.ReportWarn("Multiple sound catalogs can't be used with TR2 and TR3. Results are unpredictable. Remove all sound catalogs but one.");
                }
                return;
            }

            // Step 4: load samples
            var loadedSamples = WadSample.CompileSamples(_finalSoundInfosList, _level.Settings, false, _progressReporter);

            _finalSamplesList = loadedSamples.Values.ToList();
        }