diff --git a/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs b/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs index ebea548da7..9c87ed95db 100755 --- a/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs +++ b/OpenRA.FileFormats/Graphics/IGraphicsDevice.cs @@ -71,7 +71,7 @@ namespace OpenRA.FileFormats.Graphics public interface ITexture { void SetData( Bitmap bitmap ); - void SetData(int[,] colors); + void SetData(uint[,] colors); } public interface IFont diff --git a/OpenRA.FileFormats/Graphics/VqaReader.cs b/OpenRA.FileFormats/Graphics/VqaReader.cs index 9772e4c541..330c322088 100644 --- a/OpenRA.FileFormats/Graphics/VqaReader.cs +++ b/OpenRA.FileFormats/Graphics/VqaReader.cs @@ -9,7 +9,6 @@ #endregion using System; -using System.Drawing; using System.IO; namespace OpenRA.FileFormats @@ -30,7 +29,7 @@ namespace OpenRA.FileFormats byte cbParts; int2 blocks; UInt32[] offsets; - int[] palette; + uint[] palette; // Stores a list of subpixels, referenced by the VPTZ chunk byte[] cbf; @@ -42,7 +41,7 @@ namespace OpenRA.FileFormats byte[] origData; // Final frame output - int[,] frameData; + uint[,] frameData; byte[] audioData; // audio for this frame: 22050Hz 16bit mono pcm, uncompressed. public byte[] AudioData { get { return audioData; } } @@ -89,9 +88,9 @@ namespace OpenRA.FileFormats var frameSize = NextPowerOf2(Math.Max(Width,Height)); cbf = new byte[Width*Height]; cbp = new byte[Width*Height]; - palette = new int[numColors]; + palette = new uint[numColors]; origData = new byte[2*blocks.X*blocks.Y]; - frameData = new int[frameSize,frameSize]; + frameData = new uint[frameSize,frameSize]; var type = new String(reader.ReadChars(4)); Console.WriteLine(type); @@ -140,7 +139,7 @@ namespace OpenRA.FileFormats while (reader.BaseStream.Position < end) { var type = new String(reader.ReadChars(4)); - var length = Swap(reader.ReadUInt32()); + var length = int2.Swap(reader.ReadUInt32()); switch (type) { @@ -181,14 +180,14 @@ namespace OpenRA.FileFormats while(reader.BaseStream.Position < end) { var type = new String(reader.ReadChars(4)); - var length = Swap(reader.ReadUInt32()); + var length = int2.Swap(reader.ReadUInt32()); switch(type) { case "VQFR": DecodeVQFR(reader); break; - default: + default: // Don't parse sound here. reader.ReadBytes((int)length); break; @@ -207,7 +206,7 @@ namespace OpenRA.FileFormats // Chunks are aligned on even bytes; may be padded with a single null if (reader.PeekChar() == 0) reader.ReadByte(); var type = new String(reader.ReadChars(4)); - int subchunkLength = (int)Swap(reader.ReadUInt32()); + int subchunkLength = (int)int2.Swap(reader.ReadUInt32()); switch(type) { @@ -243,10 +242,10 @@ namespace OpenRA.FileFormats case "CPL0": for (int i = 0; i < numColors; i++) { - byte r = reader.ReadByte(); - byte g = reader.ReadByte(); - byte b = reader.ReadByte(); - palette[i] = Color.FromArgb(255,ToColorByte(r),ToColorByte(g),ToColorByte(b)).ToArgb(); + byte r = (byte)(reader.ReadByte() << 2); + byte g = (byte)(reader.ReadByte() << 2); + byte b = (byte)(reader.ReadByte() << 2); + palette[i] = (uint)(255 << 24 | (r << 16) | (g << 8) | b); } break; @@ -262,7 +261,7 @@ namespace OpenRA.FileFormats } int cachedFrame = -1; - public int[,] FrameData { get + public uint[,] FrameData { get { if (cachedFrame != currentFrame) { @@ -294,16 +293,5 @@ namespace OpenRA.FileFormats ++v; return v; } - - public byte ToColorByte(byte b) - { - return (byte)((b & 63) * 255 / 63); - } - - // Change endianness of a uint32 - public UInt32 Swap(UInt32 orig) - { - return (UInt32)((orig & 0xff000000) >> 24) | ((orig & 0x00ff0000) >> 8) | ((orig & 0x0000ff00) << 8) | ((orig & 0x000000ff) << 24); - } } } diff --git a/OpenRA.FileFormats/Palette.cs b/OpenRA.FileFormats/Palette.cs index ffcdd48885..e312545db2 100644 --- a/OpenRA.FileFormats/Palette.cs +++ b/OpenRA.FileFormats/Palette.cs @@ -11,20 +11,27 @@ using System.Collections.Generic; using System.Drawing; using System.IO; +using System.Linq; namespace OpenRA.FileFormats { public class Palette { - List colors = new List(); - + uint[] colors; public Color GetColor(int index) { - return colors[index]; + return Color.FromArgb((int)colors[index]); + } + + public uint[] Values + { + get { return colors; } } public Palette(Stream s, bool remapTransparent) { + colors = new uint[256]; + using (BinaryReader reader = new BinaryReader(s)) { for (int i = 0; i < 256; i++) @@ -32,24 +39,26 @@ namespace OpenRA.FileFormats byte r = (byte)(reader.ReadByte() << 2); byte g = (byte)(reader.ReadByte() << 2); byte b = (byte)(reader.ReadByte() << 2); - - colors.Add(Color.FromArgb(r, g, b)); + + colors[i] = (uint)Color.FromArgb(r,g,b).ToArgb();//(uint)(((byte)255 << 0) | (r << 16));// | (g << 8) | b); } } - colors[0] = Color.FromArgb(0, 0, 0, 0); + colors[0] = 0;//Color.FromArgb(0, 0, 0, 0); if (remapTransparent) { - colors[3] = Color.FromArgb(178, 0, 0, 0); - colors[4] = Color.FromArgb(140, 0, 0, 0); + colors[3] = (uint)178 << 24;//Color.FromArgb(178, 0, 0, 0); + colors[4] = (uint)140 << 24;//Color.FromArgb(140, 0, 0, 0); } } public Palette(Palette p, IPaletteRemap r) { - for (int i = 0; i < 256; i++) - colors.Add(r.GetRemappedColor(p.GetColor(i), i)); + colors = p.colors; + + //for (int i = 0; i < 256; i++) + // colors.Add(r.GetRemappedColor(p.GetColor(i), i)); } } diff --git a/OpenRA.FileFormats/Primitives/int2.cs b/OpenRA.FileFormats/Primitives/int2.cs index 93d0adf659..4426048304 100644 --- a/OpenRA.FileFormats/Primitives/int2.cs +++ b/OpenRA.FileFormats/Primitives/int2.cs @@ -53,5 +53,11 @@ namespace OpenRA public float2 ToFloat2() { return new float2(X, Y); } public override string ToString() { return string.Format("{0},{1}", X, Y); } + + // Change endianness of a uint32 + public static uint Swap(uint orig) + { + return (uint)((orig & 0xff000000) >> 24) | ((orig & 0x00ff0000) >> 8) | ((orig & 0x0000ff00) << 8) | ((orig & 0x000000ff) << 24); + } } } diff --git a/OpenRA.Game/Graphics/HardwarePalette.cs b/OpenRA.Game/Graphics/HardwarePalette.cs index eec0cf10b4..969894149f 100644 --- a/OpenRA.Game/Graphics/HardwarePalette.cs +++ b/OpenRA.Game/Graphics/HardwarePalette.cs @@ -77,11 +77,20 @@ namespace OpenRA.Graphics public void Update(IEnumerable paletteMods) { - var b = new Bitmap(Bitmap); - foreach (var mod in paletteMods) - mod.AdjustPalette(b); - - Texture.SetData(b); + //var b = new Bitmap(Bitmap); + //foreach (var mod in paletteMods) + // mod.AdjustPalette(b); + + var data = new uint[256,MaxPalettes]; + foreach (var pal in palettes) + { + var j = indices[pal.Key]; + var c = pal.Value.Values; + for (var i = 0; i < 256; i++) + data[i,j] = c[i]; + } + + Texture.SetData(data); Game.Renderer.PaletteTexture = Texture; } } diff --git a/OpenRA.Game/Widgets/VqaPlayerWidget.cs b/OpenRA.Game/Widgets/VqaPlayerWidget.cs index 2faef53b72..48812b7642 100644 --- a/OpenRA.Game/Widgets/VqaPlayerWidget.cs +++ b/OpenRA.Game/Widgets/VqaPlayerWidget.cs @@ -23,7 +23,7 @@ namespace OpenRA.Widgets string cachedVideo; float invLength; float2 videoOrigin, videoSize; - int[,] overlay; + uint[,] overlay; bool stopped; bool paused; @@ -56,8 +56,8 @@ namespace OpenRA.Widgets if (!DrawOverlay) return; - overlay = new int[2*textureSize, 2*textureSize]; - var black = Color.Black.ToArgb(); + overlay = new uint[2*textureSize, 2*textureSize]; + uint black = (uint)255 << 24; for (var y = 0; y < video.Height; y++) for (var x = 0; x < video.Width; x++) overlay[2*y,x] = black; diff --git a/OpenRA.Gl/Texture.cs b/OpenRA.Gl/Texture.cs index ec319d2571..fa1a187af7 100644 --- a/OpenRA.Gl/Texture.cs +++ b/OpenRA.Gl/Texture.cs @@ -28,8 +28,8 @@ namespace OpenRA.GlRenderer SetData(bitmap); } - // An array of Color.ToARGB()'s - public void SetData(int[,] colors) + // An array of RGBA + public void SetData(uint[,] colors) { int width = colors.GetUpperBound(0) + 1; int height = colors.GetUpperBound(1) + 1; @@ -37,22 +37,23 @@ namespace OpenRA.GlRenderer if (!IsPowerOf2(width) || !IsPowerOf2(height)) throw new InvalidDataException("Non-power-of-two array {0}x{1}".F(width,height)); - IntPtr intPtr; unsafe { - fixed (int* ptr = colors) - intPtr = new IntPtr((void *) ptr); - } - - Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture); - GraphicsDevice.CheckGlError(); - Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_BASE_LEVEL, 0); - GraphicsDevice.CheckGlError(); - Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAX_LEVEL, 0); - GraphicsDevice.CheckGlError(); - Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, width, height, - 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, intPtr); - GraphicsDevice.CheckGlError(); + fixed (uint* ptr = colors) + { + IntPtr intPtr = new IntPtr((void *) ptr); + + Gl.glBindTexture(Gl.GL_TEXTURE_2D, texture); + GraphicsDevice.CheckGlError(); + Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_BASE_LEVEL, 0); + GraphicsDevice.CheckGlError(); + Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAX_LEVEL, 0); + GraphicsDevice.CheckGlError(); + Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, width, height, + 0, Gl.GL_BGRA, Gl.GL_UNSIGNED_BYTE, intPtr); + GraphicsDevice.CheckGlError(); + } + } } public void SetData(Bitmap bitmap)