Skip to main content

EmuCore

Struct EmuCore 

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

The pure emulation-core facade: load a ROM, step a frame, expose the framebuffer + audio.

For the present path. Lives behind an Arc<Mutex<…>> when a consumer drives it from a dedicated thread; stepped synchronously otherwise.

Implementations§

Source§

impl EmuCore

Source

pub fn new(seed: u64, region: Region) -> Self

Power on with a determinism seed and a region. No ROM is loaded yet.

Source

pub fn load_rom(&mut self, rom: &[u8]) -> Result<(), EmuError>

Load a raw ROM image, transparently unwrapping a zip archive first if rom is one (the common case of a .sfc/.smc distributed zipped). Header detection + board selection happen in rustysnes-cart. On success the cart is installed in a fresh Bus and the system is left ready to boot from the cart’s reset vector on the first Self::run_frame.

§Errors

Returns an EmuError if the image is empty, is a zip archive that can’t be opened or contains no recognizable ROM entry, or no valid SNES header is found.

Source

pub fn firmware_candidates(&self) -> &'static [&'static str]

The coprocessor firmware dumps this cart will accept (filenames), in try order. Empty when the cart needs no external firmware. A host uses this to locate + install the dump.

Source

pub fn needs_firmware(&self) -> bool

Whether the loaded cart carries a coprocessor that needs a (not-yet-installed) firmware dump to function. The honesty posture of docs/adr/0003: without the dump the coprocessor is non-functional, so a host should prompt for it.

Source

pub fn install_firmware(&mut self, bytes: &[u8]) -> bool

Supply a coprocessor firmware dump. Returns true if the cart’s board accepted it (right coprocessor + size); on success the bytes are retained for Power-Cycle.

Source

pub fn load_sram(&mut self, data: &[u8])

Restore battery SRAM from a .srm image (truncated/zero-padded to the board’s SRAM size).

Source

pub fn save_sram(&self) -> &[u8]

The current battery SRAM contents (empty when the cart has no SRAM), for a .srm save.

Source

pub fn reset(&mut self)

Soft reset: re-run the cart’s reset vector without clearing RAM (the SNES front-panel Reset button). A no-op when no ROM is loaded.

Source

pub fn power_cycle(&mut self)

Power-cycle (hard reset): rebuild a clean machine from the retained ROM + firmware. Battery SRAM is NOT preserved here (the caller reloads .srm if desired).

Source

pub fn close_rom(&mut self)

Close the loaded ROM and present a clean blank frame.

Source

pub const fn rom_loaded(&self) -> bool

Whether a ROM is loaded.

Source

pub fn cart_name(&self) -> Option<&'static str>

The loaded cartridge’s board name (for a status display), if any.

Source

pub fn rom(&self) -> &[u8]

The raw ROM byte image currently loaded (empty if none) — for TAS movie recording’s ROM-identity hash (crate::movie::hash_rom/crate::movie::Movie::verify_rom), which needs the exact bytes rather than Cart’s parsed/header-stripped internal representation.

Source

pub fn system_mut(&mut self) -> &mut System

Direct mutable access to the deterministic core, for TAS movie record/playback (crate::movie), Lua scripting, or a debugger overlay — all need genuine read/write reach into the running System/Bus.

Source

pub fn set_pad(&mut self, player: usize, buttons: u16)

Latch the controller state for a player (0 = P1, 1 = P2), applied to the Bus at the top of the next Self::run_frame/Self::apply_pads. Taken as a raw button-state word, same as crate::bus::Bus::set_joypad — a host is responsible for any input hygiene it wants (e.g. the frontend’s Buttons::sanitize_dpad clearing illegal opposite D-pad directions before calling this), matching the honest “this facade stores what it’s told” posture the rest of its setters already have.

Source

pub fn apply_pads(&mut self)

Push the latched pad state to the Bus without running a frame — split out of Self::run_frame so a host that needs to interleave conditional stepping (a debugger’s pause/breakpoint gate) can latch input once and then choose how to advance the System.

Source

pub fn set_port_device(&mut self, port: usize, device: PortDevice)

Select which peripheral is attached to controller port port — see crate::bus::Bus::set_port_device.

Source

pub fn set_mouse( &mut self, port: usize, dx: i32, dy: i32, left: bool, right: bool, )

Feed one frame’s worth of SNES Mouse input for port port — see crate::bus::Bus::set_mouse.

Source

pub fn set_voice_mutes(&mut self, mutes: [bool; 8])

Set the 8 per-voice audio mute toggles — see crate::bus::Bus::set_voice_mutes’s doc.

Source

pub fn set_superscope(&mut self, port: usize, x: i32, y: i32, buttons: u8)

Feed one frame’s worth of Super Scope input for port port — see crate::bus::Bus::set_superscope.

Source

pub fn set_multitap_pad(&mut self, port: usize, sub_index: usize, buttons: u16)

Feed one frame’s worth of input for Super Multitap sub-pad sub_index of port port — see crate::bus::Bus::set_multitap_pad.

Source

pub fn run_frame(&mut self)

Advance one full video frame unconditionally: latch pads, run the scheduler to the next frame boundary, then decode the PPU framebuffer + drain the S-DSP audio. A host that needs conditional stepping (pause/breakpoints) should call Self::apply_pads + Self::system_mut + Self::present_current_frame directly instead.

Source

pub fn present_current_frame(&mut self)

Decode the PPU framebuffer + drain the S-DSP audio from the System’s CURRENT state, without advancing it — the second half of Self::run_frame, split out for a host that drives System::run_frame (or step_instruction) directly (netplay rollback, a debugger’s single-step) and needs to pick up the result afterward.

Source

pub fn framebuffer(&self) -> &[u8]

The current RGBA8 framebuffer slice (the active mode’s w*h*4 bytes), for the present path.

Source

pub fn audio(&self) -> &[(i16, i16)]

The audio samples (32 kHz stereo) produced during the most recent Self::run_frame.

Source

pub const fn fb_dims(&self) -> (u32, u32)

The active framebuffer dimensions (w, h).

Source

pub const fn region(&self) -> Region

The active region.

Source

pub fn save_state(&self) -> Vec<u8>

Snapshot the full deterministic core state (System::save_state, docs/adr/0006) for rewind/run-ahead/quick-save. Host-only state (the decoded RGBA8 framebuffer, the retained ROM/firmware bytes for Power-Cycle, latched pads) is NOT part of this — it’s outside the deterministic core and is re-derived after Self::load_state.

Source

pub fn load_state(&mut self, bytes: &[u8]) -> Result<(), SaveStateError>

Restore a snapshot taken by Self::save_state from a System with the SAME cart already loaded (a save-state never embeds ROM bytes, docs/adr/0006) — the caller must have already load_rom’d the matching ROM. Re-renders the framebuffer immediately so a host reflects the restored frame without waiting for the next Self::run_frame, and clears the audio FIFO (a state load jumps time discontinuously; there is no continuous audio stream to drain across that jump).

§Errors

Propagates rustysnes_savestate::SaveStateError if bytes is truncated/corrupt, from an incompatible format version, or doesn’t match this System’s currently-loaded cart (SRAM size, coprocessor presence) — the state is left unchanged on error.

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> 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, 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.