Skip to content

Commit

Permalink
Fix explosion/smoke rendering.
Browse files Browse the repository at this point in the history
  • Loading branch information
pchote committed Oct 25, 2023
1 parent 675d8c5 commit e0d7dcb
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
54 changes: 52 additions & 2 deletions OpenRA.Mods.Mobius/RemasterSpriteSequence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using OpenRA.Graphics;
Expand Down Expand Up @@ -64,9 +65,13 @@ public class RemasterSpriteSequence : ClassicTilesetSpecificSpriteSequence
[Desc("Adjusts the rendered size of the sprite")]
protected static readonly SpriteSequenceField<float?> RemasteredScale = new(nameof(RemasteredScale), null);

[Desc("Sprite data is already pre-multiplied by alpha channel.")]
protected static readonly SpriteSequenceField<bool> RemasteredPremultiplied = new(nameof(RemasteredPremultiplied), false);

static readonly int[] FirstFrame = { 0 };

bool hasRemasteredSprite = true;
bool premultiplied;

IEnumerable<ReservationInfo> ParseRemasterFilenames(ModData modData, string tileset, int[] frames, MiniYaml data, MiniYaml defaults)
{
Expand Down Expand Up @@ -184,6 +189,7 @@ public override void ReserveSprites(ModData modData, string tileset, SpriteCache
var remasteredOffset = LoadField(RemasteredOffset, data, defaults);
var remasteredMaskFilename = LoadField(RemasteredMaskFilename, data, defaults, out var remasteredMaskFilenameLocation);
var blendMode = LoadField(BlendMode, data, defaults);
premultiplied = LoadField(RemasteredPremultiplied, data, defaults);

if (!string.IsNullOrEmpty(remasteredMaskFilename))
remasteredMaskToken = cache.ReserveFrames(remasteredMaskFilename, null, remasteredMaskFilenameLocation);
Expand All @@ -203,7 +209,7 @@ public override void ReserveSprites(ModData modData, string tileset, SpriteCache
foreach (var f in ParseRemasterCombineFilenames(modData, tileset, subFrames, subData))
{
int token;
if (remasteredMaskToken != null)
if (remasteredMaskToken != null || premultiplied)
token = cache.ReserveFrames(f.Filename, f.LoadFrames, f.Location);
else
token = cache.ReserveSprites(f.Filename, f.LoadFrames, f.Location);
Expand All @@ -226,7 +232,7 @@ public override void ReserveSprites(ModData modData, string tileset, SpriteCache
foreach (var f in ParseRemasterFilenames(modData, tileset, frames, data, defaults))
{
int token;
if (remasteredMaskToken != null)
if (remasteredMaskToken != null || premultiplied)
token = cache.ReserveFrames(f.Filename, f.LoadFrames, f.Location);
else
token = cache.ReserveSprites(f.Filename, f.LoadFrames, f.Location);
Expand Down Expand Up @@ -271,6 +277,9 @@ public override void ResolveSprites(SpriteCache cache)
if (maskFrames.Length != frameLength)
throw new YamlException($"Sequence {image}.{Name} with {frameLength} frames cannot use mask with {maskFrames.Length} frames.");

if (premultiplied)
throw new YamlException($"Sequence {image}.{Name} with {frameLength} frames cannot use mask with premultiplication.");

allSprites = new Sprite[allFrames.Length];
for (var i = 0; i < frameLength; i++)
{
Expand Down Expand Up @@ -310,6 +319,47 @@ public override void ResolveSprites(SpriteCache cache)
allSprites[start + i] = s;
}
}
else if (premultiplied)
{
var allFrames = spritesToLoad.SelectMany<SpriteReservation, (SpriteReservation, ISpriteFrame)>(r =>
{
var resolved = cache.ResolveFrames(r.Token);
if (r.Frames != null)
return r.Frames.Select(f => (r, resolved[f]));
return resolved.Select(f => (r, f));
}).ToArray();

var frameLength = length ?? allFrames.Length - start;
allSprites = new Sprite[allFrames.Length];
for (var i = 0; i < frameLength; i++)
{
(var r, var frame) = allFrames[start + i];

if (frame.Type != SpriteFrameType.Bgra32)
throw new YamlException($"Sequence {image}.{Name} mask frame {i} must be a Bgra32 image (premultiplied=true).");

var s = cache.SheetBuilders[SheetBuilder.FrameTypeToSheetType(frame.Type)]
.Add(frame.Data, frame.Type, frame.Size, 0, frame.Offset, true);

var dx = r.Offset.X + (r.FlipX ? -s.Offset.X : s.Offset.X);
var dy = r.Offset.Y + (r.FlipY ? -s.Offset.Y : s.Offset.Y);
var dz = r.Offset.Z + s.Offset.Z + r.ZRamp * dy;
s = new Sprite(s.Sheet, FlipRectangle(s.Bounds, r.FlipX, r.FlipY), r.ZRamp, new float3(dx, dy, dz), s.Channel, r.BlendMode);

if (depthSprite != null)
{
var cw = (depthSprite.Bounds.Left + depthSprite.Bounds.Right) / 2 + (int)(s.Offset.X + depthSpriteOffset.X);
var ch = (depthSprite.Bounds.Top + depthSprite.Bounds.Bottom) / 2 + (int)(s.Offset.Y + depthSpriteOffset.Y);
var w = s.Bounds.Width / 2;
var h = s.Bounds.Height / 2;

s = new SpriteWithSecondaryData(s, depthSprite.Sheet, Rectangle.FromLTRB(cw - w, ch - h, cw + w, ch + h), depthSprite.Channel);
}

allSprites[start + i] = s;
}
}
else
{
allSprites = spritesToLoad.SelectMany(r =>
Expand Down
2 changes: 1 addition & 1 deletion mod.config
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
MOD_ID="cnc"

# The OpenRA engine version to use for this project.
ENGINE_VERSION="c76bd67384"
ENGINE_VERSION="be5edc44604a3c8946e112016fa5941126e755f0"

##############################################################################
# Packaging
Expand Down
10 changes: 10 additions & 0 deletions mods/cnc/sequences/misc-overrides.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
fb4:
idle:
RemasteredFilename: DATA\ART\TEXTURES\SRGB\TIBERIAN_DAWN\VFX\FB2.ZIP
RemasteredPremultiplied: true

fire:
1:
RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE1.ZIP
RemasteredOffset: 0, -16
RemasteredPremultiplied: true
2:
RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\FIRE2.ZIP
RemasteredOffset: 0, -16
RemasteredPremultiplied: true

burn-l:
Defaults:
RemasteredFilename: DATA\ART\TEXTURES\SRGB\TIBERIAN_DAWN\VFX\BURN-L.ZIP
RemasteredPremultiplied: true

burn-m:
Defaults:
RemasteredFilename: DATA\ART\TEXTURES\SRGB\TIBERIAN_DAWN\VFX\BURN-M.ZIP
RemasteredPremultiplied: true

burn-s:
Defaults:
RemasteredFilename: DATA\ART\TEXTURES\SRGB\TIBERIAN_DAWN\VFX\BURN-S.ZIP
RemasteredPremultiplied: true

120mm:
idle:
Expand All @@ -29,6 +35,7 @@ burn-s:
smoke_m:
Defaults:
RemasteredFilename: DATA\ART\TEXTURES\SRGB\COMMON\VFX\SMOKE_M.ZIP
RemasteredPremultiplied: true
idle:
RemasteredOffset: 11, -27
loop:
Expand All @@ -47,6 +54,7 @@ dragon:
smokey:
idle:
RemasteredFilename: DATA\ART\TEXTURES\SRGB\TIBERIAN_DAWN\VFX\SMOKEY.ZIP
RemasteredPremultiplied: true

bomb:
idle:
Expand All @@ -61,6 +69,8 @@ patriot:
RemasteredFilename: DATA\ART\TEXTURES\SRGB\TIBERIAN_DAWN\VFX\MISSILE.ZIP

explosion:
Defaults:
RemasteredPremultiplied: true
nuke_explosion:
RemasteredFilename: DATA\ART\TEXTURES\SRGB\TIBERIAN_DAWN\VFX\ATOMSFX.ZIP
piff:
Expand Down

0 comments on commit e0d7dcb

Please sign in to comment.