1 #region Copyright & License Information 2 /* 3 * Copyright 2007-2020 The OpenRA Developers (see AUTHORS) 4 * This file is part of OpenRA, which is free software. It is made 5 * available to you under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, either version 3 of 7 * the License, or (at your option) any later version. For more 8 * information, see COPYING. 9 */ 10 #endregion 11 12 using System; 13 using System.Collections.Generic; 14 using OpenRA.FileFormats; 15 using OpenRA.FileSystem; 16 using OpenRA.Graphics; 17 using OpenRA.Traits; 18 19 namespace OpenRA.Mods.Common.Traits 20 { 21 [Desc("Load a PNG and use its embedded palette.")] 22 class PaletteFromPngInfo : ITraitInfo, IProvidesCursorPaletteInfo 23 { 24 [PaletteDefinition] 25 [FieldLoader.Require] 26 [Desc("Internal palette name")] 27 public readonly string Name = null; 28 29 [Desc("If defined, load the palette only for this tileset.")] 30 public readonly string Tileset = null; 31 32 [FieldLoader.Require] 33 [Desc("Filename to load")] 34 public readonly string Filename = null; 35 36 [Desc("Map listed indices to shadow. Ignores previous color.")] 37 public readonly int[] ShadowIndex = { }; 38 39 public readonly bool AllowModifiers = true; 40 41 [Desc("Whether this palette is available for cursors.")] 42 public readonly bool CursorPalette = false; 43 Create(ActorInitializer init)44 public object Create(ActorInitializer init) { return new PaletteFromPng(init.World, this); } 45 46 string IProvidesCursorPaletteInfo.Palette { get { return CursorPalette ? Name : null; } } 47 IProvidesCursorPaletteInfo.ReadPalette(IReadOnlyFileSystem fileSystem)48 ImmutablePalette IProvidesCursorPaletteInfo.ReadPalette(IReadOnlyFileSystem fileSystem) 49 { 50 var png = new Png(fileSystem.Open(Filename)); 51 52 if (png.Palette == null) 53 throw new InvalidOperationException("Unable to load palette `{0}` from non-paletted png `{1}`".F(Name, Filename)); 54 55 var colors = new uint[Palette.Size]; 56 57 for (var i = 0; i < png.Palette.Length; i++) 58 colors[i] = (uint)png.Palette[i].ToArgb(); 59 60 return new ImmutablePalette(colors); 61 } 62 } 63 64 class PaletteFromPng : ILoadsPalettes, IProvidesAssetBrowserPalettes 65 { 66 readonly World world; 67 readonly PaletteFromPngInfo info; PaletteFromPng(World world, PaletteFromPngInfo info)68 public PaletteFromPng(World world, PaletteFromPngInfo info) 69 { 70 this.world = world; 71 this.info = info; 72 } 73 LoadPalettes(WorldRenderer wr)74 public void LoadPalettes(WorldRenderer wr) 75 { 76 if (info.Tileset != null && info.Tileset.ToLowerInvariant() != world.Map.Tileset.ToLowerInvariant()) 77 return; 78 79 wr.AddPalette(info.Name, ((IProvidesCursorPaletteInfo)info).ReadPalette(world.Map), info.AllowModifiers); 80 } 81 82 public IEnumerable<string> PaletteNames 83 { 84 get 85 { 86 // Only expose the palette if it is available for the shellmap's tileset (which is a requirement for its use). 87 if (info.Tileset == null || info.Tileset == world.Map.Rules.TileSet.Id) 88 yield return info.Name; 89 } 90 } 91 } 92 } 93