Newer
Older
pub fn load_boot_path(&mut self, path: &str) -> Result<(), String> {
let data = read_file(path)?;
pub fn load_boot_file(&mut self, boot_rom: BootRom) -> Result<(), String> {
BootRom::Dmg => self.load_boot_path("./res/boot/dmg_boot.bin")?,
BootRom::Sgb => self.load_boot_path("./res/boot/sgb_boot.bin")?,
BootRom::DmgBootix => self.load_boot_path("./res/boot/dmg_bootix.bin")?,
BootRom::MgbBootix => self.load_boot_path("./res/boot/mgb_bootix.bin")?,
BootRom::Cgb => self.load_boot_path("./res/boot/cgb_boot.bin")?,
pub fn load_boot_default_f(&mut self) -> Result<(), String> {
self.load_boot_dmg_f()?;
Ok(())
pub fn load_boot_dmg_f(&mut self) -> Result<(), String> {
self.load_boot_file(BootRom::DmgBootix)?;
Ok(())
pub fn load_boot_cgb_f(&mut self) -> Result<(), String> {
self.load_boot_file(BootRom::Cgb)?;
Ok(())
pub fn load_cartridge(&mut self, rom: Cartridge) -> &mut Cartridge {
self.mmu().set_rom(rom);
pub fn load_rom(&mut self, data: &[u8], ram_data: Option<&[u8]>) -> &mut Cartridge {
let mut rom = Cartridge::from_data(data);
if let Some(ram_data) = ram_data {
rom.set_ram_data(ram_data)
pub fn load_rom_file(&mut self, path: &str, ram_path: Option<&str>) -> &mut Cartridge {
match ram_path {
Some(ram_path) => {
self.load_rom(&data, Some(&ram_data))
}
None => self.load_rom(&data, None),
}
pub fn attach_serial(&mut self, device: Box<dyn SerialDevice>) {
self.serial().set_device(device);
}
pub fn set_speed_callback(&mut self, callback: fn(speed: GameBoySpeed)) {
self.mmu().set_speed_callback(callback);
}
pub fn reset_cheats(&mut self) {
self.reset_game_genie();
pub fn add_cheat_code(&mut self, code: &str) -> Result<bool, String> {
if GameGenie::is_code(code) {
return match self.add_game_genie_code(code) {
Ok(_) => Ok(true),
Err(message) => Err(message),
};
if GameShark::is_code(code) {
return match self.add_game_shark_code(code) {
Ok(_) => Ok(true),
Err(message) => Err(message),
};
}
Err(String::from("Not a valid cheat code"))
pub fn add_game_genie_code(&mut self, code: &str) -> Result<&GameGenieCode, String> {
let rom = self.mmu().rom();
if rom.game_genie().is_none() {
let game_genie = GameGenie::default();
rom.attach_genie(game_genie);
}
let game_genie = rom.game_genie_mut().as_mut().unwrap();
game_genie.add_code(code)
}
pub fn add_game_shark_code(&mut self, code: &str) -> Result<&GameSharkCode, String> {
let rom = self.mmu().rom();
if rom.game_shark().is_none() {
let game_shark = GameShark::default();
rom.attach_shark(game_shark);
}
let game_shark = rom.game_shark_mut().as_mut().unwrap();
game_shark.add_code(code)
}
pub fn reset_game_genie(&mut self) {
let rom = self.mmu().rom();
if rom.game_genie().is_some() {
rom.game_genie_mut().as_mut().unwrap().reset();
}
}
pub fn reset_game_shark(&mut self) {
let rom = self.mmu().rom();
if rom.game_shark().is_some() {
rom.game_shark_mut().as_mut().unwrap().reset();
}
}
#[cfg(feature = "wasm")]
#[cfg_attr(feature = "wasm", wasm_bindgen)]
impl GameBoy {
pub fn set_panic_hook_ws() {
let prev = take_hook();
set_hook(Box::new(move |info| {
hook_impl(info);
prev(info);
}));
}
pub fn load_rom_ws(&mut self, data: &[u8]) -> Cartridge {
rom.set_rumble_cb(|active| {
rumble_callback(active);
});
rom.clone()
pub fn load_callbacks_ws(&mut self) {
self.set_speed_callback(|speed| {
speed_callback(speed);
});
}
pub fn load_null_ws(&mut self) {
let null = Box::<NullDevice>::default();
self.attach_serial(null);
}
pub fn load_logger_ws(&mut self) {
let mut logger = Box::<StdoutDevice>::default();
logger.set_callback(|data| {
logger_callback(data.to_vec());
});
self.attach_serial(logger);
}
pub fn load_printer_ws(&mut self) {
let mut printer = Box::<PrinterDevice>::default();
printer.set_callback(|image_buffer| {
printer_callback(image_buffer.to_vec());
});
self.attach_serial(printer);
}
/// Updates the emulation mode using the cartridge
/// of the provided data to obtain the CGB flag value.
pub fn infer_mode_ws(&mut self, data: &[u8]) {
let mode = Cartridge::from_data(data).gb_mode();
self.set_mode(mode);
}
pub fn set_palette_colors_ws(&mut self, value: Vec<JsValue>) {
let palette: Palette = value
.into_iter()
.try_into()
.unwrap();
self.ppu().set_palette_colors(&palette);
}
pub fn wasm_engine_ws(&self) -> Option<String> {
let dependencies = dependencies_map();
if !dependencies.contains_key("wasm-bindgen") {
Some(String::from(format!(
"wasm-bindgen/{}",
*dependencies.get("wasm-bindgen").unwrap()
value
.as_string()
.unwrap()
.chars()
.collect::<Vec<char>>()
.chunks(2)
.map(|s| s.iter().collect::<String>())
.map(|s| u8::from_str_radix(&s, 16).unwrap())
.collect::<Vec<u8>>()
.try_into()
.unwrap()
}
#[cfg(feature = "wasm")]
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = window)]
#[wasm_bindgen(js_namespace = window, js_name = speedCallback)]
fn speed_callback(speed: GameBoySpeed);
#[wasm_bindgen(js_namespace = window, js_name = loggerCallback)]
fn logger_callback(data: Vec<u8>);
#[wasm_bindgen(js_namespace = window, js_name = printerCallback)]
fn printer_callback(image_buffer: Vec<u8>);
#[wasm_bindgen(js_namespace = window, js_name = rumbleCallback)]
fn rumble_callback(active: bool);
}
#[cfg(feature = "wasm")]
pub fn hook_impl(info: &PanicInfo) {
let message = info.to_string();
panic(message.as_str());
impl AudioProvider for GameBoy {
fn audio_buffer(&self) -> &VecDeque<u8> {
fn clear_audio_buffer(&mut self) {
impl Default for GameBoy {
fn default() -> Self {
impl Display for GameBoy {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.description(9))
}
}