mirror of
https://mirror.ghproxy.com/https://github.com/dexyfex/CodeWalker
synced 2024-11-26 08:52:52 +08:00
Added stereo playback option in AwcForm
This commit is contained in:
parent
1c9fc78f7f
commit
b3857db929
@ -37,6 +37,9 @@ namespace CodeWalker.GameFiles
|
|||||||
public AwcStream[] Streams { get; set; }
|
public AwcStream[] Streams { get; set; }
|
||||||
public AwcStream MultiChannelSource { get; set; }
|
public AwcStream MultiChannelSource { get; set; }
|
||||||
|
|
||||||
|
public Dictionary<uint, AwcStream> StreamDict { get; set; }
|
||||||
|
|
||||||
|
|
||||||
static public void Decrypt_RSXXTEA(byte[] data, uint[] key)
|
static public void Decrypt_RSXXTEA(byte[] data, uint[] key)
|
||||||
{
|
{
|
||||||
// Rockstar's modified version of XXTEA
|
// Rockstar's modified version of XXTEA
|
||||||
@ -212,6 +215,8 @@ namespace CodeWalker.GameFiles
|
|||||||
Streams = streams.ToArray();
|
Streams = streams.ToArray();
|
||||||
|
|
||||||
MultiChannelSource?.AssignMultiChannelSources(Streams);
|
MultiChannelSource?.AssignMultiChannelSources(Streams);
|
||||||
|
|
||||||
|
BuildStreamDict();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Write(DataWriter w)
|
private void Write(DataWriter w)
|
||||||
@ -343,6 +348,7 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
BuildStreamInfos();
|
BuildStreamInfos();
|
||||||
|
|
||||||
|
BuildStreamDict();
|
||||||
}
|
}
|
||||||
public static void WriteXmlNode(AwcFile f, StringBuilder sb, int indent, string wavfolder, string name = "AudioWaveContainer")
|
public static void WriteXmlNode(AwcFile f, StringBuilder sb, int indent, string wavfolder, string name = "AudioWaveContainer")
|
||||||
{
|
{
|
||||||
@ -461,6 +467,15 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void BuildStreamDict()
|
||||||
|
{
|
||||||
|
StreamDict = new Dictionary<uint, AwcStream>();
|
||||||
|
if (Streams == null) return;
|
||||||
|
foreach (var stream in Streams)
|
||||||
|
{
|
||||||
|
StreamDict[stream.Hash] = stream;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum AwcCodecType
|
public enum AwcCodecType
|
||||||
@ -538,6 +553,7 @@ namespace CodeWalker.GameFiles
|
|||||||
public AwcGranularLoopsChunk GranularLoopsChunk { get; set; }
|
public AwcGranularLoopsChunk GranularLoopsChunk { get; set; }
|
||||||
public AwcStreamFormatChunk StreamFormatChunk { get; set; }
|
public AwcStreamFormatChunk StreamFormatChunk { get; set; }
|
||||||
public AwcSeekTableChunk SeekTableChunk { get; set; }
|
public AwcSeekTableChunk SeekTableChunk { get; set; }
|
||||||
|
public AwcStream[] ChannelStreams { get; set; }
|
||||||
public AwcStream StreamSource { get; set; }
|
public AwcStream StreamSource { get; set; }
|
||||||
public AwcStreamFormat StreamFormat { get; set; }
|
public AwcStreamFormat StreamFormat { get; set; }
|
||||||
public AwcStreamDataBlock[] StreamBlocks { get; set; }
|
public AwcStreamDataBlock[] StreamBlocks { get; set; }
|
||||||
@ -646,6 +662,11 @@ namespace CodeWalker.GameFiles
|
|||||||
{
|
{
|
||||||
if (FormatChunk != null) return (float)FormatChunk.Samples / FormatChunk.SamplesPerSecond;
|
if (FormatChunk != null) return (float)FormatChunk.Samples / FormatChunk.SamplesPerSecond;
|
||||||
if (StreamFormat != null) return (float)StreamFormat.Samples / StreamFormat.SamplesPerSecond;
|
if (StreamFormat != null) return (float)StreamFormat.Samples / StreamFormat.SamplesPerSecond;
|
||||||
|
if ((StreamFormatChunk != null) && (StreamFormatChunk.Channels?.Length > 0))
|
||||||
|
{
|
||||||
|
var chan = StreamFormatChunk.Channels[0];
|
||||||
|
return (float)chan.Samples / chan.SamplesPerSecond;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -965,6 +986,7 @@ namespace CodeWalker.GameFiles
|
|||||||
|
|
||||||
public void AssignMultiChannelSources(AwcStream[] streams)
|
public void AssignMultiChannelSources(AwcStream[] streams)
|
||||||
{
|
{
|
||||||
|
var cstreams = new List<AwcStream>();
|
||||||
for (int i = 0; i < (streams?.Length ?? 0); i++)
|
for (int i = 0; i < (streams?.Length ?? 0); i++)
|
||||||
{
|
{
|
||||||
var stream = streams[i];
|
var stream = streams[i];
|
||||||
@ -990,9 +1012,10 @@ namespace CodeWalker.GameFiles
|
|||||||
stream.StreamSource = this;
|
stream.StreamSource = this;
|
||||||
stream.StreamFormat = (srcind < chancnt) ? StreamFormatChunk.Channels[srcind] : null;
|
stream.StreamFormat = (srcind < chancnt) ? StreamFormatChunk.Channels[srcind] : null;
|
||||||
stream.StreamChannelIndex = srcind;
|
stream.StreamChannelIndex = srcind;
|
||||||
|
cstreams.Add(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
ChannelStreams = cstreams.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CompactMultiChannelSources(AwcStream[] streams)
|
public void CompactMultiChannelSources(AwcStream[] streams)
|
||||||
|
@ -106,8 +106,11 @@ namespace CodeWalker.Forms
|
|||||||
strlist.Sort((a, b) => a.Name.CompareTo(b.Name));
|
strlist.Sort((a, b) => a.Name.CompareTo(b.Name));
|
||||||
foreach (var audio in strlist)
|
foreach (var audio in strlist)
|
||||||
{
|
{
|
||||||
if (audio.StreamBlocks != null) continue;//don't display multichannel source audios
|
var stereo = (audio.ChannelStreams?.Length == 2);
|
||||||
var item = PlayListView.Items.Add(audio.Name);
|
if ((audio.StreamBlocks != null) && (!stereo)) continue;//don't display multichannel source audios
|
||||||
|
var name = audio.Name;
|
||||||
|
if (stereo) name = "(Stereo Playback)";
|
||||||
|
var item = PlayListView.Items.Add(name);
|
||||||
item.SubItems.Add(audio.Type);
|
item.SubItems.Add(audio.Type);
|
||||||
item.SubItems.Add(audio.LengthStr);
|
item.SubItems.Add(audio.LengthStr);
|
||||||
item.SubItems.Add(TextUtil.GetBytesReadable(audio.ByteLength));
|
item.SubItems.Add(TextUtil.GetBytesReadable(audio.ByteLength));
|
||||||
@ -170,11 +173,23 @@ namespace CodeWalker.Forms
|
|||||||
{
|
{
|
||||||
var item = PlayListView.SelectedItems[0];
|
var item = PlayListView.SelectedItems[0];
|
||||||
var audio = item.Tag as AwcStream;
|
var audio = item.Tag as AwcStream;
|
||||||
|
var stereo = (audio?.ChannelStreams?.Length == 2);
|
||||||
if ((audio?.FormatChunk != null) || (audio?.StreamFormat != null))
|
if (stereo)
|
||||||
{
|
{
|
||||||
|
var name0 = audio.ChannelStreams[0].Name;
|
||||||
|
var left0 = name0.EndsWith("left") || name0.EndsWith(".l");
|
||||||
|
var f0 = left0 ? 1.0f : 0.0f;
|
||||||
|
var f1 = left0 ? 0.0f : 1.0f;
|
||||||
|
Player.LoadAudio(audio.ChannelStreams);
|
||||||
Player.SetVolume(VolumeTrackBar.Value / 100.0f);
|
Player.SetVolume(VolumeTrackBar.Value / 100.0f);
|
||||||
|
Player.SetOutputMatrix(0, f0, f1);
|
||||||
|
Player.SetOutputMatrix(1, f1, f0);
|
||||||
|
Player.Play();
|
||||||
|
}
|
||||||
|
else if ((audio?.FormatChunk != null) || (audio?.StreamFormat != null))
|
||||||
|
{
|
||||||
Player.LoadAudio(audio);
|
Player.LoadAudio(audio);
|
||||||
|
Player.SetVolume(VolumeTrackBar.Value / 100.0f);
|
||||||
Player.Play();
|
Player.Play();
|
||||||
}
|
}
|
||||||
else if (audio.MidiChunk != null)
|
else if (audio.MidiChunk != null)
|
||||||
@ -360,6 +375,13 @@ namespace CodeWalker.Forms
|
|||||||
{
|
{
|
||||||
var item = PlayListView.SelectedItems[0];
|
var item = PlayListView.SelectedItems[0];
|
||||||
var audio = item.Tag as AwcStream;
|
var audio = item.Tag as AwcStream;
|
||||||
|
var stereo = (audio?.ChannelStreams?.Length == 2);
|
||||||
|
|
||||||
|
if (stereo)
|
||||||
|
{
|
||||||
|
MessageBox.Show("Sorry, export for stereo output is not currently available.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var ext = ".wav";
|
var ext = ".wav";
|
||||||
if (audio?.MidiChunk != null)
|
if (audio?.MidiChunk != null)
|
||||||
|
@ -16,14 +16,19 @@ namespace CodeWalker.Utils
|
|||||||
|
|
||||||
public class AudioPlayer
|
public class AudioPlayer
|
||||||
{
|
{
|
||||||
|
|
||||||
private AwcStream currentAudio;
|
|
||||||
private Stream wavStream;
|
|
||||||
private SoundStream soundStream;
|
|
||||||
private XAudio2 xAudio2;
|
private XAudio2 xAudio2;
|
||||||
private MasteringVoice masteringVoice;
|
private MasteringVoice masteringVoice;
|
||||||
private AudioBuffer audioBuffer;
|
|
||||||
private SourceVoice sourceVoice;
|
public class AudioVoice
|
||||||
|
{
|
||||||
|
public AwcStream audio;
|
||||||
|
public SoundStream soundStream;
|
||||||
|
public AudioBuffer audioBuffer;
|
||||||
|
public SourceVoice sourceVoice;
|
||||||
|
public float[] outputMatrix = new[] { 1.0f, 1.0f }; //left/right channel output levels
|
||||||
|
public float trackLength;
|
||||||
|
}
|
||||||
|
private AudioVoice[] voices = new AudioVoice[0];
|
||||||
|
|
||||||
public enum PlayerState { Stopped, Playing, Paused };
|
public enum PlayerState { Stopped, Playing, Paused };
|
||||||
public PlayerState State { get; private set; } = PlayerState.Stopped;
|
public PlayerState State { get; private set; } = PlayerState.Stopped;
|
||||||
@ -35,7 +40,6 @@ namespace CodeWalker.Utils
|
|||||||
|
|
||||||
private float volume = 1.0f;
|
private float volume = 1.0f;
|
||||||
|
|
||||||
|
|
||||||
public int PlayTimeMS
|
public int PlayTimeMS
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -52,32 +56,7 @@ namespace CodeWalker.Utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void LoadAudio(AwcStream audio)
|
public void LoadAudio(params AwcStream[] audios)
|
||||||
{
|
|
||||||
if (audio != currentAudio)
|
|
||||||
{
|
|
||||||
CloseStreams();
|
|
||||||
|
|
||||||
currentAudio = audio;
|
|
||||||
trackLength = audio.Length;
|
|
||||||
wavStream = audio.GetWavStream();
|
|
||||||
soundStream = new SoundStream(wavStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CloseStreams()
|
|
||||||
{
|
|
||||||
if (soundStream != null)
|
|
||||||
{
|
|
||||||
soundStream.Close();
|
|
||||||
}
|
|
||||||
if (wavStream != null)
|
|
||||||
{
|
|
||||||
wavStream.Close();//is this necessary?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void InitializeAudio(float playBegin = 0)
|
|
||||||
{
|
{
|
||||||
if (xAudio2 == null)
|
if (xAudio2 == null)
|
||||||
{
|
{
|
||||||
@ -85,17 +64,49 @@ namespace CodeWalker.Utils
|
|||||||
masteringVoice = new MasteringVoice(xAudio2);
|
masteringVoice = new MasteringVoice(xAudio2);
|
||||||
}
|
}
|
||||||
|
|
||||||
wavStream.Position = 0;
|
if ((voices == null) || (voices.Length != audios.Length))
|
||||||
soundStream.Position = 0;
|
|
||||||
audioBuffer = new AudioBuffer
|
|
||||||
{
|
{
|
||||||
Stream = soundStream.ToDataStream(),
|
voices = new AudioVoice[audios.Length];
|
||||||
AudioBytes = (int)soundStream.Length,
|
for (int i = 0; i < audios.Length; i++)
|
||||||
Flags = BufferFlags.EndOfStream
|
{
|
||||||
};
|
voices[i] = new AudioVoice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trackLength = 0;
|
||||||
|
for (int i = 0; i < audios.Length; i++)
|
||||||
|
{
|
||||||
|
var voice = voices[i];
|
||||||
|
var audio = audios[i];
|
||||||
|
if (audio != voice.audio)
|
||||||
|
{
|
||||||
|
voice.audio = audio;
|
||||||
|
voice.trackLength = audio.Length;
|
||||||
|
trackLength = Math.Max(trackLength, voice.trackLength);
|
||||||
|
var wavStream = audio.GetWavStream();
|
||||||
|
var soundStream = new SoundStream(wavStream);
|
||||||
|
voice.soundStream = soundStream;
|
||||||
|
voice.audioBuffer = new AudioBuffer
|
||||||
|
{
|
||||||
|
Stream = soundStream.ToDataStream(),
|
||||||
|
AudioBytes = (int)soundStream.Length,
|
||||||
|
Flags = BufferFlags.EndOfStream
|
||||||
|
};
|
||||||
|
soundStream.Close();
|
||||||
|
wavStream.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CreateSourceVoices(float playBegin = 0)
|
||||||
|
{
|
||||||
if (playBegin > 0)
|
if (playBegin > 0)
|
||||||
{
|
{
|
||||||
audioBuffer.PlayBegin = (int)(soundStream.Format.SampleRate * playBegin) / 128 * 128;
|
foreach (var voice in voices)
|
||||||
|
{
|
||||||
|
voice.audioBuffer.PlayBegin = (int)(voice.soundStream.Format.SampleRate * playBegin) / 128 * 128;
|
||||||
|
}
|
||||||
if (playtimer.IsRunning)
|
if (playtimer.IsRunning)
|
||||||
{
|
{
|
||||||
playtimer.Restart();
|
playtimer.Restart();
|
||||||
@ -112,10 +123,15 @@ namespace CodeWalker.Utils
|
|||||||
}
|
}
|
||||||
|
|
||||||
trackFinished = false;
|
trackFinished = false;
|
||||||
sourceVoice = new SourceVoice(xAudio2, soundStream.Format, true);
|
foreach (var voice in voices)
|
||||||
sourceVoice.SubmitSourceBuffer(audioBuffer, soundStream.DecodedPacketsInfo);
|
{
|
||||||
sourceVoice.BufferEnd += (context) => trackFinished = true;
|
var sourceVoice = new SourceVoice(xAudio2, voice.soundStream.Format, true);
|
||||||
sourceVoice.SetVolume(volume);
|
sourceVoice.SubmitSourceBuffer(voice.audioBuffer, voice.soundStream.DecodedPacketsInfo);
|
||||||
|
sourceVoice.BufferEnd += (context) => trackFinished = true;
|
||||||
|
sourceVoice.SetVolume(volume);
|
||||||
|
sourceVoice.SetOutputMatrix(1, 2, voice.outputMatrix);
|
||||||
|
voice.sourceVoice = sourceVoice;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetPlayerState(PlayerState newState)
|
private void SetPlayerState(PlayerState newState)
|
||||||
@ -148,18 +164,35 @@ namespace CodeWalker.Utils
|
|||||||
volume = v;
|
volume = v;
|
||||||
if (State == PlayerState.Playing)
|
if (State == PlayerState.Playing)
|
||||||
{
|
{
|
||||||
sourceVoice.SetVolume(v);
|
foreach (var voice in voices)
|
||||||
|
{
|
||||||
|
voice.sourceVoice.SetVolume(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetOutputMatrix(int v, float l, float r)
|
||||||
|
{
|
||||||
|
var voice = voices[v];
|
||||||
|
voice.outputMatrix[0] = l;
|
||||||
|
voice.outputMatrix[1] = r;
|
||||||
|
if (State == PlayerState.Playing)
|
||||||
|
{
|
||||||
|
voice.sourceVoice.SetOutputMatrix(1, 2, voice.outputMatrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisposeAudio()
|
public void DisposeAudio()
|
||||||
{
|
{
|
||||||
CloseStreams();
|
|
||||||
if (xAudio2 != null)
|
if (xAudio2 != null)
|
||||||
{
|
{
|
||||||
masteringVoice.Dispose();
|
masteringVoice.Dispose();
|
||||||
xAudio2.Dispose();
|
xAudio2.Dispose();
|
||||||
}
|
}
|
||||||
|
foreach (var voice in voices)
|
||||||
|
{
|
||||||
|
voice?.audioBuffer?.Stream?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -167,9 +200,11 @@ namespace CodeWalker.Utils
|
|||||||
{
|
{
|
||||||
if (State != PlayerState.Stopped)
|
if (State != PlayerState.Stopped)
|
||||||
{
|
{
|
||||||
sourceVoice.DestroyVoice();
|
foreach (var voice in voices)
|
||||||
sourceVoice.Dispose();
|
{
|
||||||
audioBuffer.Stream.Dispose();
|
voice.sourceVoice.DestroyVoice();
|
||||||
|
voice.sourceVoice.Dispose();
|
||||||
|
}
|
||||||
SetPlayerState(PlayerState.Stopped);
|
SetPlayerState(PlayerState.Stopped);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,8 +212,11 @@ namespace CodeWalker.Utils
|
|||||||
public void Play(float playBegin = 0)
|
public void Play(float playBegin = 0)
|
||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
InitializeAudio(playBegin);
|
CreateSourceVoices(playBegin);
|
||||||
sourceVoice.Start();
|
foreach (var voice in voices)
|
||||||
|
{
|
||||||
|
voice.sourceVoice.Start();
|
||||||
|
}
|
||||||
SetPlayerState(PlayerState.Playing);
|
SetPlayerState(PlayerState.Playing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +230,7 @@ namespace CodeWalker.Utils
|
|||||||
{
|
{
|
||||||
var state = State;
|
var state = State;
|
||||||
Stop();
|
Stop();
|
||||||
InitializeAudio(playBegin);
|
CreateSourceVoices(playBegin);
|
||||||
State = state;
|
State = state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,7 +239,10 @@ namespace CodeWalker.Utils
|
|||||||
{
|
{
|
||||||
if (State == PlayerState.Playing)
|
if (State == PlayerState.Playing)
|
||||||
{
|
{
|
||||||
sourceVoice.Stop();
|
foreach (var voice in voices)
|
||||||
|
{
|
||||||
|
voice.sourceVoice.Stop();
|
||||||
|
}
|
||||||
SetPlayerState(PlayerState.Paused);
|
SetPlayerState(PlayerState.Paused);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,14 +251,142 @@ namespace CodeWalker.Utils
|
|||||||
{
|
{
|
||||||
if (State == PlayerState.Paused)
|
if (State == PlayerState.Paused)
|
||||||
{
|
{
|
||||||
sourceVoice.Start();
|
foreach (var voice in voices)
|
||||||
|
{
|
||||||
|
voice.sourceVoice.Start();
|
||||||
|
}
|
||||||
SetPlayerState(PlayerState.Playing);
|
SetPlayerState(PlayerState.Playing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class AudioDatabase
|
||||||
|
{
|
||||||
|
|
||||||
|
public bool IsInited { get; set; }
|
||||||
|
|
||||||
|
public Dictionary<uint, Dat54Sound> SoundsDB { get; set; }
|
||||||
|
public Dictionary<uint, Dat151RelData> GameDB { get; set; }
|
||||||
|
public Dictionary<uint, RpfFileEntry> ContainerDB { get; set; }
|
||||||
|
|
||||||
|
public void Init(GameFileCache gameFileCache, bool sounds = true, bool game = true)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
var rpfman = gameFileCache.RpfMan;
|
||||||
|
|
||||||
|
var datrelentries = new Dictionary<uint, RpfFileEntry>();
|
||||||
|
var awcentries = new Dictionary<uint, RpfFileEntry>();
|
||||||
|
void addRpfDatRels(RpfFile rpffile)
|
||||||
|
{
|
||||||
|
if (rpffile.AllEntries == null) return;
|
||||||
|
foreach (var entry in rpffile.AllEntries)
|
||||||
|
{
|
||||||
|
if (entry is RpfFileEntry)
|
||||||
|
{
|
||||||
|
var fentry = entry as RpfFileEntry;
|
||||||
|
//if (entry.NameLower.EndsWith(".rel"))
|
||||||
|
//{
|
||||||
|
// datrels[entry.NameHash] = fentry;
|
||||||
|
//}
|
||||||
|
if (sounds && entry.NameLower.EndsWith(".dat54.rel"))
|
||||||
|
{
|
||||||
|
datrelentries[entry.NameHash] = fentry;
|
||||||
|
}
|
||||||
|
if (game && entry.NameLower.EndsWith(".dat151.rel"))
|
||||||
|
{
|
||||||
|
datrelentries[entry.NameHash] = fentry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void addRpfAwcs(RpfFile rpffile)
|
||||||
|
{
|
||||||
|
if (rpffile.AllEntries == null) return;
|
||||||
|
foreach (var entry in rpffile.AllEntries)
|
||||||
|
{
|
||||||
|
if (entry is RpfFileEntry)
|
||||||
|
{
|
||||||
|
var fentry = entry as RpfFileEntry;
|
||||||
|
if (entry.NameLower.EndsWith(".awc"))
|
||||||
|
{
|
||||||
|
var shortname = entry.GetShortNameLower();
|
||||||
|
var parentname = entry.Parent?.GetShortNameLower() ?? "";
|
||||||
|
if (string.IsNullOrEmpty(parentname) && (entry.Parent?.File != null))
|
||||||
|
{
|
||||||
|
parentname = entry.Parent.File.NameLower;
|
||||||
|
int ind = parentname.LastIndexOf('.');
|
||||||
|
if (ind > 0)
|
||||||
|
{
|
||||||
|
parentname = parentname.Substring(0, ind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var contname = parentname + "/" + shortname;
|
||||||
|
var hash = JenkHash.GenHash(contname);
|
||||||
|
awcentries[hash] = fentry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var audrpf = rpfman.FindRpfFile("x64\\audio\\audio_rel.rpf");
|
||||||
|
if (audrpf != null)
|
||||||
|
{
|
||||||
|
addRpfDatRels(audrpf);
|
||||||
|
}
|
||||||
|
foreach (var baserpf in gameFileCache.BaseRpfs)
|
||||||
|
{
|
||||||
|
addRpfAwcs(baserpf);
|
||||||
|
}
|
||||||
|
if (gameFileCache.EnableDlc)
|
||||||
|
{
|
||||||
|
var updrpf = rpfman.FindRpfFile("update\\update.rpf");
|
||||||
|
if (updrpf != null)
|
||||||
|
{
|
||||||
|
addRpfDatRels(updrpf);
|
||||||
|
}
|
||||||
|
foreach (var dlcrpf in gameFileCache.DlcActiveRpfs) //load from current dlc rpfs
|
||||||
|
{
|
||||||
|
addRpfDatRels(dlcrpf);
|
||||||
|
addRpfAwcs(dlcrpf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var soundsdb = new Dictionary<uint, Dat54Sound>();
|
||||||
|
var gamedb = new Dictionary<uint, Dat151RelData>();
|
||||||
|
foreach (var datentry in datrelentries.Values)
|
||||||
|
{
|
||||||
|
var relfile = rpfman.GetFile<RelFile>(datentry);
|
||||||
|
if (relfile?.RelDatas != null)
|
||||||
|
{
|
||||||
|
foreach (var rd in relfile.RelDatas)
|
||||||
|
{
|
||||||
|
if (rd is Dat54Sound sd)
|
||||||
|
{
|
||||||
|
soundsdb[sd.NameHash] = sd;
|
||||||
|
}
|
||||||
|
else if (rd is Dat151RelData gd)
|
||||||
|
{
|
||||||
|
gamedb[gd.NameHash] = gd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ContainerDB = awcentries;
|
||||||
|
if (sounds) SoundsDB = soundsdb;
|
||||||
|
if (game) GameDB = gamedb;
|
||||||
|
|
||||||
|
IsInited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user