Move ShpD2 sprite loading into Mods.Common.

This commit is contained in:
Paul Chote
2014-10-05 16:34:48 +13:00
parent 533d044755
commit beb7a394a2
4 changed files with 67 additions and 55 deletions

View File

@@ -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");

View 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" />

View File

@@ -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>

View File

@@ -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;
} }
} }
} }