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