extern crate crossbeam_channel; extern crate ferretro_components; extern crate ffmpeg_next as ffmpeg; extern crate sdl2; use std::path::PathBuf; use structopt::StructOpt; use ferretro_components::prelude::*; use ferretro_components::provided::{ ffmpeg::FfmpegComponent, sdl2::*, stdlib::{PathBufComponent, StderrLogComponent, SleepFramerateLimitComponent}, }; use ferretro_components::base::ControlFlow; #[derive(StructOpt)] struct Opt { /// Core module to use. #[structopt(short, long, parse(from_os_str))] core: PathBuf, /// ROM to load using the core. #[structopt(short, long, parse(from_os_str))] rom: PathBuf, /// Save state to load at startup. #[structopt(long, parse(from_os_str))] state: Option, /// System directory, often containing BIOS files #[structopt(short, long, parse(from_os_str))] system: Option, /// Recorded video to write. #[structopt(short, long, parse(from_os_str))] video: Option, } pub fn main() -> Result<(), Box> { let opt: Opt = Opt::from_args(); let mut emu = RetroComponentBase::new(&opt.core); let mut sdl_context = sdl2::init()?; emu.register_component(StderrLogComponent { prefix: "{log} ".to_string() })?; // must register before opengl so it can have priority in queries about what N64 plugin to use // (only supports software-rendered 2D frames currently) if let Some(video) = opt.video { ffmpeg::log::set_level(ffmpeg::log::Level::Info); ffmpeg::init()?; let ffmpeg_comp = FfmpegComponent::new(emu.libretro_core(), video); emu.register_component(ffmpeg_comp)?; } let sdl2_ogl = SimpleSdl2OpenglComponent::new(&mut sdl_context, emu.libretro_core())?; emu.register_component(sdl2_ogl)?; let sdl2_audio = SimpleSdl2AudioComponent::new(&mut sdl_context, emu.libretro_core()); emu.register_component(sdl2_audio)?; emu.register_component(SimpleSdl2GamepadComponent::new(&mut sdl_context))?; let sleep_fps = SleepFramerateLimitComponent::new(emu.libretro_core()); emu.register_component(sleep_fps)?; emu.register_component(PathBufComponent { sys_path: opt.system.clone(), libretro_path: Some(opt.core.to_path_buf()), core_assets_path: None, save_path: Some(std::env::temp_dir()), })?; emu.init()?; emu.load_game(&opt.rom)?; if let Some(state) = opt.state { emu.unserialize_path(state)?; } let mut frame = 0; while let ControlFlow::Continue = emu.run() { frame += 1; } eprintln!("Ran for {} frames.", frame); Ok(()) }