diff --git a/OpenRA.Game/Graphics/SheetBuilder.cs b/OpenRA.Game/Graphics/SheetBuilder.cs index c72a6f71ac..74c57f92a2 100644 --- a/OpenRA.Game/Graphics/SheetBuilder.cs +++ b/OpenRA.Game/Graphics/SheetBuilder.cs @@ -22,31 +22,39 @@ namespace OpenRA.Graphics "to temporarily avoid the problem.") {} } + public enum SheetType + { + Indexed = 1, + DualIndexed = 2, + BGRA = 4, + } + public class SheetBuilder { Sheet current; + TextureChannel channel; + SheetType type; int rowHeight = 0; Point p; - TextureChannel channel; - Sheet NewSheet() { return new Sheet(new Size(Renderer.SheetSize, Renderer.SheetSize)); } - internal SheetBuilder(TextureChannel ch) + internal SheetBuilder(SheetType t) { - current = NewSheet(); - channel = ch; + current = new Sheet(new Size(Renderer.SheetSize, Renderer.SheetSize));; + channel = TextureChannel.Red; + type = t; } public Sprite Add(byte[] src, Size size, bool allowSheetOverflow) { - Sprite rect = Allocate(size, allowSheetOverflow); + var rect = Allocate(size, allowSheetOverflow); Util.FastCopyIntoChannel(rect, src); return rect; } public Sprite Add(Size size, byte paletteIndex, bool allowSheetOverflow) { - byte[] data = new byte[size.Width * size.Height]; - for (int i = 0; i < data.Length; i++) + var data = new byte[size.Width * size.Height]; + for (var i = 0; i < data.Length; i++) data[i] = paletteIndex; return Add(data, size, allowSheetOverflow); @@ -54,14 +62,11 @@ namespace OpenRA.Graphics TextureChannel? NextChannel(TextureChannel t) { - switch (t) - { - case TextureChannel.Red: return TextureChannel.Green; - case TextureChannel.Green: return TextureChannel.Blue; - case TextureChannel.Blue: return TextureChannel.Alpha; - case TextureChannel.Alpha: - default: return null; - } + var nextChannel = (int)t + (int)type; + if (nextChannel > (int)TextureChannel.Alpha) + return null; + + return (TextureChannel)nextChannel; } public Sprite Allocate(Size imageSize, bool allowSheetOverflow) @@ -93,11 +98,13 @@ namespace OpenRA.Graphics p = new Point(0,0); } - Sprite rect = new Sprite(current, new Rectangle(p, imageSize), channel); + var rect = new Sprite(current, new Rectangle(p, imageSize), channel); current.MakeDirty(); p.X += imageSize.Width; return rect; } + + public Sheet Current { get { return current; } } } } diff --git a/OpenRA.Game/Graphics/SpriteFont.cs b/OpenRA.Game/Graphics/SpriteFont.cs index 89ad06964f..f4284b8055 100644 --- a/OpenRA.Game/Graphics/SpriteFont.cs +++ b/OpenRA.Game/Graphics/SpriteFont.cs @@ -31,8 +31,10 @@ namespace OpenRA.Graphics glyphs = new Cache, GlyphInfo>(CreateGlyph, Pair.EqualityComparer); - // setup a 1-channel SheetBuilder for our private use - if (builder == null) builder = new SheetBuilder(TextureChannel.Alpha); + // setup a SheetBuilder for our private use + // TODO: SheetBuilder state is leaked between mod switches + if (builder == null) + builder = new SheetBuilder(SheetType.BGRA); PrecacheColor(Color.White); PrecacheColor(Color.Red); @@ -46,7 +48,7 @@ namespace OpenRA.Graphics throw new InvalidOperationException(); } - public void DrawText (string text, float2 location, Color c) + public void DrawText(string text, float2 location, Color c) { location.Y += size; // baseline vs top @@ -84,7 +86,7 @@ namespace OpenRA.Graphics public int2 Measure(string text) { - return new int2((int)text.Split( '\n' ).Max( s => s.Sum(a => glyphs[Pair.New(a, Color.White)].Advance)), text.Split('\n').Count()*size); + return new int2((int)text.Split('\n').Max(s => s.Sum(a => glyphs[Pair.New(a, Color.White)].Advance)), text.Split('\n').Count()*size); } Cache, GlyphInfo> glyphs; diff --git a/OpenRA.Game/Graphics/Util.cs b/OpenRA.Game/Graphics/Util.cs index 20d79f4f0f..d0efeadc3e 100644 --- a/OpenRA.Game/Graphics/Util.cs +++ b/OpenRA.Game/Graphics/Util.cs @@ -32,12 +32,13 @@ namespace OpenRA.Graphics static readonly int[] channelMasks = { 2, 1, 0, 3 }; // yes, our channel order is nuts. - public static void FastCopyIntoChannel(Sprite dest, byte[] src) + public static void FastCopyIntoChannel(Sprite dest, byte[] src) { FastCopyIntoChannel(dest, 0, src); } + public static void FastCopyIntoChannel(Sprite dest, int channelOffset, byte[] src) { var data = dest.sheet.Data; var srcStride = dest.bounds.Width; var destStride = dest.sheet.Size.Width * 4; - var destOffset = destStride * dest.bounds.Top + dest.bounds.Left * 4 + channelMasks[(int)dest.channel]; + var destOffset = destStride * dest.bounds.Top + dest.bounds.Left * 4 + channelMasks[(int)dest.channel + channelOffset]; var destSkip = destStride - 4 * srcStride; var height = dest.bounds.Height; diff --git a/OpenRA.Game/ModData.cs b/OpenRA.Game/ModData.cs index dd456520d4..f5c298d4b7 100755 --- a/OpenRA.Game/ModData.cs +++ b/OpenRA.Game/ModData.cs @@ -53,7 +53,7 @@ namespace OpenRA ChromeMetrics.Initialize(Manifest.ChromeMetrics); ChromeProvider.Initialize(Manifest.Chrome); - SheetBuilder = new SheetBuilder(TextureChannel.Red); + SheetBuilder = new SheetBuilder(SheetType.Indexed); SpriteLoader = new SpriteLoader(new string[] { ".shp" }, SheetBuilder); CursorProvider.Initialize(Manifest.Cursors); }