Skip to content

Commit

Permalink
Parse SwitchContainer
Browse files Browse the repository at this point in the history
  • Loading branch information
henbagle committed Dec 30, 2023
1 parent fe24a6a commit 3d881f4
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 5 deletions.
14 changes: 12 additions & 2 deletions ME3Tweaks.Wwiser.Tests/HierarchyTests/SwitchContainerTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
namespace ME3Tweaks.Wwiser.Tests.HierarchyTests;
using ME3Tweaks.Wwiser.Model.Hierarchy;

namespace ME3Tweaks.Wwiser.Tests.HierarchyTests;

public class SwitchContainerTests
{

[TestCase("SwitchContainer_V56.bin", 56)]
public void SwitchContainer_Reserializes(string filename, int version)
{
var data = TestData.GetTestDataBytes(@"Hierarchy",@"SwitchContainer", filename);
var (_, result) = TestHelpers.Deserialize<SwitchContainer>(data, version);

var reserialized = TestHelpers.Serialize(result, version);
Assert.That(reserialized, Is.EquivalentTo(data));
}
}
Binary file not shown.
43 changes: 43 additions & 0 deletions ME3Tweaks.Wwiser/Model/Hierarchy/Enums/GroupType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using BinarySerialization;

namespace ME3Tweaks.Wwiser.Model.Hierarchy.Enums;

public class GroupType : IBinarySerializable
{
public GroupTypeInner Value { get; set; }

public void Serialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;
if (version <= 89)
{
stream.Write(BitConverter.GetBytes((uint)Value));
}
else
{
stream.WriteByte((byte)Value);
}
}

public void Deserialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;
if (version <= 89)
{
Span<byte> span = stackalloc byte[4];
var read = stream.Read(span);
if (read != 4) throw new Exception();
Value = (GroupTypeInner)BitConverter.ToUInt32(span);
}
else
{
Value = (GroupTypeInner)stream.ReadByte();
}
}

public enum GroupTypeInner : uint
{
Switch,
State
}
}
7 changes: 7 additions & 0 deletions ME3Tweaks.Wwiser/Model/Hierarchy/Enums/OnSwitchMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace ME3Tweaks.Wwiser.Model.Hierarchy.Enums;

public enum OnSwitchMode : uint
{
PlayToEnd,
Stop
}
2 changes: 1 addition & 1 deletion ME3Tweaks.Wwiser/Model/Hierarchy/HircItemContainer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ public class HircItemContainer

[FieldOrder(3)]
[FieldLength(nameof(Size))]
[SubtypeFactory($"{nameof(Type)}.{nameof(Type.Value)}", typeof(HircTypeFactory))]
[SubtypeFactory($"{nameof(Type)}.{nameof(Type.Value)}", typeof(HircItemSubtypeFactory))]
public required HircItem Item { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

namespace ME3Tweaks.Wwiser.Model.Hierarchy;

public class HircTypeFactory : ISubtypeFactory
public class HircItemSubtypeFactory : ISubtypeFactory
{
private static readonly Dictionary<Type, HircType> TypeToEnum = new()
{
{ typeof(Sound), HircType.Sound },
{ typeof(Action), HircType.Action },
{ typeof(Event), HircType.Event },
{ typeof(RandSeqContainer), HircType.RandomSequenceContainer },
{ typeof(SwitchContainer), HircType.SwitchContainer },
{ typeof(ActorMixer), HircType.ActorMixer },
{ typeof(LayerContainer), HircType.LayerContainer },
{ typeof(Attenuation), HircType.Attenuation },
Expand Down Expand Up @@ -46,7 +47,7 @@ public bool TryGetType(object key, [UnscopedRef] out Type type)
HircType.Action => typeof(Action),
HircType.Event => typeof(Event),
HircType.RandomSequenceContainer => typeof(RandSeqContainer),
//HircType.SwitchContainer =>
HircType.SwitchContainer => typeof(SwitchContainer),
HircType.ActorMixer => typeof(ActorMixer),
//HircType.Bus =>
HircType.LayerContainer => typeof(LayerContainer),
Expand Down
135 changes: 135 additions & 0 deletions ME3Tweaks.Wwiser/Model/Hierarchy/SwitchContainer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
using BinarySerialization;
using ME3Tweaks.Wwiser.Model.Hierarchy.Enums;
using ME3Tweaks.Wwiser.Model.ParameterNode;

namespace ME3Tweaks.Wwiser.Model.Hierarchy;

public class SwitchContainer : HircItem, IHasNode
{
[FieldOrder(0)]
public NodeBaseParameters NodeBaseParameters { get; set; } = new();

[FieldOrder(1)]
public GroupType GroupType { get; set; } = new();

[FieldOrder(2)]
public uint GroupId { get; set; }

[FieldOrder(3)]
public uint DefaultSwitchId { get; set; }

[FieldOrder(4)]
[SerializeAs(SerializedType.UInt1)]
public bool IsContinuousValidation { get; set; }

[FieldOrder(5)]
public Children Children { get; set; } = new();

[FieldOrder(6)]
public uint SwitchGroupCount { get; set; }

[FieldOrder(7)]
[FieldCount(nameof(SwitchGroupCount))]
public List<SwitchGroup> SwitchGroups { get; set; } = new();

[FieldOrder(8)]
public uint SwitchParamsCount { get; set; }

[FieldOrder(9)]
[FieldCount(nameof(SwitchParamsCount))]
public List<SwitchParams> SwitchParams { get; set; } = new();
}

public class SwitchParams : IAkIdentifiable, IBinarySerializable
{
[Ignore]
public uint Id { get; set; }

[Ignore]
public bool IsFirstOnly { get; set; }

[Ignore]
public bool ContinuePlayback { get; set; }

[Ignore]
public OnSwitchMode OnSwitchMode { get; set; }

[Ignore]
public float FadeInTime { get; set; }

[Ignore]
public float FadeOutTime { get; set; }

public void Serialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;

stream.Write(BitConverter.GetBytes(Id));

if (version <= 89)
{
stream.WriteBoolByte(IsFirstOnly);
stream.WriteBoolByte(ContinuePlayback);
stream.Write(BitConverter.GetBytes((uint)OnSwitchMode));
}
else
{
byte bitVector = 0;
if (IsFirstOnly) bitVector |= 1 << 0;
if (ContinuePlayback) bitVector |= 1 << 1;
stream.WriteByte(bitVector);

stream.WriteByte((byte)OnSwitchMode);
}

stream.Write(BitConverter.GetBytes(FadeInTime));
stream.Write(BitConverter.GetBytes(FadeOutTime));
}

public void Deserialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
{
var version = serializationContext.FindAncestor<BankSerializationContext>().Version;

Span<byte> span = stackalloc byte[4];
var read = stream.Read(span);
if (read != 4) throw new Exception();
Id = BitConverter.ToUInt32(span);

if (version <= 89)
{
IsFirstOnly = stream.ReadBoolByte();
ContinuePlayback = stream.ReadBoolByte();

read = stream.Read(span);
if (read != 4) throw new Exception();
OnSwitchMode = (OnSwitchMode)BitConverter.ToUInt32(span);
}
else
{
var bitVector = stream.ReadByte();
IsFirstOnly = (bitVector & (1 << 0)) == 1 << 0;
ContinuePlayback = (bitVector & (1 << 1)) == 1 << 1;

OnSwitchMode = (OnSwitchMode)((byte)stream.ReadByte() & 0x7);
}


read = stream.Read(span);
if (read != 4) throw new Exception();
FadeInTime = BitConverter.ToSingle(span);

read = stream.Read(span);
if (read != 4) throw new Exception();
FadeOutTime = BitConverter.ToSingle(span);
}
}

public class SwitchGroup : AkIdentifiable
{
[FieldOrder(0)]
public uint ItemCount { get; set; }

[FieldOrder(1)]
[FieldCount(nameof(ItemCount))]
public List<uint> ItemIds { get; set; } = new();
}

0 comments on commit 3d881f4

Please sign in to comment.