Allow rewinding a replay without desyncing it
This commit is contained in:
parent
410af788fc
commit
0f0c7437a6
@ -25,13 +25,20 @@ class CC2Demo {
|
||||
this.blob_seed = this.bytes[2];
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
decompress() {
|
||||
let duration = 0;
|
||||
let l = this.bytes.length;
|
||||
if (l % 2 === 0) {
|
||||
l--;
|
||||
}
|
||||
let input = new Set;
|
||||
for (let p = 3; p < l; p += 2) {
|
||||
duration += this.bytes[p];
|
||||
}
|
||||
|
||||
let inputs = new Uint8Array(duration);
|
||||
let i = 0;
|
||||
let t = 0;
|
||||
let input = 0;
|
||||
for (let p = 3; p < l; p += 2) {
|
||||
// The first byte measures how long the /previous/ input remains
|
||||
// valid, so yield that first. Note that this is measured in 60Hz
|
||||
@ -44,24 +51,31 @@ class CC2Demo {
|
||||
t += delay;
|
||||
while (t >= 3) {
|
||||
t -= 3;
|
||||
yield input;
|
||||
inputs[i] = input;
|
||||
i++;
|
||||
}
|
||||
|
||||
let input_mask = this.bytes[p + 1];
|
||||
let is_player_2 = ((input_mask & 0x80) !== 0);
|
||||
input = this.bytes[p + 1];
|
||||
let is_player_2 = ((input & 0x80) !== 0);
|
||||
// TODO handle player 2
|
||||
if (is_player_2)
|
||||
continue;
|
||||
}
|
||||
|
||||
for (let [action, bit] of Object.entries(CC2_DEMO_INPUT_MASK)) {
|
||||
if ((input_mask & bit) === 0) {
|
||||
input.delete(action);
|
||||
// TODO maybe turn this into, like, a type, or something
|
||||
return {
|
||||
inputs: inputs,
|
||||
length: duration,
|
||||
get(t) {
|
||||
if (t >= this.inputs.length) {
|
||||
return new Set;
|
||||
}
|
||||
else {
|
||||
input.add(action);
|
||||
let input = this.inputs[t];
|
||||
return new Set(Object.entries(CC2_DEMO_INPUT_MASK).filter(([action, bit]) => input & bit).map(([action, bit]) => action));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -1826,7 +1840,6 @@ const MAX_SIMULTANEOUS_REQUESTS = 5;
|
||||
resolve(game);
|
||||
}
|
||||
|
||||
console.log(game);
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
||||
10
js/main.js
10
js/main.js
@ -898,7 +898,7 @@ class Player extends PrimaryView {
|
||||
play_demo() {
|
||||
this.restart_level();
|
||||
let demo = this.level.stored_level.demo;
|
||||
this.demo_faucet = demo[Symbol.iterator]();
|
||||
this.demo_faucet = demo.decompress();
|
||||
this.level.force_floor_direction = demo.initial_force_floor_direction;
|
||||
this.level._blob_modifier = demo.blob_seed;
|
||||
// FIXME should probably start playback on first real input
|
||||
@ -908,13 +908,7 @@ class Player extends PrimaryView {
|
||||
get_input() {
|
||||
let input;
|
||||
if (this.demo_faucet) {
|
||||
let step = this.demo_faucet.next();
|
||||
if (step.done) {
|
||||
input = new Set;
|
||||
}
|
||||
else {
|
||||
input = step.value;
|
||||
}
|
||||
input = this.demo_faucet.get(this.level.tic_counter);
|
||||
}
|
||||
else {
|
||||
// Convert input keys to actions. This is only done now
|
||||
|
||||
Loading…
Reference in New Issue
Block a user