Fix D2 shp parsing and make it a proper frame source.
This commit is contained in:
@@ -28,7 +28,7 @@ namespace OpenRA.FileFormats
|
||||
IEnumerable<ISpriteFrame> Frames { get; }
|
||||
}
|
||||
|
||||
public enum SpriteType { Unknown, ShpTD, ShpTS, TmpTD, TmpRA, R8 }
|
||||
public enum SpriteType { Unknown, ShpTD, ShpTS, ShpD2, TmpTD, TmpRA, R8 }
|
||||
public static class SpriteSource
|
||||
{
|
||||
static bool IsTmpRA(Stream s)
|
||||
@@ -129,6 +129,44 @@ namespace OpenRA.FileFormats
|
||||
return b == 0x20 || b == 0x40 || b == 0x80;
|
||||
}
|
||||
|
||||
static bool IsShpD2(Stream s)
|
||||
{
|
||||
var start = s.Position;
|
||||
|
||||
// First word is the image count
|
||||
var imageCount = s.ReadUInt16();
|
||||
if (imageCount == 0)
|
||||
{
|
||||
s.Position = start;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Test for two vs four byte offset
|
||||
var testOffset = s.ReadUInt32();
|
||||
var offsetSize = (testOffset & 0xFF0000) > 0 ? 2 : 4;
|
||||
|
||||
// Last offset should point to the end of file
|
||||
var finalOffset = start + 2 + offsetSize * imageCount;
|
||||
if (finalOffset > s.Length)
|
||||
{
|
||||
s.Position = start;
|
||||
return false;
|
||||
}
|
||||
|
||||
s.Position = finalOffset;
|
||||
var eof = offsetSize == 2 ? s.ReadUInt16() : s.ReadUInt32();
|
||||
if (eof + 2 != s.Length)
|
||||
{
|
||||
s.Position = start;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the format flag on the first frame
|
||||
var b = s.ReadUInt16();
|
||||
s.Position = start;
|
||||
return b == 5 || b <= 3;
|
||||
}
|
||||
|
||||
static bool IsR8(Stream s)
|
||||
{
|
||||
var start = s.Position;
|
||||
@@ -165,6 +203,9 @@ namespace OpenRA.FileFormats
|
||||
if (IsTmpTD(s))
|
||||
return SpriteType.TmpTD;
|
||||
|
||||
if (IsShpD2(s))
|
||||
return SpriteType.ShpD2;
|
||||
|
||||
return SpriteType.Unknown;
|
||||
}
|
||||
|
||||
@@ -183,6 +224,8 @@ namespace OpenRA.FileFormats
|
||||
return new TmpRAReader(s);
|
||||
case SpriteType.TmpTD:
|
||||
return new TmpTDReader(s);
|
||||
case SpriteType.ShpD2:
|
||||
return new ShpD2Reader(s);
|
||||
case SpriteType.Unknown:
|
||||
default:
|
||||
throw new InvalidDataException(filename + " is not a valid sprite file");
|
||||
|
||||
Reference in New Issue
Block a user