diff --git a/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj b/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj index 51b52c10f7..d6995c8f27 100644 --- a/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj +++ b/OpenRA.Mods.D2k/OpenRA.Mods.D2k.csproj @@ -74,8 +74,7 @@ - - + diff --git a/OpenRA.Mods.D2k/SpriteLoaders/R8Loader.cs b/OpenRA.Mods.D2k/SpriteLoaders/R8Loader.cs index 9bd8e69c2d..c363b0f7fa 100644 --- a/OpenRA.Mods.D2k/SpriteLoaders/R8Loader.cs +++ b/OpenRA.Mods.D2k/SpriteLoaders/R8Loader.cs @@ -12,7 +12,9 @@ using System.Collections.Generic; using System.Drawing; using System.IO; +using System.Linq; using OpenRA.Graphics; +using OpenRA.Mods.Common.Graphics; using OpenRA.Primitives; namespace OpenRA.Mods.D2k.SpriteLoaders @@ -27,6 +29,8 @@ namespace OpenRA.Mods.D2k.SpriteLoaders public byte[] Data { get; set; } public bool DisableExportPadding { get { return true; } } + public readonly uint[] Palette = null; + public R8Frame(Stream s) { // Scan forward until we find some data @@ -58,9 +62,20 @@ namespace OpenRA.Mods.D2k.SpriteLoaders Data = s.ReadBytes(width * height); - // Ignore palette + // Read palette if (type == 1 && paletteOffset != 0) - s.Seek(520, SeekOrigin.Current); + { + // Skip header + s.ReadUInt32(); + s.ReadUInt32(); + + Palette = new uint[256]; + for (var i = 0; i < 256; i++) + { + var packed = s.ReadUInt16(); + Palette[i] = (uint)((255 << 24) | ((packed & 0xF800) << 8) | ((packed & 0x7E0) << 5) | ((packed & 0x1f) << 3)); + } + } } } @@ -94,11 +109,21 @@ namespace OpenRA.Mods.D2k.SpriteLoaders var start = s.Position; var tmp = new List(); + var palettes = new Dictionary(); while (s.Position < s.Length) - tmp.Add(new R8Frame(s)); + { + var f = new R8Frame(s); + if (f.Palette != null) + palettes.Add(tmp.Count, f.Palette); + tmp.Add(f); + } + s.Position = start; frames = tmp.ToArray(); + if (palettes.Any()) + metadata = new TypeDictionary { new EmbeddedSpritePalette(framePalettes: palettes) }; + return true; } } diff --git a/OpenRA.Mods.D2k/Traits/World/D2kFogPalette.cs b/OpenRA.Mods.D2k/Traits/World/D2kFogPalette.cs new file mode 100644 index 0000000000..f1331338f4 --- /dev/null +++ b/OpenRA.Mods.D2k/Traits/World/D2kFogPalette.cs @@ -0,0 +1,54 @@ +#region Copyright & License Information +/* + * Copyright 2007-2018 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. For more + * information, see COPYING. + */ +#endregion + +using System.Collections.Generic; +using OpenRA.Graphics; +using OpenRA.Mods.Common.Traits; +using OpenRA.Traits; + +namespace OpenRA.Mods.D2k.Traits +{ + class D2kFogPaletteInfo : ITraitInfo + { + [FieldLoader.Require, PaletteDefinition] + [Desc("Internal palette name")] + public readonly string Name = null; + + [FieldLoader.Require, PaletteReference] + [Desc("The name of the shroud palette to base off.")] + public readonly string BasePalette = null; + + [Desc("Allow palette modifiers to change the palette.")] + public readonly bool AllowModifiers = true; + + public object Create(ActorInitializer init) { return new D2kFogPalette(this); } + } + + class D2kFogPalette : ILoadsPalettes, IProvidesAssetBrowserPalettes + { + readonly D2kFogPaletteInfo info; + public D2kFogPalette(D2kFogPaletteInfo info) { this.info = info; } + + public void LoadPalettes(WorldRenderer wr) + { + var basePalette = wr.Palette(info.BasePalette).Palette; + + // Bit twiddling is equivalent to unpacking RGB channels, dividing them by 2, subtracting from 255, then repacking + var fog = new uint[Palette.Size]; + for (var i = 0; i < Palette.Size; i++) + fog[i] = ~((basePalette[i] >> 1) & 0x007F7F7F); + + wr.AddPalette(info.Name, new ImmutablePalette(fog), info.AllowModifiers); + } + + public IEnumerable PaletteNames { get { yield return info.Name; } } + } +} diff --git a/OpenRA.Mods.D2k/Traits/World/FogPaletteFromR8.cs b/OpenRA.Mods.D2k/Traits/World/FogPaletteFromR8.cs deleted file mode 100644 index f7ffa687f4..0000000000 --- a/OpenRA.Mods.D2k/Traits/World/FogPaletteFromR8.cs +++ /dev/null @@ -1,68 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2018 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System.Collections.Generic; -using System.IO; -using OpenRA.Graphics; -using OpenRA.Mods.Common.Traits; -using OpenRA.Traits; - -namespace OpenRA.Mods.D2k.Traits -{ - class FogPaletteFromR8Info : ITraitInfo - { - [FieldLoader.Require, PaletteDefinition] - [Desc("Internal palette name")] - public readonly string Name = null; - - [FieldLoader.Require] - [Desc("Filename to load")] - public readonly string Filename = null; - - [Desc("Palette byte offset")] - public readonly long Offset = 0; - - public readonly bool AllowModifiers = true; - public readonly bool InvertColor = false; - - public object Create(ActorInitializer init) { return new FogPaletteFromR8(this); } - } - - class FogPaletteFromR8 : ILoadsPalettes, IProvidesAssetBrowserPalettes - { - readonly FogPaletteFromR8Info info; - public FogPaletteFromR8(FogPaletteFromR8Info info) { this.info = info; } - - public void LoadPalettes(WorldRenderer wr) - { - var colors = new uint[Palette.Size]; - using (var s = wr.World.Map.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); - } - - public IEnumerable PaletteNames { get { yield return info.Name; } } - } -} diff --git a/OpenRA.Mods.D2k/Traits/World/PaletteFromR8.cs b/OpenRA.Mods.D2k/Traits/World/PaletteFromR8.cs deleted file mode 100644 index e22d2cbcaf..0000000000 --- a/OpenRA.Mods.D2k/Traits/World/PaletteFromR8.cs +++ /dev/null @@ -1,66 +0,0 @@ -#region Copyright & License Information -/* - * Copyright 2007-2018 The OpenRA Developers (see AUTHORS) - * This file is part of OpenRA, which is free software. It is made - * available to you under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. For more - * information, see COPYING. - */ -#endregion - -using System.Collections.Generic; -using System.IO; -using OpenRA.Graphics; -using OpenRA.Mods.Common.Traits; -using OpenRA.Traits; - -namespace OpenRA.Mods.D2k.Traits -{ - class PaletteFromR8Info : ITraitInfo - { - [FieldLoader.Require, PaletteDefinition] - [Desc("Internal palette name")] - public readonly string Name = null; - - [FieldLoader.Require] - [Desc("Filename to load")] - public readonly string Filename = null; - - [Desc("Palette byte offset")] - public readonly long Offset = 0; - - public readonly bool AllowModifiers = true; - public readonly bool InvertColor = false; - - public object Create(ActorInitializer init) { return new PaletteFromR8(this); } - } - - class PaletteFromR8 : ILoadsPalettes, IProvidesAssetBrowserPalettes - { - readonly PaletteFromR8Info info; - public PaletteFromR8(PaletteFromR8Info info) { this.info = info; } - - public void LoadPalettes(WorldRenderer wr) - { - var colors = new uint[Palette.Size]; - using (var s = wr.World.Map.Open(info.Filename)) - { - s.Seek(info.Offset, SeekOrigin.Begin); - - for (var i = 0; i < Palette.Size; 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 ImmutablePalette(colors), info.AllowModifiers); - } - - public IEnumerable PaletteNames { get { yield return info.Name; } } - } -} diff --git a/mods/d2k/rules/palettes.yaml b/mods/d2k/rules/palettes.yaml index 4db052a5e6..c75685b093 100644 --- a/mods/d2k/rules/palettes.yaml +++ b/mods/d2k/rules/palettes.yaml @@ -34,11 +34,15 @@ G: 255 B: 255 A: 128 - PaletteFromR8@moveflash: + PaletteFromEmbeddedSpritePalette@moveflash-base: + Name: moveflash-base + Image: moveflsh + Sequence: idle + PaletteFromScaledPalette@moveflash: Name: moveflash - Filename: DATA.R8 - Offset: 2652107 - InvertColor: true + BasePalette: moveflash-base + Scale: -1 + Offset: 255 AllowModifiers: false PaletteFromRGBA@disabled: Name: disabled @@ -59,15 +63,13 @@ BasePalette: d2k AllowModifiers: false Offset: -64 - PaletteFromR8@shroud: + PaletteFromEmbeddedSpritePalette@shroud: Name: shroud - Filename: DATA.R8 - Offset: 12007 - FogPaletteFromR8@fog: + Image: shroud + Sequence: palette + D2kFogPalette@fog: Name: fog - Filename: DATA.R8 - Offset: 12007 - InvertColor: true + BasePalette: shroud PlayerColorPalette: BasePalette: d2k RemapIndex: 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240 diff --git a/mods/d2k/sequences/misc.yaml b/mods/d2k/sequences/misc.yaml index 9e37df881d..d7d7dab5ef 100644 --- a/mods/d2k/sequences/misc.yaml +++ b/mods/d2k/sequences/misc.yaml @@ -438,6 +438,7 @@ moveflsh: Tick: 80 BlendMode: Multiply ZOffset: 2047 + EmbeddedPalette: moveflash resources: spice: BLOXBASE.R8 @@ -450,6 +451,9 @@ shroud: BlendMode: Subtractive Offset: -16,-16 Length: 14 + palette: DATA.R8 + Start: 38 + EmbeddedPalette: shroud shrouda: DATA.R8 Start: 40 shroudb: DATA.R8