Beispiel #1
0
        // TODO: The package should be mounted into its own context to avoid name collisions with installed files
        public static bool ExtractFromPackage(string srcPath, string package, string[] files, string destPath, Action <string> onProgress, Action <string> onError)
        {
            if (!Directory.Exists(destPath))
            {
                Directory.CreateDirectory(destPath);
            }

            if (!GlobalFileSystem.Exists(srcPath))
            {
                onError("Cannot find " + package); return(false);
            }
            GlobalFileSystem.Mount(srcPath);
            if (!GlobalFileSystem.Exists(package))
            {
                onError("Cannot find " + package); return(false);
            }
            GlobalFileSystem.Mount(package);

            foreach (string s in files)
            {
                var destFile = Path.Combine(destPath, s);
                using (var sourceStream = GlobalFileSystem.Open(s))
                    using (var destStream = File.Create(destFile))
                    {
                        onProgress("Extracting " + s);
                        destStream.Write(sourceStream.ReadAllBytes());
                    }
            }

            return(true);
        }
Beispiel #2
0
        public Sheet(string filename)
        {
            var bitmap = (Bitmap)Image.FromStream(GlobalFileSystem.Open(filename));

            Size = bitmap.Size;

            data = new byte[4 * Size.Width * Size.Height];
            var b = bitmap.LockBits(bitmap.Bounds(),
                                    ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            unsafe
            {
                int *c = (int *)b.Scan0;

                for (var x = 0; x < Size.Width; x++)
                {
                    for (var y = 0; y < Size.Height; y++)
                    {
                        var i = 4 * Size.Width * y + 4 * x;

                        // Convert argb to bgra
                        var argb = *(c + (y * b.Stride >> 2) + x);
                        data[i++] = (byte)(argb >> 0);
                        data[i++] = (byte)(argb >> 8);
                        data[i++] = (byte)(argb >> 16);
                        data[i++] = (byte)(argb >> 24);
                    }
                }
            }
            bitmap.UnlockBits(b);
        }
Beispiel #3
0
 public void LoadPalettes(WorldRenderer wr)
 {
     if (info.Tileset == null || info.Tileset.ToLowerInvariant() == world.Map.Tileset.ToLowerInvariant())
     {
         wr.AddPalette(info.Name, new ImmutablePalette(GlobalFileSystem.Open(info.Filename), info.ShadowIndex), info.AllowModifiers);
     }
 }
Beispiel #4
0
        public MusicInfo(string key, MiniYaml value)
        {
            Title = value.Value;

            var nd = value.ToDictionary();

            if (nd.ContainsKey("Hidden"))
            {
                bool.TryParse(nd["Hidden"].Value, out Hidden);
            }

            var ext = nd.ContainsKey("Extension") ? nd["Extension"].Value : "aud";

            Filename = (nd.ContainsKey("Filename") ? nd["Filename"].Value : key) + "." + ext;

            if (!GlobalFileSystem.Exists(Filename))
            {
                return;
            }

            Exists = true;
            using (var s = GlobalFileSystem.Open(Filename))
            {
                if (Filename.ToLowerInvariant().EndsWith("wav"))
                {
                    Length = (int)WavLoader.WaveLength(s);
                }
                else
                {
                    Length = (int)AudLoader.SoundLength(s);
                }
            }
        }
Beispiel #5
0
        public CursorProvider(ModData modData)
        {
            var sequenceFiles = modData.Manifest.Cursors;

            cursors  = new Dictionary <string, CursorSequence>();
            palettes = new Cache <string, PaletteReference>(CreatePaletteReference);
            var sequences   = new MiniYaml(null, sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergeLiberal));
            var shadowIndex = new int[] { };

            var nodesDict = sequences.ToDictionary();

            if (nodesDict.ContainsKey("ShadowIndex"))
            {
                Array.Resize(ref shadowIndex, shadowIndex.Length + 1);
                Exts.TryParseIntegerInvariant(nodesDict["ShadowIndex"].Value,
                                              out shadowIndex[shadowIndex.Length - 1]);
            }

            palette = new HardwarePalette();
            foreach (var p in nodesDict["Palettes"].Nodes)
            {
                palette.AddPalette(p.Key, new ImmutablePalette(GlobalFileSystem.Open(p.Value.Value), shadowIndex), false);
            }

            var spriteLoader = new SpriteLoader(new string[0], new SheetBuilder(SheetType.Indexed));

            foreach (var s in nodesDict["Cursors"].Nodes)
            {
                LoadSequencesForCursor(spriteLoader, s.Key, s.Value);
            }
            spriteLoader.SheetBuilder.Current.ReleaseBuffer();

            palette.Initialize();
        }
Beispiel #6
0
        // TODO: The package should be mounted into its own context to avoid name collisions with installed files
        public static bool ExtractFromPackage(string srcPath, string package, string annotation, string[] files, string destPath, Action <string> onProgress, Action <string> onError)
        {
            if (!Directory.Exists(destPath))
            {
                Directory.CreateDirectory(destPath);
            }

            Log.Write("debug", "Mounting {0}".F(srcPath));
            GlobalFileSystem.Mount(srcPath);
            Log.Write("debug", "Mounting {0}".F(package));
            GlobalFileSystem.Mount(package, annotation);

            foreach (var file in files)
            {
                var dest = Path.Combine(destPath, file);
                if (File.Exists(dest))
                {
                    File.Delete(dest);
                }
                using (var sourceStream = GlobalFileSystem.Open(file))
                    using (var destStream = File.Create(dest))
                    {
                        Log.Write("debug", "Extracting {0} to {1}".F(file, dest));
                        onProgress("Extracting " + file);
                        destStream.Write(sourceStream.ReadAllBytes());
                    }
            }

            return(true);
        }
Beispiel #7
0
        public CreditsLogic(Widget widget, Action onExit)
        {
            var panel = widget.Get("CREDITS_PANEL");

            panel.Get <ButtonWidget>("BACK_BUTTON").OnClick = () =>
            {
                Ui.CloseWindow();
                onExit();
            };

            var scrollPanel = panel.Get <ScrollPanelWidget>("CREDITS_DISPLAY");
            var template    = scrollPanel.Get <LabelWidget>("CREDITS_TEMPLATE");

            scrollPanel.RemoveChildren();

            var lines = GlobalFileSystem.Open("AUTHORS").ReadAllLines();

            foreach (var l in lines)
            {
                // Improve the formatting
                var line  = l.Replace("\t", "    ").Replace("*", "\u2022");
                var label = template.Clone() as LabelWidget;
                label.GetText = () => line;
                scrollPanel.AddChild(label);
            }
        }
Beispiel #8
0
        public static ResourceTemplate RenderResourceType(ResourceTypeInfo info, TileSet tileset, IPalette p)
        {
            var image = ResolveFilename(info.EditorSprite, tileset);

            using (var s = GlobalFileSystem.Open(image))
            {
                // TODO: Do this properly
                var shp   = new ShpTDSprite(s);
                var frame = shp.Frames.Last();

                var bitmap = new Bitmap(frame.Size.Width, frame.Size.Height, PixelFormat.Format8bppIndexed);
                bitmap.Palette = p.AsSystemPalette();
                var data = bitmap.LockBits(bitmap.Bounds(),
                                           ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

                unsafe
                {
                    var q      = (byte *)data.Scan0.ToPointer();
                    var stride = data.Stride;

                    for (var i = 0; i < frame.Size.Width; i++)
                    {
                        for (var j = 0; j < frame.Size.Height; j++)
                        {
                            q[j * stride + i] = frame.Data[i + frame.Size.Width * j];
                        }
                    }
                }

                bitmap.UnlockBits(data);
                return(new ResourceTemplate {
                    Bitmap = bitmap, Info = info, Value = shp.Frames.Count - 1
                });
            }
        }
        public void WorldLoaded(World w, WorldRenderer wr)
        {
            world = w;
            sma   = world.WorldActor.Trait <SpawnMapActors>();

            context.Lua["World"]         = w;
            context.Lua["WorldRenderer"] = wr;
            context.RegisterObject(this, "Internal", false);
            context.RegisterType(typeof(WVec), "WVec", true);
            context.RegisterType(typeof(CVec), "CVec", true);
            context.RegisterType(typeof(WPos), "WPos", true);
            context.RegisterType(typeof(CPos), "CPos", true);
            context.RegisterType(typeof(WRot), "WRot", true);
            context.RegisterType(typeof(WAngle), "WAngle", true);
            context.RegisterType(typeof(WRange), "WRange", true);
            context.RegisterType(typeof(int2), "int2", true);
            context.RegisterType(typeof(float2), "float2", true);

            var sharedScripts = Game.modData.Manifest.LuaScripts ?? new string[0];

            if (sharedScripts.Any())
            {
                context.LoadLuaScripts(f => GlobalFileSystem.Open(f).ReadAllText(), sharedScripts);
            }

            AddMapActorGlobals();

            context.LoadLuaScripts(f => w.Map.Container.GetContent(f).ReadAllText(), info.LuaScripts);

            context.InvokeLuaFunction("WorldLoaded");
        }
Beispiel #10
0
        public void Reload()
        {
            if (!GlobalFileSystem.Exists(Filename))
            {
                return;
            }

            Exists = true;
            Length = (int)AudLoader.SoundLength(GlobalFileSystem.Open(Filename));
        }
Beispiel #11
0
        public void Load(string filename)
        {
            if (filename == cachedVideo)
            {
                return;
            }
            var video = new VqaReader(GlobalFileSystem.Open(filename));

            cachedVideo = filename;
            Open(video);
        }
Beispiel #12
0
        Voxel LoadFile(Pair <string, string> files)
        {
            VxlReader vxl;
            HvaReader hva;

            using (var s = GlobalFileSystem.Open(files.First + ".vxl"))
                vxl = new VxlReader(s);
            using (var s = GlobalFileSystem.Open(files.Second + ".hva"))
                hva = new HvaReader(s);
            return(new Voxel(this, vxl, hva));
        }
Beispiel #13
0
        public static List <MiniYamlNode> FromFileInPackage(string path)
        {
            var lines = new List <string>();

            using (var stream = GlobalFileSystem.Open(path))
                using (var reader = new StreamReader(stream))
                    while (!reader.EndOfStream)
                    {
                        lines.Add(reader.ReadLine());
                    }
            return(FromLines(lines.ToArray(), path));
        }
Beispiel #14
0
        public void Load(string filename)
        {
            if (filename == cachedVideo)
            {
                return;
            }

            stopped = true;
            paused  = true;
            Sound.StopVideo();
            onComplete = () => { };

            cachedVideo = filename;
            video       = new VqaReader(GlobalFileSystem.Open(filename));

            invLength = video.Framerate * 1f / video.Frames;

            var size        = Math.Max(video.Width, video.Height);
            var textureSize = Exts.NextPowerOf2(size);
            var videoSheet  = new Sheet(new Size(textureSize, textureSize), false);

            videoSheet.Texture.ScaleFilter = TextureScaleFilter.Linear;
            videoSheet.Texture.SetData(video.FrameData);
            videoSprite = new Sprite(videoSheet, new Rectangle(0, 0, video.Width, video.Height), TextureChannel.Alpha);

            var scale = Math.Min(RenderBounds.Width / video.Width, RenderBounds.Height / (video.Height * AspectRatio));

            videoOrigin = new float2(RenderBounds.X + (RenderBounds.Width - scale * video.Width) / 2, RenderBounds.Y + (RenderBounds.Height - scale * AspectRatio * video.Height) / 2);

            // Round size to integer pixels. Round up to be consistent with the scale calcuation.
            videoSize = new float2((int)Math.Ceiling(video.Width * scale), (int)Math.Ceiling(video.Height * scale * AspectRatio));

            if (!DrawOverlay)
            {
                return;
            }

            var scaledHeight = (int)videoSize.Y;

            overlay = new uint[Exts.NextPowerOf2(scaledHeight), 1];
            var black = (uint)255 << 24;

            for (var y = 0; y < scaledHeight; y += 2)
            {
                overlay[y, 0] = black;
            }

            var overlaySheet = new Sheet(new Size(1, Exts.NextPowerOf2(scaledHeight)), false);

            overlaySheet.Texture.SetData(overlay);
            overlaySprite = new Sprite(overlaySheet, new Rectangle(0, 0, 1, scaledHeight), TextureChannel.Alpha);
        }
Beispiel #15
0
        public static List <MiniYamlNode> FromFileInPackage(string path)
        {
            StreamReader  reader = new StreamReader(GlobalFileSystem.Open(path));
            List <string> lines  = new List <string>();

            while (!reader.EndOfStream)
            {
                lines.Add(reader.ReadLine());
            }
            reader.Close();

            return(FromLines(lines.ToArray(), path));
        }
Beispiel #16
0
        public Sheet(string filename)
        {
            using (var stream = GlobalFileSystem.Open(filename))
                using (var bitmap = (Bitmap)Image.FromStream(stream))
                {
                    Size = bitmap.Size;
                    data = new byte[4 * Size.Width * Size.Height];

                    Util.FastCopyIntoSprite(new Sprite(this, bitmap.Bounds(), TextureChannel.Red), bitmap);
                }

            ReleaseBuffer();
        }
Beispiel #17
0
        public void Load(string filename)
        {
            if (filename == cachedVideo)
            {
                return;
            }

            stopped = true;
            paused  = true;
            Sound.StopVideo();
            onComplete = () => { };

            cachedVideo = filename;
            video       = new VqaReader(GlobalFileSystem.Open(filename));

            invLength = video.Framerate * 1f / video.Frames;

            var size        = Math.Max(video.Width, video.Height);
            var textureSize = Exts.NextPowerOf2(size);
            var videoSheet  = new Sheet(new Size(textureSize, textureSize), false);

            videoSheet.Texture.SetData(video.FrameData);
            videoSprite = new Sprite(videoSheet, new Rectangle(0, 0, video.Width, video.Height), TextureChannel.Alpha);

            var scale = Math.Min(RenderBounds.Width / video.Width, RenderBounds.Height / video.Height);

            videoOrigin = new float2(RenderBounds.X + (RenderBounds.Width - scale * video.Width) / 2, RenderBounds.Y + (RenderBounds.Height - scale * video.Height) / 2);
            videoSize   = new float2(video.Width * scale, video.Height * scale);

            if (!DrawOverlay)
            {
                return;
            }

            overlay = new uint[2 * textureSize, 2 * textureSize];
            var 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;
                }
            }

            var overlaySheet = new Sheet(new Size(2 * textureSize, 2 * textureSize), false);

            overlaySheet.Texture.SetData(overlay);
            overlaySprite = new Sprite(overlaySheet, new Rectangle(0, 0, video.Width, 2 * video.Height), TextureChannel.Alpha);
        }
Beispiel #18
0
		public void Load()
		{
			if (!GlobalFileSystem.Exists(Filename))
				return;

			Exists = true;
			using (var s = GlobalFileSystem.Open(Filename))
			{
				if (Filename.ToLowerInvariant().EndsWith("wav"))
					Length = (int)WavLoader.WaveLength(s);
				else
					Length = (int)AudLoader.SoundLength(s);
			}
		}
Beispiel #19
0
        static ISoundSource LoadSound(string filename)
        {
            if (!GlobalFileSystem.Exists(filename))
            {
                Log.Write("sound", "LoadSound, file does not exist: {0}", filename);
                return(null);
            }

            if (filename.ToLowerInvariant().EndsWith("wav"))
            {
                return(LoadWave(new WavLoader(GlobalFileSystem.Open(filename))));
            }

            return(LoadSoundRaw(AudLoader.LoadSound(GlobalFileSystem.Open(filename))));
        }
Beispiel #20
0
        // TODO: The package should be mounted into its own context to avoid name collisions with installed files
        public static bool ExtractFromPackage(string srcPath, string package, string annotation, Dictionary <string, string[]> filesByDirectory,
                                              string destPath, bool overwrite, Action <string> onProgress, Action <string> onError)
        {
            if (!Directory.Exists(destPath))
            {
                Directory.CreateDirectory(destPath);
            }

            Log.Write("debug", "Mounting {0}".F(srcPath));
            GlobalFileSystem.Mount(srcPath);
            Log.Write("debug", "Mounting {0}".F(package));
            GlobalFileSystem.Mount(package, annotation);

            foreach (var directory in filesByDirectory)
            {
                var targetDir = directory.Key;

                foreach (var file in directory.Value)
                {
                    var containingDir = Path.Combine(destPath, targetDir);
                    var dest          = Path.Combine(containingDir, file.ToLowerInvariant());
                    if (File.Exists(dest))
                    {
                        if (overwrite)
                        {
                            File.Delete(dest);
                        }
                        else
                        {
                            Log.Write("debug", "Skipping {0}".F(dest));
                            continue;
                        }
                    }

                    Directory.CreateDirectory(containingDir);

                    using (var sourceStream = GlobalFileSystem.Open(file))
                        using (var destStream = File.Create(dest))
                        {
                            Log.Write("debug", "Extracting {0} to {1}".F(file, dest));
                            onProgress("Extracting " + file);
                            destStream.Write(sourceStream.ReadAllBytes());
                        }
                }
            }

            return(true);
        }
Beispiel #21
0
        public bool PlayMovieInRadar(string movie, LuaFunction playComplete = null)
        {
            if (playComplete != null)
            {
                var f = playComplete.CopyReference() as LuaFunction;
                onCompleteRadar = () =>
                {
                    try
                    {
                        using (f)
                            f.Call().Dispose();
                    }
                    catch (LuaException e)
                    {
                        Context.FatalError(e.Message);
                    }
                };
            }
            else
            {
                onCompleteRadar = () => { }
            };

            Stream s = null;

            try
            {
                s = GlobalFileSystem.Open(movie);
            }
            catch (FileNotFoundException e)
            {
                Log.Write("lua", "Couldn't play movie {0}! File doesn't exist.", e.FileName);
                onCompleteRadar();
                return(false);
            }

            AsyncLoader  l  = new AsyncLoader(Media.LoadVqa);
            IAsyncResult ar = l.BeginInvoke(s, null, null);

            onLoadComplete = () =>
            {
                Media.StopFMVInRadar();
                world.AddFrameEndTask(_ => Media.PlayFMVInRadar(world, l.EndInvoke(ar), onCompleteRadar));
            };

            world.AddFrameEndTask(w => w.Add(new AsyncAction(ar, onLoadComplete)));
            return(true);
        }
Beispiel #22
0
        public MusicInfo(string key, MiniYaml value)
        {
            Title = value.Value;

            var nd  = value.NodesDict;
            var ext = nd.ContainsKey("Extension") ? nd["Extension"].Value : "aud";

            Filename = (nd.ContainsKey("Filename") ? nd["Filename"].Value : key) + "." + ext;
            if (!GlobalFileSystem.Exists(Filename))
            {
                return;
            }

            Exists = true;
            Length = (int)AudLoader.SoundLength(GlobalFileSystem.Open(Filename));
        }
Beispiel #23
0
        public static ISpriteFrame[] GetFrames(string filename, ISpriteLoader[] loaders)
        {
            using (var stream = GlobalFileSystem.Open(filename))
            {
                ISpriteFrame[] frames;
                foreach (var loader in loaders)
                {
                    if (loader.TryParseSprite(stream, out frames))
                    {
                        return(frames);
                    }
                }

                throw new InvalidDataException(filename + " is not a valid sprite file");
            }
        }
Beispiel #24
0
        public void Run(ModData modData, string[] args)
        {
            var files = args.Skip(1);

            GlobalFileSystem.LoadFromManifest(modData.Manifest);

            foreach (var f in files)
            {
                var src = GlobalFileSystem.Open(f);
                if (src == null)
                {
                    throw new InvalidOperationException("File not found: {0}".F(f));
                }
                var data = src.ReadAllBytes();
                File.WriteAllBytes(f, data);
                Console.WriteLine(f + " saved.");
            }
        }
Beispiel #25
0
        public static ActorTemplate RenderActor(ActorInfo info, SequenceProvider sequenceProvider, TileSet tileset, IPalette p, string race)
        {
            var image = info.Traits.Get <ILegacyEditorRenderInfo>().EditorImage(info, sequenceProvider, race);

            image = ResolveFilename(image, tileset);
            using (var s = GlobalFileSystem.Open(image))
            {
                var shp    = new ShpTDSprite(s);
                var bitmap = RenderShp(shp, p);

                return(new ActorTemplate
                {
                    Bitmap = bitmap,
                    Info = info,
                    Appearance = info.Traits.GetOrDefault <EditorAppearanceInfo>()
                });
            }
        }
Beispiel #26
0
        public static void ExtractFiles(string[] args)
        {
            var mod   = args[1];
            var files = args.Skip(2);

            var manifest = new Manifest(mod);

            GlobalFileSystem.LoadFromManifest(manifest);

            foreach (var f in files)
            {
                var src = GlobalFileSystem.Open(f);
                if (src == null)
                {
                    throw new InvalidOperationException("File not found: {0}".F(f));
                }
                var data = src.ReadAllBytes();
                File.WriteAllBytes(f, data);
                Console.WriteLine(f + " saved.");
            }
        }
Beispiel #27
0
        public Sheet(string filename)
        {
            using (var stream = GlobalFileSystem.Open(filename))
                using (var bitmap = (Bitmap)Image.FromStream(stream))
                {
                    Size = bitmap.Size;

                    var dataStride = 4 * Size.Width;
                    data = new byte[dataStride * Size.Height];

                    var bd = bitmap.LockBits(bitmap.Bounds(),
                                             ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                    for (var y = 0; y < Size.Height; y++)
                    {
                        Marshal.Copy(IntPtr.Add(bd.Scan0, y * bd.Stride), data, y * dataStride, dataStride);
                    }
                    bitmap.UnlockBits(bd);
                }

            ReleaseBuffer();
        }
        public void InitPalette(WorldRenderer wr)
        {
            var colors = new uint[256];

            using (var s = GlobalFileSystem.Open(info.Filename))
            {
                s.Seek(info.Offset, SeekOrigin.Begin);

                for (var i = 0; i < 256; i++)
                {
                    var packed = s.ReadUInt16();
                    colors[i] = (uint)((255 << 24) | ((packed & 0xF800) << 8) | ((packed & 0x7E0) << 5) | ((packed & 0x1f) << 3));

                    if (info.InvertColor)
                    {
                        colors[i] ^= 0x00FFFFFF;
                    }
                }
            }

            wr.AddPalette(info.Name, new Palette(colors), info.AllowModifiers);
        }
Beispiel #29
0
        public CursorProvider(ModData modData)
        {
            var sequenceFiles = modData.Manifest.Cursors;
            var sequences     = new MiniYaml(null, sequenceFiles.Select(s => MiniYaml.FromFile(s)).Aggregate(MiniYaml.MergeLiberal));
            var shadowIndex   = new int[] { };

            var nodesDict = sequences.ToDictionary();

            if (nodesDict.ContainsKey("ShadowIndex"))
            {
                Array.Resize(ref shadowIndex, shadowIndex.Length + 1);
                Exts.TryParseIntegerInvariant(nodesDict["ShadowIndex"].Value,
                                              out shadowIndex[shadowIndex.Length - 1]);
            }

            var palettes = new Dictionary <string, ImmutablePalette>();

            foreach (var p in nodesDict["Palettes"].Nodes)
            {
                palettes.Add(p.Key, new ImmutablePalette(GlobalFileSystem.Open(p.Value.Value), shadowIndex));
            }

            Palettes = palettes.AsReadOnly();

            var frameCache = new FrameCache(modData.SpriteLoaders);
            var cursors    = new Dictionary <string, CursorSequence>();

            foreach (var s in nodesDict["Cursors"].Nodes)
            {
                foreach (var sequence in s.Value.Nodes)
                {
                    cursors.Add(sequence.Key, new CursorSequence(frameCache, sequence.Key, s.Key, s.Value.Value, sequence.Value));
                }
            }

            Cursors = cursors.AsReadOnly();
        }
Beispiel #30
0
        public void LoadPalettes(WorldRenderer wr)
        {
            var colors = new uint[Palette.Size];

            using (var s = GlobalFileSystem.Open(info.Filename))
            {
                s.Seek(info.Offset, SeekOrigin.Begin);

                for (var i = 0; i < Palette.Size; i++)
                {
                    var packed = s.ReadUInt16();

                    // Fog is rendered with half opacity
                    colors[i] = (uint)((255 << 24) | ((packed & 0xF800) << 7) | ((packed & 0x7E0) << 4) | ((packed & 0x1f) << 2));

                    if (info.InvertColor)
                    {
                        colors[i] ^= 0x00FFFFFF;
                    }
                }
            }

            wr.AddPalette(info.Name, new ImmutablePalette(colors), info.AllowModifiers);
        }