109 lines
3.8 KiB
JavaScript
109 lines
3.8 KiB
JavaScript
const library = document.querySelector('#library');
|
|
const player = document.querySelector('#player');
|
|
const status = document.querySelector('#status');
|
|
const programsElement = document.querySelector('#programs');
|
|
const refreshButton = document.querySelector('#refresh');
|
|
|
|
function titleFromPath(path) {
|
|
const filename = path.split('/').at(-1).replace(/\.prg$/i, '');
|
|
return filename.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
|
}
|
|
|
|
const typeIcons = {
|
|
Arcade: '🎮',
|
|
Logic: '◆',
|
|
Strategy: '♟',
|
|
Simulation: '⚙',
|
|
Memory: '◫',
|
|
Puzzle: '⌘',
|
|
Music: '♪',
|
|
Creative: '✎',
|
|
Demo: '✦'
|
|
};
|
|
|
|
async function loadPrograms() {
|
|
status.hidden = false;
|
|
status.className = 'status';
|
|
status.textContent = 'Loading programs…';
|
|
programsElement.replaceChildren();
|
|
refreshButton.disabled = true;
|
|
try {
|
|
const response = await fetch('/api/programs', { cache: 'no-store' });
|
|
if (!response.ok) throw new Error('The program list could not be loaded.');
|
|
const { programs } = await response.json();
|
|
for (const program of programs) {
|
|
const link = document.createElement('a');
|
|
link.className = 'program-card';
|
|
link.href = `/?program=${encodeURIComponent(program.path)}`;
|
|
|
|
const pill = document.createElement('span');
|
|
pill.className = 'type-pill';
|
|
pill.textContent = `${typeIcons[program.type] || '●'} ${program.type}`;
|
|
|
|
const title = document.createElement('strong');
|
|
title.className = 'program-title';
|
|
title.textContent = program.title;
|
|
|
|
const description = document.createElement('span');
|
|
description.className = 'program-description';
|
|
description.textContent = program.description;
|
|
|
|
const controls = document.createElement('span');
|
|
controls.className = 'controls';
|
|
controls.setAttribute('aria-label', `Controls: ${program.controls.join(', ')}`);
|
|
for (const control of program.controls) {
|
|
const key = document.createElement('kbd');
|
|
key.textContent = control;
|
|
controls.append(key);
|
|
}
|
|
|
|
const action = document.createElement('span');
|
|
action.className = 'program-action';
|
|
action.textContent = 'Run program →';
|
|
link.append(pill, title, description, controls, action);
|
|
programsElement.append(link);
|
|
}
|
|
status.textContent = programs.length ? `${programs.length} programs available` : 'No PRG files found.';
|
|
} catch (error) {
|
|
status.className = 'status error';
|
|
status.textContent = error.message;
|
|
} finally {
|
|
refreshButton.disabled = false;
|
|
}
|
|
}
|
|
|
|
function startEmulator(programPath) {
|
|
library.hidden = true;
|
|
player.hidden = false;
|
|
const title = titleFromPath(programPath);
|
|
document.title = `${title} — C64 BASIC Collection`;
|
|
document.querySelector('#program-title').textContent = title;
|
|
|
|
window.EJS_player = '#game';
|
|
window.EJS_core = 'vice_x64sc';
|
|
window.EJS_gameUrl = `/api/program?path=${encodeURIComponent(programPath)}`;
|
|
window.EJS_gameName = programPath.split('/').at(-1);
|
|
window.EJS_pathtodata = 'https://cdn.emulatorjs.org/stable/data/';
|
|
window.EJS_startOnLoaded = true;
|
|
window.EJS_language = 'en-US';
|
|
window.EJS_defaultOptions = {
|
|
menubarBehavior: 'anywhere',
|
|
keyboardInput: 'enabled',
|
|
lockMouse: 'disabled'
|
|
};
|
|
|
|
const loader = document.createElement('script');
|
|
loader.src = `${window.EJS_pathtodata}loader.js`;
|
|
loader.onerror = () => {
|
|
const message = document.querySelector('#emulator-error');
|
|
message.hidden = false;
|
|
message.textContent = 'The WASM VICE emulator could not be downloaded. Check your connection and try again.';
|
|
};
|
|
document.body.append(loader);
|
|
}
|
|
|
|
refreshButton.addEventListener('click', loadPrograms);
|
|
const programPath = new URLSearchParams(location.search).get('program');
|
|
if (programPath) startEmulator(programPath);
|
|
else loadPrograms();
|
|
|