Skip to content

Commit

Permalink
remote loading support
Browse files Browse the repository at this point in the history
  • Loading branch information
d07RiV committed Aug 4, 2019
1 parent def0236 commit 6440d69
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 14 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "diabloweb",
"version": "1.0.18",
"version": "1.0.19",
"private": true,
"dependencies": {
"@babel/core": "7.4.3",
Expand Down
2 changes: 1 addition & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ class App extends React.Component {

this.setState({loading: true, retail});

load_game(this, file).then(game => {
load_game(this, file, !retail).then(game => {
this.game = game;

document.addEventListener('mousemove', this.onMouseMove, true);
Expand Down
Binary file modified src/api/Diablo.wasm
Binary file not shown.
Binary file modified src/api/DiabloSpawn.wasm
Binary file not shown.
59 changes: 58 additions & 1 deletion src/api/game.worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import axios from 'axios';
const DiabloSize = 1316452;
const SpawnSize = 1196648;

const SpawnMpqSize = 50274091;
const RetailMpqSize = 517501282;

/* eslint-disable-next-line no-restricted-globals */
const worker = self;

Expand All @@ -17,6 +20,52 @@ let renderBatch = null;
let drawBelt = null;
let is_spawn = false;

const ChunkSize = 1 << 20;
class RemoteFile {
constructor(url, size) {
this.url = url;
this.byteLength = size;

this.buffer = new Uint8Array(size);
this.chunks = new Uint8Array(((size + ChunkSize - 1) >> 20) | 0);
}

subarray(start, end) {
let chunk0 = (start / ChunkSize) | 0;
let chunk1 = ((end + ChunkSize - 1) / ChunkSize) | 0;
let missing0 = chunk1, missing1 = chunk0;
for (let i = chunk0; i < chunk1; ++i) {
if (!this.chunks[i]) {
missing0 = Math.min(missing0, i);
missing1 = Math.max(missing1, i);
}
}
if (missing0 <= missing1) {
const request = new XMLHttpRequest();
request.open('GET', this.url, false);
request.setRequestHeader('Range', `bytes=${missing0 * ChunkSize}-${Math.min(missing1 * ChunkSize + ChunkSize - 1, this.byteLength - 1)}`);
request.responseType = 'arraybuffer';
request.send();
if (request.status < 200 || request.status > 206) {
worker.postMessage({action: "error", error: `Failed to load remote file`});
} else {
const header = request.getResponseHeader('Content-Range');
let m, start = 0;
if (header && (m = header.match(/bytes (\d+)-(\d+)\/(\d+)/))) {
start = parseInt(m[1]);
}
this.buffer.set(new Uint8Array(request.response), start);
chunk0 = ((start + ChunkSize - 1) / ChunkSize) | 0;
chunk1 = ((start + request.response.byteLength + ChunkSize - 1) / ChunkSize) | 0;
for (let i = chunk0; i < chunk1; ++i) {
this.chunks[i] = 1;
}
}
}
return this.buffer.subarray(start, end);
}
}

const DApi = {
exit_error(error) {
worker.postMessage({action: "error", error});
Expand All @@ -36,7 +85,7 @@ const DApi = {
get_file_contents(path, array, offset) {
const data = files.get(path.toLowerCase());
if (data) {
array.set(data.subarray(offset, offset + array.length));
array.set(data.subarray(offset, offset + array.byteLength));
}
},
put_file_contents(path, array) {
Expand Down Expand Up @@ -240,6 +289,14 @@ async function init_game(mpq, spawn, offscreen) {
Object.assign(DApi, DApi_renderLegacy);
}

if (!mpq) {
const name = (spawn ? 'spawn.mpq' : 'diabdat.mpq');
if (!files.has(name)) {
// This should never happen, but we do support remote loading
files.set(name, new RemoteFile(`${process.env.PUBLIC_URL}/${name}`, spawn ? SpawnMpqSize : RetailMpqSize));
}
}

progress("Loading...");
let mpqLoaded = 0, mpqTotal = (mpq ? mpq.size : 0), wasmLoaded = 0, wasmTotal = (spawn ? SpawnSize : DiabloSize);
const wasmWeight = 5;
Expand Down
14 changes: 4 additions & 10 deletions src/api/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,9 @@ function testOffscreen() {
}*/
}

async function do_load_game(api, audio, mpq) {
async function do_load_game(api, audio, mpq, spawn) {
const fs = await api.fs;
let spawn = true;
if (mpq) {
if (!mpq.name.match(/^spawn\.mpq$/i)) {
spawn = false;
fs.files.delete('spawn.mpq');
}
} else {
if (spawn && !mpq) {
await load_spawn(api, fs);
}

Expand Down Expand Up @@ -124,7 +118,7 @@ async function do_load_game(api, audio, mpq) {
});
}

export default function load_game(api, mpq) {
export default function load_game(api, mpq, spawn) {
const audio = init_sound();
return do_load_game(api, audio, mpq);
return do_load_game(api, audio, mpq, spawn);
}

0 comments on commit 6440d69

Please sign in to comment.