Move ShpD2 sprite loading into Mods.Common.
This commit is contained in:
@@ -15,52 +15,11 @@ using OpenRA.FileFormats;
|
|||||||
namespace OpenRA.Graphics
|
namespace OpenRA.Graphics
|
||||||
{
|
{
|
||||||
// TODO: Most of this should be moved into the format parsers themselves.
|
// TODO: Most of this should be moved into the format parsers themselves.
|
||||||
public enum SpriteType { Unknown, ShpD2 }
|
public enum SpriteType { Unknown }
|
||||||
public static class SpriteSource
|
public static class SpriteSource
|
||||||
{
|
{
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SpriteType DetectSpriteType(Stream s)
|
public static SpriteType DetectSpriteType(Stream s)
|
||||||
{
|
{
|
||||||
if (IsShpD2(s))
|
|
||||||
return SpriteType.ShpD2;
|
|
||||||
|
|
||||||
return SpriteType.Unknown;
|
return SpriteType.Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,8 +28,6 @@ namespace OpenRA.Graphics
|
|||||||
var type = DetectSpriteType(s);
|
var type = DetectSpriteType(s);
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case SpriteType.ShpD2:
|
|
||||||
return new ShpD2Reader(s);
|
|
||||||
case SpriteType.Unknown:
|
case SpriteType.Unknown:
|
||||||
default:
|
default:
|
||||||
throw new InvalidDataException(filename + " is not a valid sprite file");
|
throw new InvalidDataException(filename + " is not a valid sprite file");
|
||||||
|
|||||||
@@ -277,7 +277,6 @@
|
|||||||
<Compile Include="FileFormats\XccLocalDatabase.cs" />
|
<Compile Include="FileFormats\XccLocalDatabase.cs" />
|
||||||
<Compile Include="FileFormats\HvaReader.cs" />
|
<Compile Include="FileFormats\HvaReader.cs" />
|
||||||
<Compile Include="FileFormats\PngLoader.cs" />
|
<Compile Include="FileFormats\PngLoader.cs" />
|
||||||
<Compile Include="FileFormats\ShpD2Reader.cs" />
|
|
||||||
<Compile Include="FileFormats\VqaReader.cs" />
|
<Compile Include="FileFormats\VqaReader.cs" />
|
||||||
<Compile Include="FileFormats\VxlReader.cs" />
|
<Compile Include="FileFormats\VxlReader.cs" />
|
||||||
<Compile Include="Primitives\ActionQueue.cs" />
|
<Compile Include="Primitives\ActionQueue.cs" />
|
||||||
|
|||||||
@@ -117,6 +117,7 @@
|
|||||||
<Compile Include="SpriteLoaders\ShpTSLoader.cs" />
|
<Compile Include="SpriteLoaders\ShpTSLoader.cs" />
|
||||||
<Compile Include="SpriteLoaders\TmpRALoader.cs" />
|
<Compile Include="SpriteLoaders\TmpRALoader.cs" />
|
||||||
<Compile Include="SpriteLoaders\TmpTDLoader.cs" />
|
<Compile Include="SpriteLoaders\TmpTDLoader.cs" />
|
||||||
|
<Compile Include="SpriteLoaders\ShpD2Loader.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|||||||
@@ -9,13 +9,16 @@
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRA.FileFormats;
|
||||||
using OpenRA.Graphics;
|
using OpenRA.Graphics;
|
||||||
|
|
||||||
namespace OpenRA.FileFormats
|
namespace OpenRA.Mods.Common.SpriteLoaders
|
||||||
{
|
{
|
||||||
public class ShpD2Reader : ISpriteSource
|
public class ShpD2Loader : ISpriteLoader
|
||||||
{
|
{
|
||||||
[Flags] enum FormatFlags : int
|
[Flags] enum FormatFlags : int
|
||||||
{
|
{
|
||||||
@@ -24,7 +27,7 @@ namespace OpenRA.FileFormats
|
|||||||
VariableLengthTable = 4
|
VariableLengthTable = 4
|
||||||
}
|
}
|
||||||
|
|
||||||
class Frame : ISpriteFrame
|
class ShpD2Frame : ISpriteFrame
|
||||||
{
|
{
|
||||||
public Size Size { get; private set; }
|
public Size Size { get; private set; }
|
||||||
public Size FrameSize { get { return Size; } }
|
public Size FrameSize { get { return Size; } }
|
||||||
@@ -32,7 +35,7 @@ namespace OpenRA.FileFormats
|
|||||||
public byte[] Data { get; set; }
|
public byte[] Data { get; set; }
|
||||||
public bool DisableExportPadding { get { return false; } }
|
public bool DisableExportPadding { get { return false; } }
|
||||||
|
|
||||||
public Frame(Stream s)
|
public ShpD2Frame(Stream s)
|
||||||
{
|
{
|
||||||
var flags = (FormatFlags)s.ReadUInt16();
|
var flags = (FormatFlags)s.ReadUInt16();
|
||||||
s.Position += 1;
|
s.Position += 1;
|
||||||
@@ -84,10 +87,48 @@ namespace OpenRA.FileFormats
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyList<ISpriteFrame> Frames { get; private set; }
|
bool IsShpD2(Stream s)
|
||||||
|
|
||||||
public ShpD2Reader(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShpD2Frame[] ParseFrames(Stream s)
|
||||||
|
{
|
||||||
|
var start = s.Position;
|
||||||
|
|
||||||
var imageCount = s.ReadUInt16();
|
var imageCount = s.ReadUInt16();
|
||||||
|
|
||||||
// Last offset is pointer to end of file.
|
// Last offset is pointer to end of file.
|
||||||
@@ -101,13 +142,27 @@ namespace OpenRA.FileFormats
|
|||||||
for (var i = 0; i < imageCount + 1; i++)
|
for (var i = 0; i < imageCount + 1; i++)
|
||||||
offsets[i] = (twoByteOffset ? s.ReadUInt16() : s.ReadUInt32()) + 2;
|
offsets[i] = (twoByteOffset ? s.ReadUInt16() : s.ReadUInt32()) + 2;
|
||||||
|
|
||||||
var frames = new Frame[imageCount];
|
var frames = new ShpD2Frame[imageCount];
|
||||||
Frames = frames.AsReadOnly();
|
|
||||||
for (var i = 0; i < frames.Length; i++)
|
for (var i = 0; i < frames.Length; i++)
|
||||||
{
|
{
|
||||||
s.Position = offsets[i];
|
s.Position = offsets[i];
|
||||||
frames[i] = new Frame(s);
|
frames[i] = new ShpD2Frame(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.Position = start;
|
||||||
|
return frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryParseSprite(Stream s, out ISpriteFrame[] frames)
|
||||||
|
{
|
||||||
|
if (!IsShpD2(s))
|
||||||
|
{
|
||||||
|
frames = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
frames = ParseFrames(s);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user