Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shadow of the Erdtree Compatibility #931

Merged
merged 6 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
85 changes: 84 additions & 1 deletion src/Andre/SoulsFormats/SoulsFormats/Formats/DCX.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ internal static Memory<byte> Decompress(BinaryReaderEx br, out Type type)
{
type = Type.DCP_EDGE;
}
else if (format == "ZSTD")
{
type = Type.ZSTD;
}
}
else if (magic == "DCX\0")
{
Expand Down Expand Up @@ -125,6 +129,10 @@ internal static Memory<byte> Decompress(BinaryReaderEx br, out Type type)
int compressionLevel = br.GetByte(0x30);
type = compressionLevel == 9 ? Type.DCX_KRAK_MAX : Type.DCX_KRAK;
}
else if (format == "ZSTD")
{
type = Type.ZSTD;
}
}
else
{
Expand Down Expand Up @@ -155,10 +163,50 @@ internal static Memory<byte> Decompress(BinaryReaderEx br, out Type type)
return DecompressDCXKRAK(br);
else if (type == Type.DCX_KRAK_MAX)
return DecompressDCXKRAK(br, 9);
else if (type == Type.ZSTD)
return DecompressDCXZSTD(br);
else
throw new FormatException("Unknown DCX format.");
}


private static byte[] DecompressDCXZSTD(BinaryReaderEx br)
{
br.AssertASCII("DCX\0");
br.AssertInt32(0x11000);
br.AssertInt32(0x18);
br.AssertInt32(0x24);
br.AssertInt32(0x44);
br.AssertInt32(0x4C);

br.AssertASCII("DCS\0");
int uncompressedSize = br.ReadInt32();
int compressedSize = br.ReadInt32();

br.AssertASCII("DCP\0");
br.AssertASCII("ZSTD");
br.AssertInt32(0x20);
br.AssertByte(0x15);
br.AssertByte(0);
br.AssertByte(0);
br.AssertByte(0);
br.AssertInt32(0x0);
br.AssertByte(0);
br.AssertByte(0);
br.AssertByte(0);
br.AssertByte(0);
br.AssertInt32(0x0);
br.AssertInt32(0x010100);

br.AssertASCII("DCA\0");
br.AssertInt32(8);

byte[] decompressed = SFUtil.ReadZstd(br, compressedSize);

return decompressed;
}


private static byte[] DecompressDCPDFLT(BinaryReaderEx br)
{
br.AssertASCII("DCP\0");
Expand Down Expand Up @@ -427,12 +475,42 @@ internal static void Compress(Span<byte> data, BinaryWriterEx bw, Type type)
CompressDCXKRAK(data, bw);
else if (type == Type.DCX_KRAK_MAX)
CompressDCXKRAK(data, bw, 9);
else if (type == Type.ZSTD)
{
// Temporary until proper ZSTD re-compression settings are discovered
CompressDCPDFLT(data, bw);
}
else if (type == Type.Unknown)
throw new ArgumentException("You cannot compress a DCX with an unknown type.");
else
throw new NotImplementedException("Compression for the given type is not implemented.");
}

private static void CompressDCXZSTD(Span<byte> data, BinaryWriterEx bw)
{
// TODO: just a stub for future implementation
/*
bw.WriteASCII("DCX\0");
bw.WriteASCII("ZSTD");
bw.WriteInt32(0x20);
bw.WriteInt32(0x9000000);
bw.WriteInt32(0);
bw.WriteInt32(0);
bw.WriteInt32(0);
bw.WriteInt32(0x00010100);

bw.WriteASCII("DCS\0");
bw.WriteInt32(data.Length);
bw.ReserveInt32("CompressedSize");

int compressedSize = SFUtil.WriteZstd(bw, 3, data);
bw.FillInt32("CompressedSize", compressedSize);

bw.WriteASCII("DCA\0");
bw.WriteInt32(8);
*/
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still hopeful we'll figure this out, though it seems more and more likely we'll need to inject some hardcore ghidra user like chain with a few shots of caffeine

private static void CompressDCPDFLT(Span<byte> data, BinaryWriterEx bw)
{
bw.WriteASCII("DCP\0");
Expand Down Expand Up @@ -711,7 +789,12 @@ public enum Type
/// <summary>
/// DCX header, different Oodle compression. Used in Armored Core VI.
/// </summary>
DCX_KRAK_MAX
DCX_KRAK_MAX,

/// <summary>
/// header, deflate compression. Used in SOTE Elden Ring regulation.bin
/// </summary>
ZSTD
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1422,7 +1422,7 @@
/// <summary>
/// Unknown.
/// </summary>
public UnkStruct50 UnkStruct50 { get; set; }

Check warning on line 1425 in src/Andre/SoulsFormats/SoulsFormats/Formats/MSB/MSB-AC6/PartParam.cs

View workflow job for this annotation

GitHub Actions / Build

'MSB_AC6.Part.MapPiece.UnkStruct50' hides inherited member 'MSB_AC6.Part.UnkStruct50'. Use the new keyword if hiding was intended.

/// <summary>
/// Unknown.
Expand All @@ -1437,22 +1437,22 @@
/// <summary>
/// Unknown.
/// </summary>
public UnkStruct88 UnkStruct88 { get; set; }

Check warning on line 1440 in src/Andre/SoulsFormats/SoulsFormats/Formats/MSB/MSB-AC6/PartParam.cs

View workflow job for this annotation

GitHub Actions / Build

'MSB_AC6.Part.MapPiece.UnkStruct88' hides inherited member 'MSB_AC6.Part.UnkStruct88'. Use the new keyword if hiding was intended.

/// <summary>
/// Unknown.
/// </summary>
public UnkStruct90 UnkStruct90 { get; set; }

Check warning on line 1445 in src/Andre/SoulsFormats/SoulsFormats/Formats/MSB/MSB-AC6/PartParam.cs

View workflow job for this annotation

GitHub Actions / Build

'MSB_AC6.Part.MapPiece.UnkStruct90' hides inherited member 'MSB_AC6.Part.UnkStruct90'. Use the new keyword if hiding was intended.

/// <summary>
/// Unknown.
/// </summary>
public UnkStruct98 UnkStruct98 { get; set; }

Check warning on line 1450 in src/Andre/SoulsFormats/SoulsFormats/Formats/MSB/MSB-AC6/PartParam.cs

View workflow job for this annotation

GitHub Actions / Build

'MSB_AC6.Part.MapPiece.UnkStruct98' hides inherited member 'MSB_AC6.Part.UnkStruct98'. Use the new keyword if hiding was intended.

/// <summary>
/// Unknown.
/// </summary>
public UnkStructA0 UnkStructA0 { get; set; }

Check warning on line 1455 in src/Andre/SoulsFormats/SoulsFormats/Formats/MSB/MSB-AC6/PartParam.cs

View workflow job for this annotation

GitHub Actions / Build

'MSB_AC6.Part.MapPiece.UnkStructA0' hides inherited member 'MSB_AC6.Part.UnkStructA0'. Use the new keyword if hiding was intended.

/// <summary>
/// Creates a MapPiece with default values.
Expand Down Expand Up @@ -1529,7 +1529,7 @@
/// <summary>
/// Unknown.
/// </summary>
public UnkStruct50 UnkStruct50 { get; set; }

Check warning on line 1532 in src/Andre/SoulsFormats/SoulsFormats/Formats/MSB/MSB-AC6/PartParam.cs

View workflow job for this annotation

GitHub Actions / Build

'MSB_AC6.Part.EnemyBase.UnkStruct50' hides inherited member 'MSB_AC6.Part.UnkStruct50'. Use the new keyword if hiding was intended.

/// <summary>
/// Unknown.
Expand Down Expand Up @@ -1657,8 +1657,7 @@
/// <summary>
/// Unknown.
/// </summary>
[IgnoreProperty]
public sbyte Unk56 { get; set; }
public sbyte KillPayoutClassification { get; set; }

/// <summary>
/// Unknown. Maybe PartsTokenParam?
Expand Down Expand Up @@ -1829,7 +1828,7 @@
Unk3C = -1;
Unk44 = -1;
Unk50 = -1;
Unk56 = (sbyte)-1;
KillPayoutClassification = (sbyte)-1;
PartsTokenParamID = -1;

UnkEnemyStruct70 = new EnemyUnkStruct70();
Expand Down Expand Up @@ -1879,7 +1878,7 @@
Unk50 = br.ReadInt32();
Unk54 = br.ReadByte();
Unk55 = br.ReadByte();
Unk56 = br.ReadSByte();
KillPayoutClassification = br.ReadSByte();
br.AssertByte(new byte[1]);
PartsTokenParamID = br.ReadInt32();
br.AssertInt32(new int[1]);
Expand Down Expand Up @@ -1933,7 +1932,7 @@
bw.WriteInt32(Unk50);
bw.WriteByte(Unk54);
bw.WriteByte(Unk55);
bw.WriteSByte(Unk56);
bw.WriteSByte(KillPayoutClassification);
bw.WriteByte((byte)0);
bw.WriteInt32(PartsTokenParamID);
bw.WriteInt32(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,6 @@ public class Collision : Part
{
/// <summary>
/// HitFilterType
/// Unused as it is not exhaustive
Philiquaz marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
public enum HitFilterType : byte
{
Expand All @@ -1244,6 +1243,7 @@ public enum HitFilterType : byte
FallDamageImmunity = 22,
Unk23 = 23,
Unk24 = 24,
Unk25 = 25,
Unk29 = 29,
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
}
Expand Down Expand Up @@ -1295,7 +1295,7 @@ public enum MapVisiblity : byte
/// <summary>
/// Sets collision behavior. Fall collision, death collision, enemy-only collision, etc.
/// </summary>
public byte HitFilterID { get; set; }
public HitFilterType HitFilterID { get; set; } = HitFilterType.Standard;

/// <summary>
/// Modifies sounds while the player is touching this collision.
Expand Down Expand Up @@ -1405,7 +1405,7 @@ internal Collision(BinaryReaderEx br) : base(br) { }

private protected override void ReadTypeData(BinaryReaderEx br)
{
HitFilterID = br.ReadByte();
HitFilterID = br.ReadEnum8<HitFilterType>();
SoundSpaceType = br.ReadEnum8<SoundSpace>();
EnvLightMapSpotIndex = br.ReadInt16();
ReflectPlaneHeight = br.ReadSingle();
Expand Down Expand Up @@ -1440,7 +1440,7 @@ private protected override void ReadTypeData(BinaryReaderEx br)

private protected override void WriteTypeData(BinaryWriterEx bw)
{
bw.WriteByte(HitFilterID);
bw.WriteByte((byte)HitFilterID);
bw.WriteByte((byte)SoundSpaceType);
bw.WriteInt16(EnvLightMapSpotIndex);
bw.WriteSingle(ReflectPlaneHeight);
Expand Down
Loading
Loading