diff --git a/src/common/recorder.ts b/src/common/recorder.ts index aa43777a..7db47d5a 100644 --- a/src/common/recorder.ts +++ b/src/common/recorder.ts @@ -85,6 +85,10 @@ export class StateRecorderImpl implements EmuRecorder { } getStateAtOrBefore(frame : number) : {frame : number, state : EmuState} { + // initial frame? + if (frame <= 0 && this.checkpoints.length > 0) + return {frame:0, state:this.checkpoints[0]}; + var bufidx = Math.floor(frame / this.checkpointInterval); var foundidx = bufidx < this.checkpoints.length ? bufidx : this.checkpoints.length-1; var foundframe = foundidx * this.checkpointInterval; @@ -111,6 +115,11 @@ export class StateRecorderImpl implements EmuRecorder { frame++; numSteps = this.platform.advance(frame < seekframe); // TODO: infinite loop? } + // TODO: if first frame, we must figure out # of steps + if (frame == 0) { + numSteps = this.platform.advance(true); + this.platform.loadState(state); + } // seek to step index // TODO: what if advance() returns clocks, but steps use insns? if (seekstep > 0 && this.platform.advanceFrameClock) { @@ -122,7 +131,7 @@ export class StateRecorderImpl implements EmuRecorder { this.lastStepCount = numSteps; return seekframe; } else { - return 0; + return -1; } } diff --git a/src/ide/ui.ts b/src/ide/ui.ts index 3923dc66..e14e5677 100644 --- a/src/ide/ui.ts +++ b/src/ide/ui.ts @@ -1638,7 +1638,7 @@ function setupReplaySlider() { _pause(); var frame : number = parseInt(replayslider.val().toString()); var step : number = parseInt(clockslider.val().toString()); - if (stateRecorder.loadFrame(frame, step)) { + if (stateRecorder.loadFrame(frame, step) >= 0) { clockslider.attr('min', 0); clockslider.attr('max', stateRecorder.lastStepCount); updateFrameNo(); @@ -1647,7 +1647,7 @@ function setupReplaySlider() { }; var setFrameTo = (frame:number) => { _pause(); - if (stateRecorder.loadFrame(frame)) { + if (stateRecorder.loadFrame(frame) >= 0) { replayslider.val(frame); updateFrameNo(); uiDebugCallback(platform.saveState()); @@ -1656,14 +1656,14 @@ function setupReplaySlider() { var setClockTo = (clock:number) => { _pause(); var frame : number = parseInt(replayslider.val().toString()); - if (stateRecorder.loadFrame(frame, clock)) { + if (stateRecorder.loadFrame(frame, clock) >= 0) { clockslider.val(clock); updateFrameNo(); uiDebugCallback(platform.saveState()); } }; stateRecorder.callbackStateChanged = () => { - replayslider.attr('min', 1); + replayslider.attr('min', 0); replayslider.attr('max', stateRecorder.numFrames()); replayslider.val(stateRecorder.currentFrame()); clockslider.val(stateRecorder.currentStep()); diff --git a/test/cli/testplatforms.js b/test/cli/testplatforms.js index 39853335..b4ecc306 100644 --- a/test/cli/testplatforms.js +++ b/test/cli/testplatforms.js @@ -157,6 +157,7 @@ async function testPlatform(platid, romname, maxframes, callback) { var state1 = platform.saveState(); platform.loadState(state1); assert.deepEqual(state1, platform.saveState()); + assert.equal(0, rec.loadFrame(0)); assert.equal(1, rec.loadFrame(1)); assert.equal(maxframes, rec.loadFrame(maxframes)); var state2 = platform.saveState();