smodusermc's picture
download
raw
6.8 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>FEZ - Web</title>
<link rel="icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%23000'/%3E%3Cpath fill='%23f0c040' d='M7 7h18v5H13v4h10v5H13v4H7z'/%3E%3C/svg%3E" />
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 100%; height: 100%; overflow: hidden; background: #000; }
#status {
position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
color: #fff; font-family: monospace; font-size: 14px; text-align: center;
z-index: 10;
}
#status.hidden { display: none; }
#progress-bar {
width: 300px; height: 6px; background: #333; border-radius: 3px;
margin: 12px auto; overflow: hidden;
}
#progress-fill {
width: 0%; height: 100%; background: #f0c040; transition: width 0.2s;
}
#detail {
margin-top: 8px; color: #888; font-size: 11px;
}
canvas {
display: block; width: 100vw; height: 100vh;
image-rendering: pixelated;
}
</style>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-PXHK7Q7G3Z"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "G-PXHK7Q7G3Z");
</script>
</head>
<body>
<div id="status">
<div id="status-text">Loading...</div>
<div id="progress-bar"><div id="progress-fill"></div></div>
<div id="detail"></div>
</div>
<canvas id="canvas" class="canvas" tabindex="0"></canvas>
<script type="module">
// keep browser from stealing fucking game keys mid game
const GAME_KEYS = new Set(['Tab', 'Escape', 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', ' ']);
window.addEventListener('keydown', e => {
if (GAME_KEYS.has(e.key)) e.preventDefault();
});
window.addEventListener('keyup', e => {
if (GAME_KEYS.has(e.key)) e.preventDefault();
});
const statusEl = document.getElementById('status');
const statusText = document.getElementById('status-text');
const progressFill = document.getElementById('progress-fill');
const detailEl = document.getElementById('detail');
const canvas = document.getElementById('canvas');
canvas.focus();
function setStatus(msg, pct, detail) {
statusEl.classList.remove('hidden');
statusText.textContent = msg;
if (pct !== undefined) progressFill.style.width = pct + '%';
detailEl.textContent = detail || '';
}
function formatSize(bytes) {
if (bytes >= 1048576) return (bytes / 1048576).toFixed(1) + ' MB';
if (bytes >= 1024) return (bytes / 1024).toFixed(0) + ' KB';
return bytes + ' B';
}
const CONTENT_FILES = [
{ url: 'content/Essentials.pak', dest: '/Content/Essentials.pak', size: 17825792 },
{ url: 'content/Updates.pak', dest: '/Content/Updates.pak', size: 1036288 },
{ url: 'content/Sounds/SoundLevels.sdl', dest: '/Content/Sounds/SoundLevels.sdl', size: 25600 },
{ url: 'content/Other.pak', dest: '/Content/Other.pak', size: 167772160 },
{ url: 'content/Music.pak', dest: '/Content/Music.pak', size: 203423744 },
{ url: 'content/gamecontrollerdb.txt', dest: '/gamecontrollerdb.txt', size: 41984 },
];
const TOTAL_SIZE = CONTENT_FILES.reduce((s, f) => s + f.size, 0);
async function run() {
try {
setStatus('Loading .NET runtime...', 2);
const wasm = await eval('import("./_framework/dotnet.js")');
const dotnet = wasm.dotnet;
setStatus('Initializing runtime...', 8);
const runtime = await dotnet
.withModuleConfig({ canvas })
.create();
const config = runtime.getConfig();
const exports = await runtime.getAssemblyExports(config.mainAssemblyName);
const api = exports.FezGame.Program;
await runtime.runMain();
setStatus('Setting up filesystem...', 12);
await api.PreInit(window.location.origin + window.location.pathname.replace(/\/[^/]*$/, '/'));
let downloaded = 0;
for (let i = 0; i < CONTENT_FILES.length; i++) {
const f = CONTENT_FILES[i];
const baseName = f.url.split('/').pop();
const pct = 15 + Math.round((downloaded / TOTAL_SIZE) * 70);
setStatus(
`Downloading game content (${i + 1}/${CONTENT_FILES.length})...`,
pct,
`${baseName} — ${formatSize(f.size)}`
);
await api.DownloadContentFile(f.url, f.dest);
downloaded += f.size;
}
setStatus('Content loaded!', 88);
setStatus('Initializing game...', 90);
await api.Init(canvas.width || 1280, canvas.height || 720);
setStatus('Starting FEZ...', 98);
statusEl.classList.add('hidden');
canvas.focus();
console.log('[FEZ] Starting game loop via requestAnimationFrame');
const mainLoop = async () => {
try {
const keepRunning = await api.MainLoop();
if (keepRunning) {
requestAnimationFrame(mainLoop);
} else {
console.log('[FEZ] Game requested exit');
await api.Cleanup();
}
} catch (e) {
console.error('[FEZ] MainLoop error:', e);
setStatus('Error: ' + e.message, 0, 'Check browser console (F12) for details.');
}
};
requestAnimationFrame(mainLoop);
} catch (e) {
console.error('Fatal error:', e);
setStatus('Error: ' + e.message, 0, 'Check browser console (F12) for details.');
}
}
run();
</script>
</body>
</html>

Xet Storage Details

Size:
6.8 kB
·
Xet hash:
61072012f19e1f858d8fda0460e24952f918230c44f742a46e8b45ac57a15b6e

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.