From 08a7cd966af693edbe068df9e32f8d47c8a6f947 Mon Sep 17 00:00:00 2001 From: Michel Heily Date: Wed, 30 Sep 2020 00:10:47 +0300 Subject: [PATCH] core: add "no_video_interface" feature Former-commit-id: 0b1462e3ef1ab65c37e2c0fce54bc7f5c2f9f2b5 Former-commit-id: 7b837be4dcb477b048f0118c4ab30f97eb445363 --- core/Cargo.toml | 2 ++ core/src/gba.rs | 11 ++++++++++- core/src/gpu/mod.rs | 19 ++++++++++++++++--- core/src/lib.rs | 5 ++++- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/core/Cargo.toml b/core/Cargo.toml index 9e48653..a14d229 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -58,3 +58,5 @@ elf_support = ["goblin"] # Uses lookup tables when executing instructions instead of `match` statements. # Faster, but consumes more memory. arm7tdmi_dispatch_table = [] +# For use for ports where VideoInterface is not needed like wasm & jni +no_video_interface = [] \ No newline at end of file diff --git a/core/src/gba.rs b/core/src/gba.rs index ece9b80..e9caee7 100644 --- a/core/src/gba.rs +++ b/core/src/gba.rs @@ -15,12 +15,15 @@ use super::sound::SoundController; use super::sysbus::SysBus; use super::timer::Timers; -use super::{AudioInterface, InputInterface, VideoInterface}; +use super::{AudioInterface, InputInterface}; +#[cfg(not(feature = "no_video_interface"))] +use super::VideoInterface; pub struct GameBoyAdvance { pub sysbus: Box, pub cpu: arm7tdmi::Core, + #[cfg(not(feature = "no_video_interface"))] pub video_device: Rc>, pub audio_device: Rc>, pub input_device: Rc>, @@ -55,6 +58,7 @@ impl GameBoyAdvance { pub fn new( bios_rom: Box<[u8]>, gamepak: Cartridge, + #[cfg(not(feature = "no_video_interface"))] video_device: Rc>, audio_device: Rc>, input_device: Rc>, @@ -83,6 +87,7 @@ impl GameBoyAdvance { cpu: cpu, sysbus: sysbus, + #[cfg(not(feature = "no_video_interface"))] video_device: video_device, audio_device: audio_device, input_device: input_device, @@ -99,6 +104,7 @@ impl GameBoyAdvance { pub fn from_saved_state( savestate: &[u8], + #[cfg(not(feature = "no_video_interface"))] video_device: Rc>, audio_device: Rc>, input_device: Rc>, @@ -117,6 +123,7 @@ impl GameBoyAdvance { interrupt_flags: interrupts, + #[cfg(not(feature = "no_video_interface"))] video_device: video_device, audio_device: audio_device, input_device: input_device, @@ -258,6 +265,7 @@ impl GameBoyAdvance { cycles, &mut cycles_to_next_event, self.sysbus.as_mut(), + #[cfg(not(feature = "no_video_interface"))] &self.video_device, ); io.sound @@ -292,6 +300,7 @@ impl GameBoyAdvance { cycles, &mut _ignored, self.sysbus.as_mut(), + #[cfg(not(feature = "no_video_interface"))] &self.video_device, ); io.sound.update(cycles, &mut _ignored, &self.audio_device); diff --git a/core/src/gpu/mod.rs b/core/src/gpu/mod.rs index f2e07ae..7a3e127 100644 --- a/core/src/gpu/mod.rs +++ b/core/src/gpu/mod.rs @@ -1,5 +1,7 @@ +#[cfg(not(feature = "no_video_interface"))] use std::cell::RefCell; use std::fmt; +#[cfg(not(feature = "no_video_interface"))] use std::rc::Rc; use serde::{Deserialize, Serialize}; @@ -9,6 +11,7 @@ use super::dma::{DmaNotifer, TIMING_HBLANK, TIMING_VBLANK}; use super::interrupt::{self, Interrupt, InterruptConnect, SharedInterruptFlags}; pub use super::sysbus::consts::*; use super::util::BoxedMemory; +#[cfg(not(feature = "no_video_interface"))] use super::VideoInterface; use crate::bitfield::Bit; @@ -172,6 +175,7 @@ impl Default for ObjBufferEntry { } } +#[cfg(not(feature = "no_video_interface"))] type VideoDeviceRcRefCell = Rc>; #[derive(Serialize, Deserialize, Clone, DebugStub)] @@ -414,7 +418,7 @@ impl Gpu { &mut self, completed: GpuState, dma_notifier: &mut D, - video_device: &VideoDeviceRcRefCell, + #[cfg(not(feature = "no_video_interface"))] video_device: &VideoDeviceRcRefCell, ) where D: DmaNotifer, { @@ -470,7 +474,10 @@ impl Gpu { }; dma_notifier.notify(TIMING_VBLANK); + + #[cfg(not(feature = "no_video_interface"))] video_device.borrow_mut().render(&self.frame_buffer); + self.obj_buffer_reset(); self.cycles_left_for_current_state = CYCLES_HDRAW; self.state = VBlankHDraw; @@ -508,14 +515,19 @@ impl Gpu { mut cycles: usize, cycles_to_next_event: &mut usize, dma_notifier: &mut D, - video_device: &VideoDeviceRcRefCell, + #[cfg(not(feature = "no_video_interface"))] video_device: &VideoDeviceRcRefCell, ) where D: DmaNotifer, { loop { if self.cycles_left_for_current_state <= cycles { cycles -= self.cycles_left_for_current_state; - self.on_state_completed(self.state, dma_notifier, video_device); + self.on_state_completed( + self.state, + dma_notifier, + #[cfg(not(feature = "no_video_interface"))] + video_device, + ); } else { self.cycles_left_for_current_state -= cycles; break; @@ -638,6 +650,7 @@ mod tests { $cycles, &mut cycles_to_next_event, &mut dma_notifier, + #[cfg(not(feature = "no_video_interface"))] &video_clone, ); total_cycles += $cycles; diff --git a/core/src/lib.rs b/core/src/lib.rs index 62d43aa..f3f3e80 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -59,6 +59,7 @@ pub mod gdb; #[cfg(feature = "debugger")] pub mod debugger; +#[cfg(not(feature = "no_video_interface"))] pub trait VideoInterface { #[allow(unused_variables)] fn render(&mut self, buffer: &[u32]) {} @@ -133,6 +134,8 @@ pub mod prelude { pub use super::gpu::{DISPLAY_HEIGHT, DISPLAY_WIDTH}; pub use super::util::{read_bin_file, write_bin_file}; pub use super::Bus; - pub use super::{AudioInterface, InputInterface, StereoSample, VideoInterface}; + pub use super::{AudioInterface, InputInterface, StereoSample}; + #[cfg(not(feature = "no_video_interface"))] + pub use super::VideoInterface; pub use super::{GBAError, GBAResult, GameBoyAdvance}; }