Skip to main content

MovieRecorder

Struct MovieRecorder 

Source
pub struct MovieRecorder { /* private fields */ }
Expand description

Records the per-frame input stream applied to an emulator.

Usage (caller-driven, mirrors the frontend’s per-frame loop):

let mut rec = MovieRecorder::power_on(&nes);
loop {
    nes.set_buttons(0, p1);
    nes.set_buttons(1, p2);
    rec.capture(&nes); // BEFORE run_frame — captures the inputs it consumes
    nes.run_frame();
}
let movie = rec.finish();

Implementations§

Source§

impl MovieRecorder

Source

pub const fn power_on(nes: &Nes) -> Self

Begin recording a movie that starts from a fresh power-on of the ROM nes is running. The caller is responsible for power-cycling nes before the first captured frame so the recording starts from the same state a replay will reconstruct.

Source

pub fn from_current_state(nes: &Nes) -> Self

Begin recording a movie that starts from nes’s current state (a branch point). Captures a snapshot now and embeds it as the start point; the input stream is recorded from here forward.

Source

pub fn capture(&mut self, nes: &Nes)

Record the controller inputs currently held on nes. Call this each frame before Nes::run_frame, after the frontend has applied its set_buttons calls — this captures exactly the inputs the upcoming frame consumes.

§Two ports only, including under a Four Score

FrameInput models ports 0 and 1, so this reads nes.buttons(0) and nes.buttons(1) and nothing else. The core itself carries four — the frontend calls set_buttons(2) / set_buttons(3) whenever the Four Score adapter is active — so recording a four-player session captures half of what drove it, and replaying that movie diverges from the run it came from.

Stated here rather than left to be discovered, because the failure is silent at record time: nothing about a .rnm says which ports it could not hold, and the divergence only appears on playback. The frontend’s Replay panel says so where the topology is displayed, and Movie::verify’s attestation catches it after the fact.

Widening FrameInput is a .rnm format epoch change (ADR 0028), not an additive one, which is why this is a documented limit rather than a fix. The .fm2 importer already takes the same position for the same reason — it keeps pads 1 and 2, drops 3 and 4, and preserves the fourscore flag so the caller is not silently misled.

Source

pub fn capture_input(&mut self, input: FrameInput)

Record an explicit frame of input (for callers that drive input programmatically rather than through set_buttons).

Source

pub const fn len(&self) -> usize

Number of frames captured so far.

Source

pub const fn is_empty(&self) -> bool

true if no frames have been captured.

Source

pub fn enable_attestation(&mut self)

v2.3.2 “Lucid” — start accumulating a replay attestation.

Call before the first frame. The caller must then call Self::attest_frame after every run_frame, in lockstep with Self::capture, or the recorded hash will describe a different run than the input stream does — which Movie::verify would then report as a mismatch, correctly but unhelpfully.

Source

pub fn disable_attestation(&mut self)

Abandon an in-progress attestation, keeping the recording itself.

For a host that rewinds or otherwise moves the emulator off the timeline the accumulated hash describes. Once dropped it is not resumed: the prefix already folded in cannot be un-folded, and a partial hash that silently covers only part of the run would be worse than none.

Source

pub fn attest_frame(&mut self, framebuffer: &[u8])

Fold this frame’s video output into the attestation.

A no-op unless Self::enable_attestation was called. Pass the slice Nes::run_frame returned (or Nes::framebuffer()), AFTER the frame ran.

Uses the input recorded by the matching Self::capture, so the two must stay in lockstep — one capture then one attest_frame per frame. If they drift the recorded frame counts disagree and Movie::deserialize drops the tail, which is the safe direction.

Source

pub fn finish(self) -> Movie

Finish recording and produce the Movie.

Trait Implementations§

Source§

impl Clone for MovieRecorder

Source§

fn clone(&self) -> MovieRecorder

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for MovieRecorder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.