namespace XFESystem.Branding; /// Allocation-free, integer-only boot artwork. No fonts, text, OS or runtime APIs. public static unsafe class BootVisual { public const int IntroMilliseconds = 2400; public const uint Cyan = 0x20C9FF; public static bool ShouldRelease(ulong elapsedMilliseconds, bool applicationReady) => applicationReady && elapsedMilliseconds >= IntroMilliseconds; public static bool IsWaiting(ulong elapsedMilliseconds, bool applicationReady) => !applicationReady && elapsedMilliseconds >= IntroMilliseconds; public static int LogoSize(int width, int height) { int value = (width < height ? width : height) / 5; return value < 80 ? 80 : value > 288 ? 288 : value; } public static int CenterY(int height) => height * 42 / 100; public static int LoaderY(int width, int height) => CenterY(height) + LogoSize(width, height) / 2 + LogoSize(width, height) / 12 * 20 / 12 + 62; /// Caller owns the mapped extent; only the central animation region is updated. public static void Draw(uint* pixels, int width, int height, int stride, ulong milliseconds, bool waiting, int redShift = 16, int greenShift = 8, int blueShift = 0) { if (pixels == null || width < 320 || height < 240 || width > 16384 || height > 16384 || stride < width) return; int size = LogoSize(width, height), cx = width / 2, cy = CenterY(height); int top = cy - size - 12, bottom = LoaderY(width, height) + 32; for (int y = top < 0 ? 0 : top; y < bottom && y < height; y++) for (int x = cx - size - 12; x <= cx + size + 12; x++) if (x >= 0 && x < width) pixels[y * stride + x] = 0; int age = milliseconds > IntroMilliseconds ? IntroMilliseconds : (int)milliseconds; if (age < 160) return; int opacity = Ease((age - 160) * 255 / 950); int reveal = (age - 160) * 55 / 850; int drawnSize = size * (920 + 80 * opacity / 255) / 1000; int left = cx - drawnSize / 2, logoTop = cy - drawnSize / 2; fixed (char* data = BootLogoData.Pixels) { for (int y = 0; y < drawnSize; y++) for (int x = 0; x < drawnSize; x++) { int sx = x * 64 / drawnSize, sy = y * 64 / drawnSize; int dx = sx - 32, dy = sy - 32; if (reveal < 48 && dx * dx + dy * dy > reveal * reveal) continue; int at = (sy * 64 + sx) * 2; uint rgb565 = data[at]; int alpha = (data[at + 1] - 32) * opacity / 255; if (alpha <= 0) continue; uint rgb = ((rgb565 >> 11) * 255 / 31 << 16) | (((rgb565 >> 5) & 63) * 255 / 63 << 8) | ((rgb565 & 31) * 255 / 31); int scan = (age - 950) * 140 / 850 - 50; int band = sx + sy - scan; if (age > 950 && age < 1850 && band > -5 && band < 5) rgb = Blend(rgb, 0xD7F8FF, (uint)((5 - (band < 0 ? -band : band)) * 24)); Put(pixels, width, height, stride, left + x, logoTop + y, Dim(rgb, alpha), redShift, greenShift, blueShift); } } // The only typography during loading is the product's requested wordmark. int cell = size / 12, markHeight = cell * 20 / 12, gap = size / 70; if (gap < 1) gap = 1; int markWidth = 9 * cell + 8 * gap, markLeft = cx - markWidth / 2, markTop = cy + size / 2 + 20; int markOpacity = Ease((age - 700) * 255 / 900); fixed (char* mark = BootLogoData.Wordmark) for (int glyph = 0; glyph < 9; glyph++) for (int y = 0; y < markHeight; y++) for (int x = 0; x < cell; x++) { int alpha = (mark[glyph * 240 + y * 20 / markHeight * 12 + x * 12 / cell] - 32) * markOpacity / 255; if (alpha != 0) Put(pixels, width, height, stride, markLeft + glyph * (cell + gap) + x, markTop + y, Dim(0xDBF2FF, alpha), redShift, greenShift, blueShift); } if (age < 2000) { int fade = age < 600 ? (age - 160) * 180 / 440 : (2000 - age) * 180 / 1400; if (fade > 180) fade = 180; int phase = (int)(milliseconds % 1400) * 256 / 1400; Arc(pixels, width, height, stride, cx, cy, size * 3 / 4, phase, 120, Dim(Cyan, fade), redShift, greenShift, blueShift); Arc(pixels, width, height, stride, cx, cy, size * 3 / 4 + 5, phase + 138, 20, Dim(Cyan, fade / 3), redShift, greenShift, blueShift); } if (!waiting) return; int ly = LoaderY(width, height), radius = size / 10; if (radius < 12) radius = 12; int turn = (int)(milliseconds % 1200) * 256 / 1200; for (int tick = 0; tick < 12; tick++) { int phase = tick * 256 / 12; int distance = ((int)(milliseconds / 75) - tick + 12000) % 12; int light = distance < 5 ? 255 - distance * 43 : 25; int x1 = cx + Cos(phase) * (radius - 3) / 1024, y1 = ly + Sin(phase) * (radius - 3) / 1024; int x2 = cx + Cos(phase) * radius / 1024, y2 = ly + Sin(phase) * radius / 1024; Line(pixels, width, height, stride, x1, y1, x2, y2, Dim(distance == 0 ? 0xC4F4FF : Cyan, light), redShift, greenShift, blueShift); } Arc(pixels, width, height, stride, cx, ly, radius + 6, -turn, 42, Dim(Cyan, 130), redShift, greenShift, blueShift); Arc(pixels, width, height, stride, cx, ly, radius + 6, -turn + 128, 12, Dim(Cyan, 55), redShift, greenShift, blueShift); Put(pixels, width, height, stride, cx, ly, Dim(Cyan, 120 + Sin(turn) * 50 / 1024), redShift, greenShift, blueShift); } private static int Ease(int value) { if (value < 0) return 0; if (value > 255) return 255; return value * value * (765 - 2 * value) / 65025; } private static uint Dim(uint rgb, int light) { if (light < 0) light = 0; if (light > 255) light = 255; return ((rgb >> 16) * (uint)light / 255 << 16) | (((rgb >> 8) & 255) * (uint)light / 255 << 8) | ((rgb & 255) * (uint)light / 255); } private static uint Blend(uint a, uint b, uint amount) => (((a >> 16) * (255 - amount) + (b >> 16) * amount) / 255 << 16) | ((((a >> 8) & 255) * (255 - amount) + ((b >> 8) & 255) * amount) / 255 << 8) | (((a & 255) * (255 - amount) + (b & 255) * amount) / 255); private static int Sin(int phase) { phase &= 255; int index = phase & 63; int value = BootLogoData.QuarterSine[(phase & 64) == 0 ? index : 64 - index]; return (phase & 128) == 0 ? value : -value; } private static int Cos(int phase) => Sin(phase + 64); private static void Put(uint* pixels, int width, int height, int stride, int x, int y, uint rgb, int r, int g, int b) { if (x >= 0 && y >= 0 && x < width && y < height) pixels[y * stride + x] = ((rgb >> 16) << r) | (((rgb >> 8) & 255) << g) | ((rgb & 255) << b); } private static void Arc(uint* pixels, int width, int height, int stride, int cx, int cy, int radius, int start, int length, uint rgb, int r, int g, int b) { for (int phase = start; phase < start + length; phase++) Line(pixels, width, height, stride, cx + Cos(phase) * radius / 1024, cy + Sin(phase) * radius / 1024, cx + Cos(phase + 1) * radius / 1024, cy + Sin(phase + 1) * radius / 1024, rgb, r, g, b); } private static void Line(uint* pixels, int width, int height, int stride, int x, int y, int endX, int endY, uint rgb, int r, int g, int b) { int dx = endX - x; if (dx < 0) dx = -dx; int dy = endY - y; if (dy > 0) dy = -dy; int sx = x < endX ? 1 : -1, sy = y < endY ? 1 : -1, error = dx + dy; for (;;) { Put(pixels, width, height, stride, x, y, rgb, r, g, b); if (x == endX && y == endY) return; int twice = 2 * error; if (twice >= dy) { error += dy; x += sx; } if (twice <= dx) { error += dx; y += sy; } } } }