1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
pub mod register; pub mod cpu; pub mod ppu; pub mod apu; pub mod rom; pub mod memory; pub mod mapper; pub mod button; pub mod joypad; pub mod input; pub mod audio; pub mod display; pub mod default_input; pub mod default_audio; pub mod default_display; use cpu::Cpu; use rom::Rom; use button::Button; use input::Input; use display::Display; use audio::Audio; /// NES emulator. /// /// ```ignore /// use std::fs::File; /// use std::io::Read; /// use std::time::Duration; /// use nes_rust::Nes; /// use nes_rust::rom::Rom; /// use nes_rust::default_input::DefaultInput; /// use nes_rust::default_audio::DefaultAudio; /// use nes_rust::default_display::DefaultDisplay; /// /// let input = Box::new(DefaultInput::new()); /// let display = Box::new(DefaultDisplay::new()); /// let audio = Box::new(DefaultAudio::new()); /// let mut nes = Nes::new(input, display, audio); /// /// // Load and set Rom from rom image binary /// let filename = &args[1]; /// let mut file = File::open(filename)?; /// let mut contents = vec![]; /// file.read_to_end(&mut contents)?; /// let rom = Rom::new(contents); /// nes.set_rom(rom); /// /// // Go! /// nes.bootup(); /// let mut rgba_pixels = [256 * 240 * 4]; /// loop { /// nes.step_frame(); /// nes.copy_pixels(rgba_pixels); /// // Render rgba_pixels /// // @TODO: Audio buffer sample code is T.B.D. /// // Adjust sleep time for your platform /// std::thread::sleep(Duration::from_millis(1)); /// } /// ``` pub struct Nes { cpu: Cpu } impl Nes { /// Creates a new `Nes`. /// You need to pass [`input::Input`](./input/trait.Input.html), /// [`display::Display`](./display/trait.Display.html), and /// [`audio::Audio`](./audio/trait.Audio.html) traits for your platform /// specific Input/Output. /// /// # Arguments /// * `input` For pad input /// * `display` For screen output /// * `audio` For audio output pub fn new(input: Box<dyn Input>, display: Box<dyn Display>, audio: Box<dyn Audio>) -> Self { Nes { cpu: Cpu::new( input, display, audio ) } } /// Sets up NES rom /// /// # Arguments /// * `rom` pub fn set_rom(&mut self, rom: Rom) { self.cpu.set_rom(rom); } /// Boots up pub fn bootup(&mut self) { self.cpu.bootup(); } /// Resets pub fn reset(&mut self) { self.cpu.reset(); } /// Executes a CPU cycle pub fn step(&mut self) { self.cpu.step(); } /// Executes a PPU (screen refresh) frame pub fn step_frame(&mut self) { self.cpu.step_frame(); } /// Copies RGB pixels of screen to passed pixels. /// The length and result should be specific to `display` passed via the constructor. /// /// # Arguments /// * `pixels` pub fn copy_pixels(&self, pixels: &mut [u8]) { self.cpu.get_ppu().get_display().copy_to_rgba_pixels(pixels); } /// Copies audio buffer to passed buffer. /// The length and result should be specific to `audio` passed via the constructor. /// /// # Arguments /// * `buffer` pub fn copy_sample_buffer(&mut self, buffer: &mut [f32]) { self.cpu.get_mut_apu().get_mut_audio().copy_sample_buffer(buffer); } /// Presses a pad button /// /// # Arguments /// * `button` pub fn press_button(&mut self, button: Button) { self.cpu.get_mut_input().press(button); } /// Releases a pad button /// /// # Arguments /// * `buffer` pub fn release_button(&mut self, button: Button) { self.cpu.get_mut_input().release(button); } }