XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.IO.Compression;
using System.Numerics;
using System.Security.Cryptography;
using System.Text.Json;

namespace XFEEDToolBox.Core.Rendering;

/// <summary>Actual separate BackgroundBlackHole source material and its copied BC1 array.</summary>
public static class GalaxyOriginalBlackHole
{
    public const int Width=512,Height=512,MipCount=10,PayloadBytes=181248;
    public const string PayloadSha256="0d8ddcc7b1a303234a8a4385c6dc3e195c176704dcfbfe40c9ea35e0e6deb18a";
    public const string VertexShaderSha256="fb5c6e57697c6e6620f3ca0166b9cb5b639dcc3ec63198e9911b2627e712943c";
    public const string PixelShaderSha256="30d4e80799f9da2263e12089e1a2d50f99d0445c5c8efedfd937bd5fe68f5b4a";
    // 3AB44E0 overrides this fifth stellar publisher as well as the ordinary four.
    public static Vector4 Material(bool alternateGlow=false)=>alternateGlow?new(1,4,1,0):new(1,2.75f,.17f,1.903f);
    public static bool IsSpecial(ushort classification)=>(classification&63) is 41 or 42;
    // The original param7 is Settings5 (NavigationMarkers), independent of the
    // tool's general icon switch. special itself is forced only in RealisticView0.
    public static bool Enabled(ushort classification,bool realistic,bool navigationMarkers)=>
        realistic&&navigationMarkers&&IsSpecial(classification);
    public static float HalfExtent(float styleSize)
    {
        if(!float.IsFinite(styleSize)||styleSize<=0)return 0;
        var half=(float)(Half)styleSize;return float.IsFinite(half)?half:0;
    }

    /// <summary>Independent per-channel pixel arithmetic, not the summed BackgroundStars mask.</summary>
    public static Vector4 SourcePixel(Vector3 mask,float normalizedRadius,Vector4 material,float hdrWrite)
    {
        var radial=material.Y-normalizedRadius/material.Z+1;
        var gain=radial*material.W+1-Math.Clamp(material.W,0,1);
        var colour=Vector3.Clamp(new(MathF.Pow(Math.Max(0,mask.X),1.2f)*gain,
            MathF.Pow(Math.Max(0,mask.Y),1.2f)*gain,MathF.Pow(Math.Max(0,mask.Z),1.2f)*gain),Vector3.Zero,new(100));
        return new((Vector3.One-colour)*hdrWrite,colour.Length()*(1f/3));
    }

    private static readonly Lazy<(byte[] Payload,IReadOnlyList<GalaxyOriginalSpriteMip> Mips)> source=new(Read);
    public static ReadOnlyMemory<byte> Payload=>source.Value.Payload;
    public static IReadOnlyList<GalaxyOriginalSpriteMip> Mips=>source.Value.Mips;
    private static (byte[],IReadOnlyList<GalaxyOriginalSpriteMip>) Read()
    {
        var assembly=typeof(GalaxyOriginalBlackHole).Assembly;
        using var metadata=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-black-hole.json")!;
        using var json=JsonDocument.Parse(metadata);var root=json.RootElement;
        if(root.GetProperty("width").GetInt32()!=Width||root.GetProperty("height").GetInt32()!=Height||
           root.GetProperty("layers").GetInt32()!=1||root.GetProperty("mipCount").GetInt32()!=MipCount||
           root.GetProperty("payloadSha256").GetString()!=PayloadSha256)throw new InvalidDataException("原黑洞纹理描述无效。");
        using var compressed=assembly.GetManifestResourceStream("XFEEDToolBox.Core.Rendering.original-black-hole.bc1.gz")!;
        using var gzip=new GZipStream(compressed,CompressionMode.Decompress);var data=new byte[PayloadBytes];gzip.ReadExactly(data);
        if(gzip.ReadByte()!=-1||Convert.ToHexStringLower(SHA256.HashData(data))!=PayloadSha256)throw new InvalidDataException("原黑洞纹理字节校验失败。");
        var mips=root.GetProperty("mips").EnumerateArray().Select(m=>new GalaxyOriginalSpriteMip(m.GetProperty("offset").GetInt32(),
            m.GetProperty("sliceBytes").GetInt32(),m.GetProperty("size").GetInt32(),m.GetProperty("rowPitch").GetInt32(),m.GetProperty("depthPitch").GetInt32())).ToArray();
        var end=0;
        for(var level=0;level<mips.Length;level++)
        {
            var mip=mips[level];
            if(mip.Offset!=end||mip.Size!=mip.SliceBytes||mip.RowPitch<Math.Max(1,((Width>>level)+3)/4)*8||
               mip.SliceBytes<mip.RowPitch*Math.Max(1,((Height>>level)+3)/4))throw new InvalidDataException("原黑洞纹理层级布局无效。");
            end=checked(end+mip.Size);
        }
        if(mips.Length!=MipCount||end!=data.Length)throw new InvalidDataException("原黑洞纹理层级数量无效。");
        return(data,Array.AsReadOnly(mips));
    }
}