using System.IO.Compression; using System.Numerics; using System.Security.Cryptography; using System.Text.Json; namespace XFEEDToolBox.Core.Rendering; /// Actual separate BackgroundBlackHole source material and its copied BC1 array. 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; } /// Independent per-channel pixel arithmetic, not the summed BackgroundStars mask. 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 Mips)> source=new(Read); public static ReadOnlyMemory Payload=>source.Value.Payload; public static IReadOnlyList Mips=>source.Value.Mips; private static (byte[],IReadOnlyList) 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>level)+3)/4)*8|| mip.SliceBytes>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)); } }