// App shell: layers in z order - scene canvas (1), halftone (2), CRT (5), // HUD + touch overlay (9-12), BIOS readout (20), dance controls (25), // title menu (30). Also owns the pre-game device detection and title -> enter flow. import { useEffect } from "react"; import GameCanvas from "./scene/GameCanvas.jsx"; import { Halftone, CrtOverlay } from "./ui/Overlays.jsx"; import Hud from "./ui/Hud.jsx"; import TouchOverlay from "./ui/TouchOverlay.jsx"; import BiosOverlay from "./ui/BiosOverlay.jsx"; import TitleMenu from "./ui/TitleMenu.jsx"; import DanceControls from "./ui/DanceControls.jsx"; import { useGame } from "./store.js"; export default function App() { useEffect(() => { const params = new URLSearchParams(location.search); // Gamepad presence for the tutorial variant, before the game controller // takes over polling (the game loop keeps mirroring it afterwards). const pollPad = () => { const gp = [...(navigator.getGamepads?.() ?? [])].find( (p) => p && p.connected, ); useGame.setState({ padConnected: !!gp }); }; window.addEventListener("gamepadconnected", pollPad); window.addEventListener("gamepaddisconnected", pollPad); pollPad(); // Touch detection, latching. const coarse = matchMedia("(pointer: coarse)"); const armTouch = () => { window.__microduckTouched = true; useGame.setState({ touchMode: true }); }; const onCoarse = () => { if (coarse.matches) armTouch(); }; if (coarse.matches) armTouch(); else coarse.addEventListener("change", onCoarse); window.addEventListener("touchstart", armTouch, { once: true, passive: true, }); if (params.get("touch") === "1") armTouch(); // ?boot=1 skips the title entirely - testing hook. if (params.get("boot") === "1") { useGame.setState({ prebootDone: true, entered: true, menuOpen: false, }); } else { useGame.setState({ prebootDone: true, menuOpen: true, }); } return () => { window.removeEventListener("gamepadconnected", pollPad); window.removeEventListener("gamepaddisconnected", pollPad); coarse.removeEventListener("change", onCoarse); window.removeEventListener("touchstart", armTouch); }; }, []); return ( <> {/* N = neck isolation, H = circular neck isolation */} ); }