Skip to content

Commit

Permalink
Browsing games from archive.org
Browse files Browse the repository at this point in the history
  • Loading branch information
gasman committed Aug 14, 2021
1 parent 3cf5e78 commit 51d833e
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions runtime/icons/close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
87 changes: 87 additions & 0 deletions runtime/jsspeccy.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@ window.JSSpeccy = (container, opts) => {
}
emu.on('setAutoLoadTapes', updateAutoLoadTapesCheckbox);
updateAutoLoadTapesCheckbox();

fileMenu.addItem('Find games...', () => {
openGameBrowser();
});
}

const machineMenu = ui.menuBar.addMenu('Machine');
Expand Down Expand Up @@ -476,6 +480,89 @@ window.JSSpeccy = (container, opts) => {
});
}

const openGameBrowser = () => {
emu.pause();
const body = ui.showDialog();
body.innerHTML = `
<label>Find games</label>
<form>
<input type="search">
<button type="submit">Search</button>
</form>
<div class="results">
</div>
`;
const input = body.querySelector('input');
const searchButton = body.querySelector('button');
const searchForm = body.querySelector('form');
const resultsContainer = body.querySelector('.results');

searchForm.addEventListener('submit', (e) => {
e.preventDefault();
searchButton.innerText = 'Searching...';
const searchTerm = input.value.replace(/[^\w\s\-\']/, '');

const encodeParam = (key, val) => {
return encodeURIComponent(key) + '=' + encodeURIComponent(val);
}

const searchUrl = (
'https://archive.org/advancedsearch.php?'
+ encodeParam('q', 'collection:softwarelibrary_zx_spectrum title:"' + searchTerm + '"')
+ '&' + encodeParam('fl[]', 'creator')
+ '&' + encodeParam('fl[]', 'identifier')
+ '&' + encodeParam('fl[]', 'title')
+ '&' + encodeParam('rows', '50')
+ '&' + encodeParam('page', '1')
+ '&' + encodeParam('output', 'json')
)
fetch(searchUrl).then(response => {
searchButton.innerText = 'Search';
return response.json();
}).then(data => {
resultsContainer.innerHTML = '<ul></ul><p>- powered by <a href="https://archive.org/">Internet Archive</a></p>';
const ul = resultsContainer.querySelector('ul');
const results = data.response.docs;
results.forEach(result => {
const li = document.createElement('li');
ul.appendChild(li);
const resultLink = document.createElement('a');
resultLink.href = '#';
resultLink.innerText = result.title;
const creator = document.createTextNode(' - ' + result.creator)
li.appendChild(resultLink);
li.appendChild(creator);
resultLink.addEventListener('click', (e) => {
e.preventDefault();
fetch(
'https://archive.org/metadata/' + result.identifier
).then(response => response.json()).then(data => {
let chosenFilename = null;
data.files.forEach(file => {
const ext = file.name.split('.').pop().toLowerCase();
if (ext == 'z80' || ext == 'sna' || ext == 'tap' || ext == 'tzx' || ext == 'szx') {
chosenFilename = file.name;
}
});
if (!chosenFilename) {
alert('No loadable file found');
} else {
const finalUrl = 'https://cors.archive.org/cors/' + result.identifier + '/' + chosenFilename;
emu.openUrl(finalUrl).catch((err) => {
alert(err);
}).then(() => {
ui.hideDialog();
emu.start();
});
}
})
})
})
})
})
input.focus();
}

const exit = () => {
emu.exit();
ui.unload();
Expand Down
39 changes: 39 additions & 0 deletions runtime/ui.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import EventEmitter from 'events';

import playIcon from './icons/play.svg';
import closeIcon from './icons/close.svg';


export class MenuBar {
Expand Down Expand Up @@ -212,6 +213,23 @@ export class UIController extends EventEmitter {
this.canvas = emulator.canvas;

/* build UI elements */
this.dialog = document.createElement('div');
this.dialog.style.display = 'none';
container.appendChild(this.dialog);
const dialogCloseButton = document.createElement('button');
dialogCloseButton.innerHTML = closeIcon;
dialogCloseButton.style.float = 'right';
dialogCloseButton.style.border = 'none';
dialogCloseButton.firstChild.style.height = '20px';
dialogCloseButton.firstChild.style.verticalAlign = 'middle';
this.dialog.appendChild(dialogCloseButton);
dialogCloseButton.addEventListener('click', () => {
this.hideDialog();
})
this.dialogBody = document.createElement('div');
this.dialogBody.style.clear = 'both';
this.dialog.appendChild(this.dialogBody);

this.appContainer = document.createElement('div');
container.appendChild(this.appContainer);
this.appContainer.style.position = 'relative';
Expand Down Expand Up @@ -391,7 +409,28 @@ export class UIController extends EventEmitter {
this.toolbar.show();
}
}
showDialog() {
this.dialog.style.display = 'block';
this.dialog.style.position = 'absolute';
this.dialog.style.backgroundColor = '#eee';
this.dialog.style.zIndex = '100';
this.dialog.style.width = '75%';
this.dialog.style.height = '80%';
this.dialog.style.left = '12%';
this.dialog.style.top = '10%';
this.dialog.style.overflow = 'scroll'; // TODO: less hacky scrolling that doesn't hide the close button
this.dialogBody.style.paddingLeft = '8px';
this.dialogBody.style.paddingRight = '8px';
this.dialogBody.style.paddingBottom = '8px';

return this.dialogBody;
}
hideDialog() {
this.dialog.style.display = 'none';
this.dialogBody.innerHTML = '';
}
unload() {
this.dialog.remove();
this.appContainer.remove();
}
}

0 comments on commit 51d833e

Please sign in to comment.