<!DOCTYPE html><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>@CLIENT_NAME@ Emscripten demo</title>
<style>
html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: rgb(0, 0, 0); display:flex; align-items: center; justify-content: center; }
canvas { max-width: 100%; max-height: 100%; min-width: 100%; min-height: 100%; object-fit: contain; }
</style>

<canvas id=canvas></canvas>

<script type=module>
// These strings are set in the generated HTML file in the build directory.
const CLIENT_NAME = '@CLIENT_NAME@';
const BASEGAME = '@BASEGAME@';
const EMSCRIPTEN_PRELOAD_FILE = '@EMSCRIPTEN_PRELOAD_FILE@' === 'ON';

// Path or URL containing the client engine .js, .wasm, and possibly .data.
let enginePath = './';
// Path or URL containing fs_game directories.
let dataPath = './';
// Path or URL for config file that specifies the files to load for each fs_game.
let configFilename = `./${CLIENT_NAME}-config.json`;

if (window.location.protocol === 'file:') throw new Error(`Unfortunately browser security restrictions prevent loading wasm from a file: URL. This file must be loaded from a web server. The easiest way to do this is probably to use Python\'s built-in web server by running \`python3 -m http.server\` in the top level source directory and then navigate to http://localhost:8000/build/debug-emscripten-wasm32/${CLIENT_NAME}.html`);

// First set up the command line arguments and the Emscripten filesystem.
const urlParams = new URLSearchParams(window.location.search);
const com_basegame = urlParams.get('com_basegame') || BASEGAME;
const fs_basegame = urlParams.get('fs_basegame') || '';
const fs_game = urlParams.get('fs_game') || '';
let generatedArguments = `
    +set sv_pure 0
    +set net_enabled 0
    +set r_mode -2
    +set com_basegame "${com_basegame}"
    +set fs_basegame "${fs_basegame}"
    +set fs_game "${fs_game}"
`;
// Note that unfortunately "+" needs to be encoded as "%2b" in URL query strings or it will be stripped by the browser.
const queryArgs = urlParams.get('args');
if (queryArgs) generatedArguments += ` ${queryArgs} `;

const dataURL = new URL(dataPath, location.origin + location.pathname);

const configPromise = EMSCRIPTEN_PRELOAD_FILE ? Promise.resolve({[BASEGAME]: {files: []}})
  : fetch(configFilename).then(r => r.ok ? r.json() : { /* empty config */ });

const ioquake3 = (await import(enginePath + `@CLIENT_BINARY@.js`)).default;
ioquake3({
    canvas: canvas,
    arguments: generatedArguments.trim().split(/\s+/),
    locateFile: (file) => enginePath + file,
    preRun: [async (module) => {
        module.addRunDependency('setup-ioq3-filesystem');
        try {
            const config = await configPromise;
            const gamedirs = [com_basegame,fs_basegame,fs_game];
            for (let g = 0; g < gamedirs.length; g++) {
                const gamedir = gamedirs[g];
                if (gamedir === '') {
                    continue;
                }
                if (config[gamedir] === null
                 || config[gamedir].files === null) {
                    console.warn(`Game directory '${gamedir}' cannot be used. It must have files listed in ${configFilename}.`);
                    continue;
                }
                const files = config[gamedir].files;
                const fetches = files.map(file => fetch(new URL(file.src, dataURL)));
                for (let i = 0; i < files.length; i++) {
                    const response = await fetches[i];
                    if (!response.ok) continue;
                    const data = await response.arrayBuffer();
                    let name = files[i].src.match(/[^/]+$/)[0];
                    let dir = files[i].dst;
                    module.FS.mkdirTree(dir);
                    module.FS.writeFile(`${dir}/${name}`, new Uint8Array(data));
                }
            }
        } finally {
            module.removeRunDependency('setup-ioq3-filesystem');
        }
    }],
});
</script>
