use pyo3::{prelude::*, types::PyBytes}; use crate::{ gb::{GameBoy as GameBoyBase, GameBoyMode}, ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH}, }; #[pyclass] struct GameBoy { system: GameBoyBase, } #[pymethods] impl GameBoy { #[new] fn new(mode: u8) -> Self { Self { system: GameBoyBase::new(Some(GameBoyMode::from_u8(mode))), } } pub fn reset(&mut self) { self.system.reset(); } pub fn load(&mut self) { self.system.load(true); } pub fn load_rom(&mut self, data: &[u8]) { self.system.load_rom(data, None); } pub fn load_rom_file(&mut self, path: &str) { self.system.load_rom_file(path, None); } pub fn clock(&mut self) -> u16 { self.system.clock() } pub fn clock_m(&mut self, count: usize) -> u16 { self.system.clock_m(count) } pub fn clocks(&mut self, count: usize) -> u64 { self.system.clocks(count) } pub fn next_frame(&mut self) -> u32 { self.system.next_frame() } pub fn frame_buffer(&mut self, py: Python) -> PyObject { let pybytes = PyBytes::new(py, self.system.frame_buffer()); pybytes.into() } pub fn ppu_enabled(&self) -> bool { self.system.ppu_enabled() } pub fn set_ppu_enabled(&mut self, value: bool) { self.system.set_ppu_enabled(value); } pub fn apu_enabled(&self) -> bool { self.system.apu_enabled() } pub fn set_apu_enabled(&mut self, value: bool) { self.system.set_apu_enabled(value); } pub fn dma_enabled(&self) -> bool { self.system.dma_enabled() } pub fn set_dma_enabled(&mut self, value: bool) { self.system.set_dma_enabled(value); } pub fn timer_enabled(&self) -> bool { self.system.timer_enabled() } pub fn set_timer_enabled(&mut self, value: bool) { self.system.set_timer_enabled(value); } pub fn serial_enabled(&self) -> bool { self.system.serial_enabled() } pub fn set_serial_enabled(&mut self, value: bool) { self.system.set_serial_enabled(value); } } #[pymodule] fn boytacean(_py: Python, module: &PyModule) -> PyResult<()> { module.add_class::<GameBoy>()?; module.add("DISPLAY_WIDTH", DISPLAY_WIDTH)?; module.add("DISPLAY_HEIGHT", DISPLAY_HEIGHT)?; module.add("CPU_FREQ", GameBoyBase::CPU_FREQ)?; Ok(()) }