Skip to content

Commit a0c27df

Browse files
committed
Handle ParameterId alternate serialization in HIRC state objects
1 parent 2b3e882 commit a0c27df

File tree

2 files changed

+58
-10
lines changed

2 files changed

+58
-10
lines changed

ME3Tweaks.Wwiser/Model/Hierarchy/Enums/ParameterId.cs

Lines changed: 57 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public ModulatorRtpcParameterId? ModParamId
3030
}
3131
}
3232

33-
public void Serialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
33+
public virtual void Serialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
3434
{
3535
var context = serializationContext.FindAncestor<BankSerializationContext>();
3636
var value = GetSerializableValue(context.Version, context.UseModulator);
@@ -58,7 +58,7 @@ public void Serialize(Stream stream, Endianness endianness, BinarySerializationC
5858
}
5959
}
6060

61-
public void Deserialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
61+
public virtual void Deserialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
6262
{
6363
var context = serializationContext.FindAncestor<BankSerializationContext>();
6464
var res = DeserializeStatic(stream, context.Version, context.UseModulator);
@@ -78,16 +78,35 @@ public bool IsValidOnVersion(uint version)
7878
}
7979
}
8080

81-
public static (RtpcParameterId?, ModulatorRtpcParameterId?) DeserializeStatic(Stream stream, uint version, bool useModulator)
81+
/// <summary>
82+
/// Deserializes a parameter id from a stream based on the version and whether the bank uses modulator parameters
83+
/// </summary>
84+
/// <param name="stream">Stream to read from, length read may be different per version</param>
85+
/// <param name="version">Version of WwiseBank</param>
86+
/// <param name="useModulator">Whether the bank uses modulator parameters</param>
87+
/// <param name="isState">True if parameter being read is from HIRC State object, which uses different serialization</param>
88+
/// <returns>Rtpc or Modulator parameter ID, one will always be null</returns>
89+
/// <exception cref="Exception">Unable to read data length</exception>
90+
/// <exception cref="ArgumentException">No parameter ID mapping is known for given Wwise version</exception>
91+
public static (RtpcParameterId?, ModulatorRtpcParameterId?) DeserializeStatic(Stream stream, uint version, bool useModulator, bool isState = false)
8292
{
8393
byte value;
8494
switch (version)
8595
{
96+
case >= 72 and <= 126 when isState:
97+
value = (byte)stream.ReadByte();
98+
break;
99+
case > 126 when isState:
100+
Span<byte> spanUshort = stackalloc byte[2];
101+
var readUshort = stream.Read(spanUshort);
102+
if (readUshort != 2) throw new Exception();
103+
value = (byte)BitConverter.ToUInt16(spanUshort);
104+
break;
86105
case <= 89:
87-
Span<byte> span = stackalloc byte[4];
88-
var read = stream.Read(span);
89-
if (read != 4) throw new Exception();
90-
value = (byte)BitConverter.ToUInt32(span);
106+
Span<byte> spanUint = stackalloc byte[4];
107+
var readUint = stream.Read(spanUint);
108+
if (readUint != 4) throw new Exception();
109+
value = (byte)BitConverter.ToUInt32(spanUint);
91110
break;
92111
case <= 113:
93112
value = (byte)stream.ReadByte();
@@ -111,8 +130,8 @@ public static (RtpcParameterId?, ModulatorRtpcParameterId?) DeserializeStatic(St
111130
_ => throw new ArgumentException($"No known parameter id mapping for version {version}", nameof(version))
112131
};
113132
}
114-
115-
private byte GetSerializableValue(uint version, bool useModulator)
133+
134+
protected byte GetSerializableValue(uint version, bool useModulator)
116135
{
117136
var paramId = ParamId ?? 0;
118137
return version switch
@@ -326,4 +345,33 @@ public enum ModulatorRtpcParameterId : byte
326345
ModulatorTimeInitialDelay
327346
}
328347
// ReSharper restore InconsistentNaming
348+
}
349+
350+
/// <summary>
351+
/// Slightly different version of ParameterId used for State HIRC objects
352+
/// </summary>
353+
public class StateParameterId : ParameterId
354+
{
355+
public override void Serialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
356+
{
357+
var context = serializationContext.FindAncestor<BankSerializationContext>();
358+
var value = GetSerializableValue(context.Version, false); // TODO: This variant should never use modulator, right?
359+
360+
switch (context.Version)
361+
{
362+
case <= 126:
363+
stream.WriteByte(value);
364+
break;
365+
default:
366+
stream.Write(BitConverter.GetBytes((ushort)value));
367+
break;
368+
}
369+
}
370+
371+
public override void Deserialize(Stream stream, Endianness endianness, BinarySerializationContext serializationContext)
372+
{
373+
var context = serializationContext.FindAncestor<BankSerializationContext>();
374+
var res = DeserializeStatic(stream, context.Version, false, true);
375+
(ParamId, ModParamId) = res;
376+
}
329377
}

ME3Tweaks.Wwiser/Model/Hierarchy/State.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public class PropBundleFloat
6161

6262
[FieldOrder(1)]
6363
[FieldCount($"{nameof(PropCount)}.{nameof(PropCount.Value)}")]
64-
public List<ParameterId> PropIds { get; set; } = new();
64+
public List<StateParameterId> PropIds { get; set; } = new();
6565

6666
[FieldOrder(2)]
6767
[FieldCount($"{nameof(PropCount)}.{nameof(PropCount.Value)}")]

0 commit comments

Comments
 (0)