Add plumbing for mod-defined sprite loaders.
This commit is contained in:
@@ -45,7 +45,7 @@ namespace OpenRA.Graphics
|
|||||||
foreach (var p in nodesDict["Palettes"].Nodes)
|
foreach (var p in nodesDict["Palettes"].Nodes)
|
||||||
palette.AddPalette(p.Key, new ImmutablePalette(GlobalFileSystem.Open(p.Value.Value), shadowIndex), false);
|
palette.AddPalette(p.Key, new ImmutablePalette(GlobalFileSystem.Open(p.Value.Value), shadowIndex), false);
|
||||||
|
|
||||||
var spriteLoader = new SpriteLoader(new string[0], new SheetBuilder(SheetType.Indexed));
|
var spriteLoader = new SpriteLoader(modData.SpriteLoaders, new string[0], new SheetBuilder(SheetType.Indexed));
|
||||||
foreach (var s in nodesDict["Cursors"].Nodes)
|
foreach (var s in nodesDict["Cursors"].Nodes)
|
||||||
LoadSequencesForCursor(spriteLoader, s.Key, s.Value);
|
LoadSequencesForCursor(spriteLoader, s.Key, s.Value);
|
||||||
spriteLoader.SheetBuilder.Current.ReleaseBuffer();
|
spriteLoader.SheetBuilder.Current.ReleaseBuffer();
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ namespace OpenRA.Graphics
|
|||||||
{
|
{
|
||||||
this.modData = modData;
|
this.modData = modData;
|
||||||
|
|
||||||
spriteLoader = Exts.Lazy(() => new SpriteLoader(tileSet.Extensions, new SheetBuilder(SheetType.Indexed)));
|
spriteLoader = Exts.Lazy(() => new SpriteLoader(modData.SpriteLoaders, tileSet.Extensions, new SheetBuilder(SheetType.Indexed)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sequences LoadSequences(Map map)
|
public Sequences LoadSequences(Map map)
|
||||||
|
|||||||
@@ -8,21 +8,44 @@
|
|||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OpenRA.FileSystem;
|
using OpenRA.FileSystem;
|
||||||
using OpenRA.Primitives;
|
using OpenRA.Primitives;
|
||||||
|
|
||||||
namespace OpenRA.Graphics
|
namespace OpenRA.Graphics
|
||||||
{
|
{
|
||||||
|
public interface ISpriteLoader
|
||||||
|
{
|
||||||
|
bool TryParseSprite(Stream s, out ISpriteFrame[] frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ISpriteFrame
|
||||||
|
{
|
||||||
|
Size Size { get; }
|
||||||
|
Size FrameSize { get; }
|
||||||
|
float2 Offset { get; }
|
||||||
|
byte[] Data { get; }
|
||||||
|
bool DisableExportPadding { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ISpriteSource
|
||||||
|
{
|
||||||
|
IReadOnlyList<ISpriteFrame> Frames { get; }
|
||||||
|
}
|
||||||
|
|
||||||
public class SpriteLoader
|
public class SpriteLoader
|
||||||
{
|
{
|
||||||
public readonly SheetBuilder SheetBuilder;
|
public readonly SheetBuilder SheetBuilder;
|
||||||
|
readonly ISpriteLoader[] loaders;
|
||||||
readonly Cache<string, Sprite[]> sprites;
|
readonly Cache<string, Sprite[]> sprites;
|
||||||
readonly Cache<string, ISpriteFrame[]> frames;
|
readonly Cache<string, ISpriteFrame[]> frames;
|
||||||
readonly string[] exts;
|
readonly string[] exts;
|
||||||
|
|
||||||
public SpriteLoader(string[] exts, SheetBuilder sheetBuilder)
|
public SpriteLoader(ISpriteLoader[] loaders, string[] exts, SheetBuilder sheetBuilder)
|
||||||
{
|
{
|
||||||
|
this.loaders = loaders;
|
||||||
SheetBuilder = sheetBuilder;
|
SheetBuilder = sheetBuilder;
|
||||||
|
|
||||||
// Include extension-less version
|
// Include extension-less version
|
||||||
@@ -40,8 +63,16 @@ namespace OpenRA.Graphics
|
|||||||
ISpriteFrame[] CacheFrames(string filename)
|
ISpriteFrame[] CacheFrames(string filename)
|
||||||
{
|
{
|
||||||
using (var stream = GlobalFileSystem.OpenWithExts(filename, exts))
|
using (var stream = GlobalFileSystem.OpenWithExts(filename, exts))
|
||||||
|
{
|
||||||
|
ISpriteFrame[] frames;
|
||||||
|
foreach (var loader in loaders)
|
||||||
|
if (loader.TryParseSprite(stream, out frames))
|
||||||
|
return frames;
|
||||||
|
|
||||||
|
// Fall back to the hardcoded types (for now).
|
||||||
return SpriteSource.LoadSpriteSource(stream, filename).Frames
|
return SpriteSource.LoadSpriteSource(stream, filename).Frames
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sprite[] LoadAllSprites(string filename) { return sprites[filename]; }
|
public Sprite[] LoadAllSprites(string filename) { return sprites[filename]; }
|
||||||
|
|||||||
@@ -14,20 +14,6 @@ using OpenRA.FileFormats;
|
|||||||
|
|
||||||
namespace OpenRA.Graphics
|
namespace OpenRA.Graphics
|
||||||
{
|
{
|
||||||
public interface ISpriteFrame
|
|
||||||
{
|
|
||||||
Size Size { get; }
|
|
||||||
Size FrameSize { get; }
|
|
||||||
float2 Offset { get; }
|
|
||||||
byte[] Data { get; }
|
|
||||||
bool DisableExportPadding { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface ISpriteSource
|
|
||||||
{
|
|
||||||
IReadOnlyList<ISpriteFrame> Frames { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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, ShpTD, ShpTS, ShpD2, TmpTD, TmpRA, TmpTS, R8 }
|
public enum SpriteType { Unknown, ShpTD, ShpTS, ShpD2, TmpTD, TmpRA, TmpTS, R8 }
|
||||||
public static class SpriteSource
|
public static class SpriteSource
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace OpenRA.Graphics
|
|||||||
templates = new Dictionary<ushort, Sprite[]>();
|
templates = new Dictionary<ushort, Sprite[]>();
|
||||||
|
|
||||||
// We manage the SheetBuilder ourselves, to avoid loading all of the tileset images
|
// We manage the SheetBuilder ourselves, to avoid loading all of the tileset images
|
||||||
var spriteLoader = new SpriteLoader(tileset.Extensions, null);
|
var spriteLoader = new SpriteLoader(Game.modData.SpriteLoaders, tileset.Extensions, null);
|
||||||
foreach (var t in tileset.Templates)
|
foreach (var t in tileset.Templates)
|
||||||
{
|
{
|
||||||
var allFrames = spriteLoader.LoadAllFrames(t.Value.Image);
|
var allFrames = spriteLoader.LoadAllFrames(t.Value.Image);
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ namespace OpenRA
|
|||||||
public readonly Size TileSize = new Size(24, 24);
|
public readonly Size TileSize = new Size(24, 24);
|
||||||
public readonly TileShape TileShape = TileShape.Rectangle;
|
public readonly TileShape TileShape = TileShape.Rectangle;
|
||||||
|
|
||||||
|
public readonly string[] SpriteFormats = { };
|
||||||
|
|
||||||
[Desc("(x,y,z) offset of the full cell and each sub-cell", "X & Y should be between -512 ... 512 and Z >= 0")]
|
[Desc("(x,y,z) offset of the full cell and each sub-cell", "X & Y should be between -512 ... 512 and Z >= 0")]
|
||||||
public readonly WVec[] SubCellOffsets =
|
public readonly WVec[] SubCellOffsets =
|
||||||
{
|
{
|
||||||
@@ -128,6 +130,9 @@ namespace OpenRA
|
|||||||
compat.Add(c.Trim());
|
compat.Add(c.Trim());
|
||||||
|
|
||||||
MapCompatibility = compat.ToArray();
|
MapCompatibility = compat.ToArray();
|
||||||
|
|
||||||
|
if (yaml.ContainsKey("SpriteFormats"))
|
||||||
|
SpriteFormats = FieldLoader.GetValue<string[]>("SpriteFormats", yaml["SpriteFormats"].Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static string[] YamlList(Dictionary<string, MiniYaml> yaml, string key)
|
static string[] YamlList(Dictionary<string, MiniYaml> yaml, string key)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace OpenRA
|
|||||||
public readonly ObjectCreator ObjectCreator;
|
public readonly ObjectCreator ObjectCreator;
|
||||||
public readonly WidgetLoader WidgetLoader;
|
public readonly WidgetLoader WidgetLoader;
|
||||||
public readonly MapCache MapCache;
|
public readonly MapCache MapCache;
|
||||||
|
public readonly ISpriteLoader[] SpriteLoaders;
|
||||||
public ILoadScreen LoadScreen = null;
|
public ILoadScreen LoadScreen = null;
|
||||||
public VoxelLoader VoxelLoader;
|
public VoxelLoader VoxelLoader;
|
||||||
public readonly RulesetCache RulesetCache;
|
public readonly RulesetCache RulesetCache;
|
||||||
@@ -45,6 +46,18 @@ namespace OpenRA
|
|||||||
RulesetCache.LoadingProgress += HandleLoadingProgress;
|
RulesetCache.LoadingProgress += HandleLoadingProgress;
|
||||||
MapCache = new MapCache(this);
|
MapCache = new MapCache(this);
|
||||||
|
|
||||||
|
var loaders = new List<ISpriteLoader>();
|
||||||
|
foreach (var format in Manifest.SpriteFormats)
|
||||||
|
{
|
||||||
|
var loader = ObjectCreator.FindType(format + "Loader");
|
||||||
|
if (loader == null || !loader.GetInterfaces().Contains(typeof(ISpriteLoader)))
|
||||||
|
throw new InvalidOperationException("Unable to find a sprite loader for type '{0}'.".F(format));
|
||||||
|
|
||||||
|
loaders.Add((ISpriteLoader)ObjectCreator.CreateBasic(loader));
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteLoaders = loaders.ToArray();
|
||||||
|
|
||||||
// HACK: Mount only local folders so we have a half-working environment for the asset installer
|
// HACK: Mount only local folders so we have a half-working environment for the asset installer
|
||||||
GlobalFileSystem.UnmountAll();
|
GlobalFileSystem.UnmountAll();
|
||||||
foreach (var dir in Manifest.Folders)
|
foreach (var dir in Manifest.Folders)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ namespace OpenRA.Mods.Common.UtilityCommands
|
|||||||
|
|
||||||
var palette = new ImmutablePalette(args[2], shadowIndex);
|
var palette = new ImmutablePalette(args[2], shadowIndex);
|
||||||
|
|
||||||
var frames = new SpriteLoader(new string[0], null)
|
var frames = new SpriteLoader(modData.SpriteLoaders, new string[0], null)
|
||||||
.LoadAllFrames(src);
|
.LoadAllFrames(src);
|
||||||
|
|
||||||
var usePadding = !args.Contains("--nopadding");
|
var usePadding = !args.Contains("--nopadding");
|
||||||
|
|||||||
Reference in New Issue
Block a user