Skip to content

Commit

Permalink
Merge pull request #121 from Gothic-UnZENity-Project/feature/32-lock-…
Browse files Browse the repository at this point in the history
…picking

Feature/32 lock picking - v1
  • Loading branch information
JaXt0r authored Sep 29, 2024
2 parents a1c14b7 + 52a8baa commit a1318c5
Show file tree
Hide file tree
Showing 46 changed files with 2,815 additions and 232 deletions.
90 changes: 47 additions & 43 deletions Assets/UnZENity-Core/Scripts/Creator/Sounds/SoundCreator.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.IO;
using System.Text;
using GUZ.Core.Caches;
using GUZ.Core.Data;
using JetBrains.Annotations;
using UnityEngine;

namespace GUZ.Core.Creator.Sounds
Expand All @@ -18,6 +20,7 @@ private enum BitDepth
/// Create AudioClip from a file inside .vdf containers.
/// Usage: ToAudioClip("fileName"):
/// </summary>
[CanBeNull]
public static AudioClip ToAudioClip(string fileName)
{
fileName = Path.GetFileNameWithoutExtension(fileName);
Expand All @@ -27,75 +30,76 @@ public static AudioClip ToAudioClip(string fileName)
return cachedClip;
}

SoundData soundData = ResourceLoader.TryGetSound(fileName);
AudioClip audioClip;

try
{
audioClip = AudioClip.Create(fileName, soundData.Sound.Length / soundData.Channels, soundData.Channels, soundData.SampleRate, false);
audioClip.SetData(soundData.Sound, 0);
}
catch (Exception e)
var soundData = ResourceLoader.TryGetSound(fileName);
if (soundData == null)
{
Debug.LogError(e);
audioClip = AudioClip.Create(fileName, 1, 1, 44100, false);
audioClip.SetData(new float[] { 0 }, 0); // almost empty audio
return null;
}

var audioClip = AudioClip.Create(fileName, soundData.Sound.Length / soundData.Channels, soundData.Channels,
soundData.SampleRate, false);
audioClip.SetData(soundData.Sound, 0);

MultiTypeCache.AudioClips.Add(fileName, audioClip);
return audioClip;
}

public static SoundData ConvertWavByteArrayToFloatArray(byte[] fileBytes)
{
//var riff = Encoding.ASCII.GetString(fileBytes, 0, 4);
//var wave = Encoding.ASCII.GetString(fileBytes, 8, 4);
var subchunk1 = BitConverter.ToInt32(fileBytes, 16);
var audioFormat = BitConverter.ToUInt16(fileBytes, 20);

var formatCode = FormatCode(audioFormat);

var channels = BitConverter.ToUInt16(fileBytes, 22);
var sampleRate = BitConverter.ToInt32(fileBytes, 24);
//var byteRate = BitConverter.ToInt32(fileBytes, 28);
//var blockAlign = BitConverter.ToUInt16(fileBytes, 32);
var bitDepth = BitConverter.ToUInt16(fileBytes, 34);

// Calculate header offset and data size
var headerOffset = 20 + subchunk1;
var dataSizeOffset = headerOffset + 4;
if (dataSizeOffset + 4 > fileBytes.Length)
// HINT: Commented out elements are there for reference only.

// string riffHeader = Encoding.ASCII.GetString(fileBytes, 0, 4);
// int fileSize = BitConverter.ToInt32(fileBytes, 4);
// string waveHeader = Encoding.ASCII.GetString(fileBytes, 8, 4);
// string fmtHeader = Encoding.ASCII.GetString(fileBytes, 12, 4);
// int fmtLength = BitConverter.ToInt32(fileBytes, 16);

ushort formatType = BitConverter.ToUInt16(fileBytes, 20);
string formatCode = FormatCode(formatType);
ushort numChannels = BitConverter.ToUInt16(fileBytes, 22);
int sampleRate = BitConverter.ToInt32(fileBytes, 24);

// int byteRate = BitConverter.ToInt32(fileBytes, 28);
// short blockAlign = BitConverter.ToInt16(fileBytes, 32);

short bitsPerSample = BitConverter.ToInt16(fileBytes, 34);
string dataHeader = Encoding.ASCII.GetString(fileBytes, 36, 4);

// Check for "PAD" header and skip it if present
int padSize = 0;
while (dataHeader == "PAD ")
{
throw new ArgumentException("Invalid WAV file structure.");
padSize += BitConverter.ToInt32(fileBytes, 40);

// we add 8 bits to padding as to skip the pad subchunk header + data
padSize += 8;

// Skip the PAD section
dataHeader = Encoding.ASCII.GetString(fileBytes, 36 + padSize, 4);
}

var subchunk2 = BitConverter.ToInt32(fileBytes, dataSizeOffset);

// Ensure that subchunk2 does not exceed fileBytes length
var dataAvailable = fileBytes.Length - (dataSizeOffset + 4);
if (subchunk2 > dataAvailable)
{
subchunk2 = dataAvailable;
}
int dataSize = BitConverter.ToInt32(fileBytes, 40 + padSize);

if (formatCode == "IMA ADPCM")
{
return ConvertWavByteArrayToFloatArray(ImaadpcmDecoder.Decode(fileBytes));
}

// sometimes a file has more data than is specified after the RIFF header
long stopPosition = Math.Min(dataSize, (fileBytes.Length - 44));

// Copy WAV data section into a new array
var data = new byte[subchunk2];
Array.Copy(fileBytes, dataSizeOffset + 4, data, 0, subchunk2);
var audioData = new byte[stopPosition];
Array.Copy(fileBytes, 44+padSize, audioData, 0, stopPosition);

return new SoundData
{
Sound = ConvertByteArrayToFloatArray(data, 0, (BitDepth)bitDepth),
Channels = channels,
Sound = ConvertByteArrayToFloatArray(audioData, 0, (BitDepth)bitsPerSample),
Channels = numChannels,
SampleRate = sampleRate
};
}


private static float[] ConvertByteArrayToFloatArray(byte[] source, int headerOffset, BitDepth bit)
{
switch (bit)
Expand Down
16 changes: 16 additions & 0 deletions Assets/UnZENity-Core/Scripts/Globals/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,25 @@
using System;
using UnityEngine;

namespace GUZ.Core.Globals
{
public static class Constants
{
public static class GothicIni
{
public static bool PlayLogoVideos => GameGlobals.Settings.GothicIniSettings.TryGetValue("playLogoVideos", out var value) ? Convert.ToBoolean(Convert.ToInt16(value)) : true;
}

public static class Daedalus
{
public static string DoorLockSoundName => "DOOR_LOCK.WAV";
public static string PickLockFailureSoundName => GameData.GothicVm.GetSymbolByName("_STR_SOUND_PICKLOCK_FAILURE").GetString(0);
public static string PickLockBrokenSoundName => GameData.GothicVm.GetSymbolByName("_STR_SOUND_PICKLOCK_BROKEN").GetString(0);
public static string PickLockSuccessSoundName => GameData.GothicVm.GetSymbolByName("_STR_SOUND_PICKLOCK_SUCCESS").GetString(0);
public static string PickLockUnlockSoundName => GameData.GothicVm.GetSymbolByName("_STR_SOUND_PICKLOCK_UNLOCK").GetString(0);
public static string DoorUnlockSoundName => "DOOR_UNLOCK.WAV"; // _STR_*_UNLOCK value above couldn't be found/isn't used in G1, therefore we use this as fallback.
}

public static readonly Material LoadingMaterial; // Used for Vobs and World before applying TextureArray.

// Unity shaders
Expand Down
8 changes: 6 additions & 2 deletions Assets/UnZENity-Core/Scripts/PrefabType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ public enum PrefabType
Vob,
Npc,
VobAnimate,
VobItem,
VobContainer,
VobDoor,
VobFire,
Expand All @@ -24,6 +23,9 @@ public enum PrefabType
VobSoundDaytime,
VobLadder,

VobItem,
VobItemLockPick,

Player,
MainMenu,
XRDeviceSimulator,
Expand All @@ -40,7 +42,6 @@ public static string Path(this PrefabType type)
PrefabType.Vob => "Prefabs/Vobs/Vob",
PrefabType.Npc => "Prefabs/Vobs/oCNpc",
PrefabType.VobAnimate => "Prefabs/Vobs/zCVobAnimate",
PrefabType.VobItem => "Prefabs/Vobs/oCItem",
PrefabType.VobContainer => "Prefabs/Vobs/oCMobContainer",
PrefabType.VobDoor => "Prefabs/Vobs/oCMobDoor",
PrefabType.VobFire => "Prefabs/Vobs/oCMobFire",
Expand All @@ -56,6 +57,9 @@ public static string Path(this PrefabType type)
PrefabType.VobSoundDaytime => "Prefabs/Vobs/zCVobSoundDaytime",
PrefabType.VobLadder => "Prefabs/Vobs/oCMobLadder",

PrefabType.VobItem => "Prefabs/Vobs/oCItem",
PrefabType.VobItemLockPick => "Prefabs/Vobs/oCItem/LockPick",

PrefabType.Player => "Prefabs/Player",
PrefabType.MainMenu => "Prefabs/Menus/MainMenu",
PrefabType.XRDeviceSimulator => "Prefabs/VRPlayer/XR Device Simulator",
Expand Down
Loading

0 comments on commit a1318c5

Please sign in to comment.