/** * BIOS Boot Animation * Displays a retro BIOS-style boot sequence before the terminal loads */ const BIOS_LINES = [ { text: 'LitRuv BIOS v4.20.69', class: 'white', delay: 300 }, { text: 'Copyright (C) 2024-2026 LitRuv Industries', class: '', delay: 200 }, { text: '', delay: 400 }, { text: 'CPU: Quantum Core i9-42069 @ 6.9GHz', class: '', delay: 300 }, { text: 'Memory Test: ', class: '', inline: true, delay: 200 }, { text: '65536K OK', class: 'highlight', delay: 600 }, { text: '', delay: 300 }, { text: 'Detecting Primary Master... LitDrive SSD 2TB', class: '', delay: 400 }, { text: 'Detecting Primary Slave... None', class: '', delay: 300 }, { text: '', delay: 400 }, { text: 'Initializing Terminal Interface...', class: 'highlight', delay: 500 }, { text: 'Loading modules: [', class: '', inline: true, delay: 200 }, { text: '████████████████████', class: 'highlight', inline: true, delay: 800 }, { text: '] 100%', class: '', delay: 300 }, { text: '', delay: 200 }, { text: 'Starting LIT.RUV.WTF Terminal...', class: 'highlight', delay: 400 } ]; const BOOT_STARTUP_SOUND_PATH = window.location.hostname.endsWith('neocities.org') ? 'https://lit.ruv.wtf/sounds/551405__nakkivene66__old-pc-startup-idle-shutdown.wav' : 'sounds/551405__nakkivene66__old-pc-startup-idle-shutdown.wav'; let bootStartupSoundPlayed = false; let bootStartupSoundUnlockBound = false; /** * Play the boot startup sound as early as possible. * Falls back to first user interaction when autoplay is blocked. * @returns {Promise} */ async function playBootStartupSound() { if (bootStartupSoundPlayed) { return; } try { const startupSound = new Audio(BOOT_STARTUP_SOUND_PATH); startupSound.preload = 'auto'; startupSound.volume = 0.55; await startupSound.play(); bootStartupSoundPlayed = true; bootStartupSoundUnlockBound = false; return; } catch (error) { if (bootStartupSoundUnlockBound) { return; } bootStartupSoundUnlockBound = true; const unlockAndPlay = async () => { if (bootStartupSoundPlayed) { return; } try { const deferredSound = new Audio(BOOT_STARTUP_SOUND_PATH); deferredSound.preload = 'auto'; deferredSound.volume = 0.55; await deferredSound.play(); bootStartupSoundPlayed = true; } catch (retryError) { // Keep boot sequence running even if sound cannot play. } }; document.addEventListener('pointerdown', unlockAndPlay, { once: true }); document.addEventListener('keydown', unlockAndPlay, { once: true }); } } /** * Run the BIOS boot animation * @returns {Promise} Resolves when animation is complete */ function runBootAnimation() { return new Promise((resolve) => { void playBootStartupSound(); const bootScreen = document.getElementById('bootScreen'); const biosText = document.getElementById('biosText'); const pageFade = document.getElementById('pageFade'); if (!bootScreen || !biosText) { if (pageFade) pageFade.classList.add('fade-out'); resolve(); return; } let skipped = false; const timeouts = []; // Skip animation on space key press const skipHandler = (event) => { if (event.code === 'Space' && !skipped) { event.preventDefault(); skipped = true; // Clear all pending timeouts timeouts.forEach(timeout => clearTimeout(timeout)); // Complete the boot screen immediately bootScreen.classList.add('fade-out'); setTimeout(() => { bootScreen.style.display = 'none'; if (pageFade) pageFade.style.display = 'none'; document.removeEventListener('keydown', skipHandler); resolve(); }, 100); } }; document.addEventListener('keydown', skipHandler); // Start fade in from black after brief delay timeouts.push(setTimeout(() => { if (pageFade && !skipped) pageFade.classList.add('fade-out'); }, 200)); let lineIndex = 0; let totalDelay = 800; // Start after fade begins const baseDelay = 150; BIOS_LINES.forEach((line, index) => { const delay = totalDelay; totalDelay += line.delay || baseDelay; timeouts.push(setTimeout(() => { if (skipped) return; const span = document.createElement('span'); if (line.class) { span.className = line.class; } span.textContent = line.text; biosText.appendChild(span); if (!line.inline) { biosText.appendChild(document.createTextNode('\n')); } }, delay)); }); // Fade out and remove boot screen timeouts.push(setTimeout(() => { if (skipped) return; bootScreen.classList.add('fade-out'); timeouts.push(setTimeout(() => { bootScreen.style.display = 'none'; if (pageFade) pageFade.style.display = 'none'; document.removeEventListener('keydown', skipHandler); resolve(); }, 500)); }, totalDelay + 300)); }); } // Export for use in terminal.js window.runBootAnimation = runBootAnimation;