Added audio playback to cutscene viewer

This commit is contained in:
dexy 2020-03-07 23:05:03 +11:00
parent 419c63af93
commit 44756e0277
2 changed files with 376 additions and 36 deletions

View File

@ -40,11 +40,16 @@
this.TimeLabel = new System.Windows.Forms.Label();
this.PlayStopButton = new System.Windows.Forms.Button();
this.PlaybackTimer = new System.Windows.Forms.Timer(this.components);
this.VolumeLabel = new System.Windows.Forms.Label();
this.VolumeTrackBar = new System.Windows.Forms.TrackBar();
this.SubtitlesCheckBox = new System.Windows.Forms.CheckBox();
this.AudioCheckBox = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.TimeTrackBar)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.VolumeTrackBar)).BeginInit();
this.SuspendLayout();
//
// label3
@ -53,7 +58,7 @@
this.label3.Location = new System.Drawing.Point(10, 10);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(55, 13);
this.label3.TabIndex = 3;
this.label3.TabIndex = 0;
this.label3.Text = "Cutscene:";
//
// CutsceneComboBox
@ -65,8 +70,8 @@
this.CutsceneComboBox.FormattingEnabled = true;
this.CutsceneComboBox.Location = new System.Drawing.Point(71, 7);
this.CutsceneComboBox.Name = "CutsceneComboBox";
this.CutsceneComboBox.Size = new System.Drawing.Size(529, 21);
this.CutsceneComboBox.TabIndex = 2;
this.CutsceneComboBox.Size = new System.Drawing.Size(639, 21);
this.CutsceneComboBox.TabIndex = 1;
this.CutsceneComboBox.SelectedIndexChanged += new System.EventHandler(this.CutsceneComboBox_SelectedIndexChanged);
//
// splitContainer1
@ -74,7 +79,7 @@
this.splitContainer1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.splitContainer1.Location = new System.Drawing.Point(1, 70);
this.splitContainer1.Location = new System.Drawing.Point(1, 99);
this.splitContainer1.Name = "splitContainer1";
//
// splitContainer1.Panel1
@ -84,9 +89,9 @@
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.InfoPropertyGrid);
this.splitContainer1.Size = new System.Drawing.Size(722, 330);
this.splitContainer1.Size = new System.Drawing.Size(722, 361);
this.splitContainer1.SplitterDistance = 259;
this.splitContainer1.TabIndex = 4;
this.splitContainer1.TabIndex = 13;
//
// CutsceneTreeView
//
@ -98,8 +103,8 @@
this.CutsceneTreeView.Name = "CutsceneTreeView";
this.CutsceneTreeView.ShowLines = false;
this.CutsceneTreeView.ShowRootLines = false;
this.CutsceneTreeView.Size = new System.Drawing.Size(259, 330);
this.CutsceneTreeView.TabIndex = 1;
this.CutsceneTreeView.Size = new System.Drawing.Size(259, 361);
this.CutsceneTreeView.TabIndex = 14;
this.CutsceneTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.CutsceneTreeView_AfterSelect);
//
// InfoPropertyGrid
@ -108,19 +113,18 @@
this.InfoPropertyGrid.HelpVisible = false;
this.InfoPropertyGrid.Location = new System.Drawing.Point(0, 0);
this.InfoPropertyGrid.Name = "InfoPropertyGrid";
this.InfoPropertyGrid.Size = new System.Drawing.Size(459, 330);
this.InfoPropertyGrid.TabIndex = 0;
this.InfoPropertyGrid.Size = new System.Drawing.Size(459, 361);
this.InfoPropertyGrid.TabIndex = 15;
//
// AnimateCameraCheckBox
//
this.AnimateCameraCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.AnimateCameraCheckBox.AutoSize = true;
this.AnimateCameraCheckBox.Checked = true;
this.AnimateCameraCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.AnimateCameraCheckBox.Location = new System.Drawing.Point(617, 9);
this.AnimateCameraCheckBox.Location = new System.Drawing.Point(250, 74);
this.AnimateCameraCheckBox.Name = "AnimateCameraCheckBox";
this.AnimateCameraCheckBox.Size = new System.Drawing.Size(102, 17);
this.AnimateCameraCheckBox.TabIndex = 5;
this.AnimateCameraCheckBox.TabIndex = 8;
this.AnimateCameraCheckBox.Text = "Animate camera";
this.AnimateCameraCheckBox.UseVisualStyleBackColor = true;
this.AnimateCameraCheckBox.CheckedChanged += new System.EventHandler(this.AnimateCameraCheckBox_CheckedChanged);
@ -131,30 +135,29 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.TimeTrackBar.AutoSize = false;
this.TimeTrackBar.LargeChange = 0;
this.TimeTrackBar.Location = new System.Drawing.Point(91, 34);
this.TimeTrackBar.Location = new System.Drawing.Point(12, 34);
this.TimeTrackBar.Maximum = 100;
this.TimeTrackBar.Name = "TimeTrackBar";
this.TimeTrackBar.Size = new System.Drawing.Size(509, 30);
this.TimeTrackBar.TabIndex = 7;
this.TimeTrackBar.Size = new System.Drawing.Size(700, 30);
this.TimeTrackBar.TabIndex = 2;
this.TimeTrackBar.Scroll += new System.EventHandler(this.TimeTrackBar_Scroll);
this.TimeTrackBar.MouseUp += new System.Windows.Forms.MouseEventHandler(this.TimeTrackBar_MouseUp);
//
// TimeLabel
//
this.TimeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.TimeLabel.AutoSize = true;
this.TimeLabel.Location = new System.Drawing.Point(614, 41);
this.TimeLabel.Location = new System.Drawing.Point(103, 75);
this.TimeLabel.Name = "TimeLabel";
this.TimeLabel.Size = new System.Drawing.Size(60, 13);
this.TimeLabel.TabIndex = 8;
this.TimeLabel.Size = new System.Drawing.Size(129, 16);
this.TimeLabel.TabIndex = 7;
this.TimeLabel.Text = "0.00 / 0.00";
this.TimeLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// PlayStopButton
//
this.PlayStopButton.Location = new System.Drawing.Point(10, 36);
this.PlayStopButton.Location = new System.Drawing.Point(13, 70);
this.PlayStopButton.Name = "PlayStopButton";
this.PlayStopButton.Size = new System.Drawing.Size(75, 23);
this.PlayStopButton.TabIndex = 9;
this.PlayStopButton.TabIndex = 3;
this.PlayStopButton.Text = "Play";
this.PlayStopButton.UseVisualStyleBackColor = true;
this.PlayStopButton.Click += new System.EventHandler(this.PlayStopButton_Click);
@ -163,11 +166,66 @@
//
this.PlaybackTimer.Tick += new System.EventHandler(this.PlaybackTimer_Tick);
//
// VolumeLabel
//
this.VolumeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.VolumeLabel.AutoSize = true;
this.VolumeLabel.Location = new System.Drawing.Point(549, 75);
this.VolumeLabel.Name = "VolumeLabel";
this.VolumeLabel.Size = new System.Drawing.Size(56, 13);
this.VolumeLabel.TabIndex = 11;
this.VolumeLabel.Text = "🕩 Volume";
//
// VolumeTrackBar
//
this.VolumeTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.VolumeTrackBar.AutoSize = false;
this.VolumeTrackBar.BackColor = System.Drawing.SystemColors.Control;
this.VolumeTrackBar.LargeChange = 10;
this.VolumeTrackBar.Location = new System.Drawing.Point(605, 71);
this.VolumeTrackBar.Maximum = 100;
this.VolumeTrackBar.Name = "VolumeTrackBar";
this.VolumeTrackBar.Size = new System.Drawing.Size(105, 28);
this.VolumeTrackBar.TabIndex = 12;
this.VolumeTrackBar.TickStyle = System.Windows.Forms.TickStyle.None;
this.VolumeTrackBar.Value = 50;
this.VolumeTrackBar.Scroll += new System.EventHandler(this.VolumeTrackBar_Scroll);
//
// SubtitlesCheckBox
//
this.SubtitlesCheckBox.AutoSize = true;
this.SubtitlesCheckBox.Checked = true;
this.SubtitlesCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.SubtitlesCheckBox.Location = new System.Drawing.Point(368, 74);
this.SubtitlesCheckBox.Name = "SubtitlesCheckBox";
this.SubtitlesCheckBox.Size = new System.Drawing.Size(66, 17);
this.SubtitlesCheckBox.TabIndex = 9;
this.SubtitlesCheckBox.Text = "Subtitles";
this.SubtitlesCheckBox.UseVisualStyleBackColor = true;
this.SubtitlesCheckBox.CheckedChanged += new System.EventHandler(this.SubtitlesCheckBox_CheckedChanged);
//
// AudioCheckBox
//
this.AudioCheckBox.AutoSize = true;
this.AudioCheckBox.Checked = true;
this.AudioCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
this.AudioCheckBox.Location = new System.Drawing.Point(450, 74);
this.AudioCheckBox.Name = "AudioCheckBox";
this.AudioCheckBox.Size = new System.Drawing.Size(53, 17);
this.AudioCheckBox.TabIndex = 10;
this.AudioCheckBox.Text = "Audio";
this.AudioCheckBox.UseVisualStyleBackColor = true;
this.AudioCheckBox.CheckedChanged += new System.EventHandler(this.AudioCheckBox_CheckedChanged);
//
// CutsceneForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(724, 401);
this.ClientSize = new System.Drawing.Size(724, 461);
this.Controls.Add(this.VolumeTrackBar);
this.Controls.Add(this.AudioCheckBox);
this.Controls.Add(this.SubtitlesCheckBox);
this.Controls.Add(this.VolumeLabel);
this.Controls.Add(this.PlayStopButton);
this.Controls.Add(this.TimeLabel);
this.Controls.Add(this.TimeTrackBar);
@ -178,6 +236,7 @@
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "CutsceneForm";
this.Text = "Cutscene Viewer - CodeWalker by dexyfex";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.CutsceneForm_FormClosing);
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.CutsceneForm_FormClosed);
this.Load += new System.EventHandler(this.CutsceneForm_Load);
this.splitContainer1.Panel1.ResumeLayout(false);
@ -185,6 +244,7 @@
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.TimeTrackBar)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.VolumeTrackBar)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@ -202,5 +262,9 @@
private System.Windows.Forms.Label TimeLabel;
private System.Windows.Forms.Button PlayStopButton;
private System.Windows.Forms.Timer PlaybackTimer;
private System.Windows.Forms.Label VolumeLabel;
private System.Windows.Forms.TrackBar VolumeTrackBar;
private System.Windows.Forms.CheckBox SubtitlesCheckBox;
private System.Windows.Forms.CheckBox AudioCheckBox;
}
}

View File

@ -1,5 +1,6 @@
using CodeWalker.GameFiles;
using CodeWalker.Rendering;
using CodeWalker.Utils;
using SharpDX;
using System;
using System.Collections.Generic;
@ -18,13 +19,16 @@ namespace CodeWalker.World
{
private WorldForm WorldForm;
private GameFileCache GameFileCache;
private AudioDatabase AudioDatabase;
private Cutscene Cutscene = null;
private bool AnimateCamera = true;
private bool EnableSubtitles = true;
private bool EnableAudio = true;
private bool Playing = false;
private bool PositionScrolled = false;
private float Volume = 0.5f;
class CutsceneDropdownItem
{
@ -40,6 +44,7 @@ namespace CodeWalker.World
{
WorldForm = worldForm;
GameFileCache = WorldForm.GameFileCache;
AudioDatabase = new AudioDatabase();
InitializeComponent();
}
@ -53,6 +58,14 @@ namespace CodeWalker.World
{
var newt = Cutscene.PlaybackTime + elapsed;
Cutscene.Update(newt);
if (Cutscene.PlaybackTime != newt)
{
if (EnableAudio) // handle looping cutscenes, loop the audio also
{
BeginInvoke(new Action(() => PlayAudio(Cutscene.PlaybackTime)));
}
}
}
if (AnimateCamera && (Cutscene.CameraObject != null))
@ -99,6 +112,11 @@ namespace CodeWalker.World
if (GameFileCache.IsInited)
{
if (!AudioDatabase.IsInited)
{
AudioDatabase.Init(GameFileCache);
}
var entry = dditem?.RpfEntry as RpfFileEntry;
if (entry != null)
{
@ -107,7 +125,7 @@ namespace CodeWalker.World
GameFileCache.RpfMan.LoadFile(cutFile, entry);
cutscene = new Cutscene();
cutscene.Init(cutFile, GameFileCache, WorldForm);
cutscene.Init(cutFile, GameFileCache, WorldForm, AudioDatabase);
}
}
@ -129,8 +147,20 @@ namespace CodeWalker.World
return;
}
DisposeAudio();
Cutscene = cs;
if (cs != null)
{
cs.EnableSubtitles = EnableSubtitles;
if (Playing)
{
PlayAudio(cs.PlaybackTime);
}
}
LoadTreeView(cs);
TimeTrackBar.Maximum = (int)(cs.Duration * 10.0f);
@ -211,8 +241,52 @@ namespace CodeWalker.World
private void PlayAudio(float playTime = 0.0f)
{
StopAudio();
if (!EnableAudio) return;
var sp = Cutscene?.SoundPlayer;
if (sp != null)
{
sp.SetVolume(Volume);
sp.Play(Cutscene.SoundStartOffset + playTime);
}
}
private void StopAudio()
{
var sp = Cutscene?.SoundPlayer;
if (sp != null)
{
sp.Stop();
}
}
private void PauseAudio()
{
if (!EnableAudio) return;
var sp = Cutscene?.SoundPlayer;
if (sp != null)
{
sp.Pause();
}
}
private void ResumeAudio()
{
if (!EnableAudio) return;
var sp = Cutscene?.SoundPlayer;
if (sp != null)
{
sp.Resume();
}
}
private void DisposeAudio()
{
var sp = Cutscene?.SoundPlayer;
if (sp != null)
{
sp.Stop();
sp.DisposeAudio();
}
}
private void CutsceneForm_Load(object sender, EventArgs e)
@ -242,6 +316,11 @@ namespace CodeWalker.World
}
private void CutsceneForm_FormClosing(object sender, FormClosingEventArgs e)
{
DisposeAudio();
}
private void CutsceneForm_FormClosed(object sender, FormClosedEventArgs e)
{
WorldForm?.OnCutsceneFormClosed();
@ -275,6 +354,31 @@ namespace CodeWalker.World
}
}
private void SubtitlesCheckBox_CheckedChanged(object sender, EventArgs e)
{
EnableSubtitles = SubtitlesCheckBox.Checked;
if (Cutscene != null)
{
Cutscene.EnableSubtitles = EnableSubtitles;
}
}
private void AudioCheckBox_CheckedChanged(object sender, EventArgs e)
{
EnableAudio = AudioCheckBox.Checked;
if (!EnableAudio)
{
StopAudio();
}
else
{
if (Playing && (Cutscene != null))
{
PlayAudio(Cutscene.PlaybackTime);
}
}
}
private void PlayStopButton_Click(object sender, EventArgs e)
{
if (Playing)
@ -282,12 +386,14 @@ namespace CodeWalker.World
Playing = false;
PlayStopButton.Text = "Play";
PlaybackTimer.Enabled = false;
StopAudio();
}
else
{
Playing = true;
PlayStopButton.Text = "Stop";
PlaybackTimer.Enabled = true;
PlayAudio(Cutscene.PlaybackTime);
}
}
@ -309,6 +415,11 @@ namespace CodeWalker.World
if (Cutscene != null)
{
Cutscene.Update(t);
if (Playing)
{
PlayAudio(t);
}
}
if (!Playing)
@ -327,11 +438,17 @@ namespace CodeWalker.World
PositionScrolled = false;
var f = Math.Min(Math.Max((e.X - 13.0f) / (TimeTrackBar.Width - 26.0f), 0.0f), 1.0f);
var v = f * (TimeTrackBar.Maximum / 10.0f);
var t = f * (TimeTrackBar.Maximum / 10.0f);
if (Cutscene != null)
{
Cutscene.Update(v);
Cutscene.Update(t);
if (Playing)
{
StopAudio();
PlayAudio(t);
}
}
if (!Playing)
@ -340,6 +457,16 @@ namespace CodeWalker.World
UpdateTimeLabel();
}
}
private void VolumeTrackBar_Scroll(object sender, EventArgs e)
{
Volume = VolumeTrackBar.Value / 100.0f;
var sp = Cutscene?.SoundPlayer;
if (sp != null)
{
sp.SetVolume(Volume);
}
}
}
@ -348,6 +475,7 @@ namespace CodeWalker.World
public CutFile CutFile { get; set; } = null;
private GameFileCache GameFileCache = null;
private WorldForm WorldForm = null;
private AudioDatabase AudioDB = null;
public float[] CameraCutList { get; set; } = null;
public YcdFile[] Ycds { get; set; } = null;
@ -357,6 +485,8 @@ namespace CodeWalker.World
public float PlaybackTime { get; set; } = 0.0f;
private bool Seeking = false;
public bool EnableSubtitles { get; set; } = true;
public Dictionary<int, CutObject> Objects { get; set; } = null;
public Dictionary<int, CutsceneObject> SceneObjects { get; set; } = null;
@ -381,14 +511,17 @@ namespace CodeWalker.World
public bool CameraClipUpdate = false;//signal to the form to update the camera clip planes
public Quaternion CameraRotationOffset = Quaternion.RotationAxis(Vector3.UnitX, -1.57079632679f) * Quaternion.RotationAxis(Vector3.UnitZ, 3.141592653f);
public AudioPlayer SoundPlayer { get; set; } = null;
public float SoundStartOffset { get; set; }
public void Init(CutFile cutFile, GameFileCache gfc, WorldForm wf)
public void Init(CutFile cutFile, GameFileCache gfc, WorldForm wf, AudioDatabase adb)
{
CutFile = cutFile;
GameFileCache = gfc;
WorldForm = wf;
AudioDB = adb;
var csf = cutFile?.CutsceneFile2;
if (csf == null) return;
@ -766,6 +899,37 @@ namespace CodeWalker.World
if (args == null)
{ return; }
var obje = e as CutObjectIdEvent;
if (obje == null)
{ return; }
var obj = obje.Object as CutAudioObject;
if (obj == null)
{ return; }
if (Seeking) return;
if (SceneObjects.TryGetValue(obje.iObjectId, out CutsceneObject audobj))
{
if (audobj.SoundPlayer != null)
{
SoundStartOffset = obj.fOffset;
if (SoundPlayer != audobj.SoundPlayer)
{
if (SoundPlayer != null)
{
SoundPlayer.Stop();
SoundPlayer.DisposeAudio();
SoundPlayer = null;
}
SoundPlayer = audobj.SoundPlayer;
}
}
else
{ }
}
else
{ }
}
private void LoadModels(CutEvent e)
{
@ -962,6 +1126,7 @@ namespace CodeWalker.World
if (args == null)
{ return; }
if (!EnableSubtitles) return;
if (Seeking) return; //don't raise subtitle events while seeking backwards...
if (WorldForm != null)
@ -1109,7 +1274,7 @@ namespace CodeWalker.World
foreach (var obj in Objects.Values)
{
var sobj = new CutsceneObject();
sobj.Init(obj, GameFileCache);
sobj.Init(obj, GameFileCache, AudioDB);
SceneObjects[sobj.ObjectID] = sobj;
if (sobj.AnimHash != 0)
@ -1148,10 +1313,14 @@ namespace CodeWalker.World
public MetaHash AnimHash { get; set; }
public ClipMapEntry AnimClip { get; set; }
public Dat54Sound SoundInfo { get; set; }
public AwcStream[] SoundStreams { get; set; }
public AudioPlayer SoundPlayer { get; set; }
public bool Enabled { get; set; } = false;
public void Init(CutObject obj, GameFileCache gfc)
public void Init(CutObject obj, GameFileCache gfc, AudioDatabase adb)
{
CutObject = obj;
ObjectID = obj?.iObjectId ?? -1;
@ -1170,6 +1339,10 @@ namespace CodeWalker.World
else if (obj is CutCameraObject cam)
{
}
else if (obj is CutAudioObject aud)
{
InitAudio(aud, gfc, adb);
}
else if (obj is CutPedModelObject ped)
{
InitPed(ped, gfc);
@ -1214,9 +1387,6 @@ namespace CodeWalker.World
else if (obj is CutOverlayObject ovr)
{
}
else if (obj is CutAudioObject aud)
{
}
else if (obj is CutSubtitleObject sub)
{
}
@ -1230,6 +1400,112 @@ namespace CodeWalker.World
{ }
}
private void InitAudio(CutAudioObject aud, GameFileCache gfc, AudioDatabase adb)
{
//how to know the correct name/hash to use?
//sound name in the format: cutscenes_name_mastered_only
var name = aud.cName.ToCleanString().ToLowerInvariant().Replace(".wav", "");
var soundname = "cutscenes_" + name + "_mastered";
var soundname2 = "cutscenes_" + name + "_mastered_only";
uint soundhash = JenkHash.GenHash(soundname);
uint soundhash2 = JenkHash.GenHash(soundname2);
if (adb?.SoundsDB != null)
{
if (adb.SoundsDB.TryGetValue(soundhash, out Dat54Sound snd))
{
SoundInfo = snd;
}
else if (adb.SoundsDB.TryGetValue(soundhash2, out Dat54Sound snd2))
{
SoundInfo = snd2;
}
}
if (SoundInfo is Dat54StreamingSound strsnd)
{
int dur = strsnd.Duration;
MetaHash awchash = 0;
AwcFile awc = null;
var streaminfs = new List<Dat54SimpleSound>();
var streamlist = new List<AwcStream>();
foreach (var chan in strsnd.AudioTracks)
{
if (chan is Dat54SimpleSound chansnd)
{
var chanawchash = chansnd.ContainerName;
if (chanawchash != awchash)
{
awchash = chanawchash;
if (adb.ContainerDB.TryGetValue(awchash, out RpfFileEntry awcentry))
{
awc = new AwcFile();
gfc.RpfMan.LoadFile(awc, awcentry);
}
else
{ }
}
if (awc?.StreamDict != null)
{
var chanhash = chansnd.FileName & 0x1FFFFFFF;
if (awc.StreamDict.TryGetValue(chanhash, out AwcStream chanstream))
{
streaminfs.Add(chansnd);
streamlist.Add(chanstream);
}
else
{ }
}
else
{ }
}
else
{ }
}
var streams = streamlist.ToArray();
SoundPlayer = new AudioPlayer();
SoundPlayer.LoadAudio(streams);
for (int i = 0; i < streaminfs.Count; i++)
{
var streaminf = streaminfs[i];
var left = 1.0f;
var right = 1.0f;
switch (streaminf.Header?.Unk06 ?? 0)
{
case 0://center/default
left = 1.0f;
right = 1.0f;
break;
case 0x133: // 307://left channel
left = 1.0f;
right = 0.0f;
break;
case 0x35: // 53://right channel
left = 0.0f;
right = 1.0f;
break;
default:
break;
}
SoundPlayer.SetOutputMatrix(i, left, right);
}
}
else if (SoundInfo != null)
{ }
if (SoundInfo == null)
{ }
}
private void InitPed(CutPedModelObject ped, GameFileCache gfc)
{