feat: add BlendMath (colorkey match + ARGB unpack)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
34
engine/Age.Engine.Tests/BlendMathTests.cs
Normal file
34
engine/Age.Engine.Tests/BlendMathTests.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using Age.Engine.Model;
|
||||
using Xunit;
|
||||
|
||||
public class BlendMathTests
|
||||
{
|
||||
[Fact]
|
||||
public void NegativeColorKey_IsNoKey()
|
||||
{
|
||||
Assert.False(BlendMath.HasColorKey(-1));
|
||||
Assert.False(BlendMath.ColorKeyMatches(0, 0, 0, -1)); // never matches when no key
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ZeroColorKey_KeysBlack()
|
||||
{
|
||||
Assert.True(BlendMath.HasColorKey(0));
|
||||
Assert.True(BlendMath.ColorKeyMatches(0, 0, 0, 0)); // (0,0,0) == key black
|
||||
Assert.False(BlendMath.ColorKeyMatches(1, 0, 0, 0)); // near-black is NOT keyed (exact match)
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ColorKey_MatchesRgb888Bytes()
|
||||
{
|
||||
long key = 0xFF00FF; // magenta 0xRRGGBB
|
||||
Assert.True(BlendMath.ColorKeyMatches(0xFF, 0x00, 0xFF, key));
|
||||
Assert.False(BlendMath.ColorKeyMatches(0xFE, 0x00, 0xFF, key));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnpackArgb_SplitsBytes()
|
||||
{
|
||||
Assert.Equal((0x80, 0x12, 0x34, 0x56), BlendMath.UnpackArgb(0x80123456));
|
||||
}
|
||||
}
|
||||
22
engine/Age.Engine/Model/BlendMath.cs
Normal file
22
engine/Age.Engine/Model/BlendMath.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
namespace Age.Engine.Model;
|
||||
|
||||
/// <summary>Pure blend helpers shared by the engine resolution and the host blit. Colorkey semantics come
|
||||
/// from the native loader (docs/engine-re.md §"Blend & transparency"): op arg 3 < 0 = no key; otherwise
|
||||
/// the operand is 0xRRGGBB and matching (R,G,B) texels are transparent (operand 0 = key black).</summary>
|
||||
public static class BlendMath
|
||||
{
|
||||
/// <summary>A colorkey operand >= 0 is an active key; a negative operand means "no colorkey".</summary>
|
||||
public static bool HasColorKey(long colorKey) => colorKey >= 0;
|
||||
|
||||
/// <summary>True when (r,g,b) exactly equals the key's 0xRRGGBB bytes. Always false when there is no key.</summary>
|
||||
public static bool ColorKeyMatches(byte r, byte g, byte b, long colorKey)
|
||||
{
|
||||
if (!HasColorKey(colorKey)) return false;
|
||||
return r == ((colorKey >> 16) & 0xff) && g == ((colorKey >> 8) & 0xff) && b == (colorKey & 0xff);
|
||||
}
|
||||
|
||||
/// <summary>Split a 0xAARRGGBB packed color (see GfxState.PackColor) into its byte channels.</summary>
|
||||
public static (int A, int R, int G, int B) UnpackArgb(long packed)
|
||||
=> ((int)((packed >> 24) & 0xff), (int)((packed >> 16) & 0xff),
|
||||
(int)((packed >> 8) & 0xff), (int)(packed & 0xff));
|
||||
}
|
||||
Reference in New Issue
Block a user