ace/Source/ACE.DatLoader/BinaryReaderExtensions.cs
Mag-nus a24f7cbb17
ACE.DatLoader more IUnpackable refactoring (#616)
* ACE.DatLoader.Tests fix for Animation.

Also includes some ACE.Entity.Position replacements with ACE.DatLoader.Entity.Frame

* ACE.DatLoader Scene converted

Also made all the ReadFromDat code more generic/copyable

* ACE.DatLoader Palette converted

* ACE.DatLoader: PaletteSet converted

* ACE.DatLoader: CombatManeuverTable converted

* ACE.DatLoader PhysicsScriptTable converted

* ACE.DatLoader SpellComponentTable converted

* ACE.DatLoader misc cleanups

* ACE.DatLoader Surface converted

* ACE.DatLoader much more progress

* ACE.DatLoader/Tests Added cell.dat testing framework. First done EnvCell

* ACE.DatLoader ParticileEmitter converted. PositionExtensions removed (via conversion to Position/Frame/Vector3/Quaternion)

* ACE.DatLoader: ClothingTable converted and fixed

* ACE.DatLoader GeneratorTable converted

* ACE.DatLoader: GfxObjDegradeInfo converted

* ACE.DatLoader: MotionTable converted

* Merge conflicts

* Merge Conflicts

* More merge conflicts

* More conflicts resolved
2018-02-04 11:16:30 -06:00

99 lines
3.3 KiB
C#

using System.IO;
using System.Numerics;
namespace ACE.DatLoader
{
static class BinaryReaderExtensions
{
/// <summary>
/// Aligns the stream to the next DWORD boundary.
/// </summary>
public static void AlignBoundary(this BinaryReader reader)
{
// Aligns the DatReader to the next DWORD boundary.
long alignDelta = reader.BaseStream.Position % 4;
if (alignDelta != 0)
reader.BaseStream.Position += (int)(4 - alignDelta);
}
/// <summary>
/// A Compressed UInt32 can be 1, 2, or 4 bytes.<para />
/// If the first MSB (0x80) is 0, it is one byte.<para />
/// If the first MSB (0x80) is set and the second MSB (0x40) is 0, it's 2 bytes.<para />
/// If both (0x80) and (0x40) are set, it's 4 bytes.
/// </summary>
public static uint ReadCompressedUInt32(this BinaryReader reader)
{
var b0 = reader.ReadByte();
if ((b0 & 0x80) == 0)
return b0;
var b1 = reader.ReadByte();
if ((b0 & 0x40) == 0)
return (uint)(((b0 & 0x7F) << 8) | b1);
var s = reader.ReadUInt16();
return (uint)(((((b0 & 0x3F) << 8) | b1) << 16) | s);
}
/// <summary>
/// First reads a UInt16. If the MSB is set, it will be masked with 0x3FFF, shifted left 2 bytes, and then OR'd with the next UInt16. The sum is then added to knownType.
/// </summary>
public static uint ReadAsDataIDOfKnownType(this BinaryReader reader, uint knownType)
{
var value = reader.ReadUInt16();
if ((value & 0x8000) != 0)
{
var lower = reader.ReadUInt16();
var higher = (value & 0x3FFF) << 16;
return (uint)(knownType + (higher | lower));
}
return (knownType + value);
}
/// <summary>
/// Returns a string as defined by the first 2-byte's length
/// </summary>
public static string ReadPString(this BinaryReader reader)
{
int stringlength = reader.ReadUInt16();
byte[] thestring = reader.ReadBytes(stringlength);
return System.Text.Encoding.Default.GetString(thestring);
}
/// <summary>
/// Returns a string as defined by the first byte's length and removes the obfuscation (upper/lower nibbles swapped)
/// </summary>
public static string ReadObfuscatedString(this BinaryReader reader)
{
int stringlength = reader.ReadUInt16();
byte[] thestring = reader.ReadBytes(stringlength);
for (var i = 0; i < stringlength; i++)
// flip the bytes in the string to undo the obfuscation: i.e. 0xAB => 0xBA
thestring[i] = (byte)((thestring[i] >> 4) | (thestring[i] << 4));
return System.Text.Encoding.Default.GetString(thestring);
}
/// <summary>
/// Returns a Vector3 object read out as 3 floats, x y z
/// </summary>
public static Vector3 ReadVector3(this BinaryReader reader)
{
var x = reader.ReadSingle();
var y = reader.ReadSingle();
var z = reader.ReadSingle();
return new Vector3(x, y, z);
}
}
}