core: add "no_video_interface" feature
Former-commit-id: 0b1462e3ef1ab65c37e2c0fce54bc7f5c2f9f2b5 Former-commit-id: 7b837be4dcb477b048f0118c4ab30f97eb445363
This commit is contained in:
parent
e25268f4d8
commit
08a7cd966a
|
@ -58,3 +58,5 @@ elf_support = ["goblin"]
|
||||||
# Uses lookup tables when executing instructions instead of `match` statements.
|
# Uses lookup tables when executing instructions instead of `match` statements.
|
||||||
# Faster, but consumes more memory.
|
# Faster, but consumes more memory.
|
||||||
arm7tdmi_dispatch_table = []
|
arm7tdmi_dispatch_table = []
|
||||||
|
# For use for ports where VideoInterface is not needed like wasm & jni
|
||||||
|
no_video_interface = []
|
|
@ -15,12 +15,15 @@ use super::sound::SoundController;
|
||||||
use super::sysbus::SysBus;
|
use super::sysbus::SysBus;
|
||||||
use super::timer::Timers;
|
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 struct GameBoyAdvance {
|
||||||
pub sysbus: Box<SysBus>,
|
pub sysbus: Box<SysBus>,
|
||||||
pub cpu: arm7tdmi::Core,
|
pub cpu: arm7tdmi::Core,
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
pub video_device: Rc<RefCell<dyn VideoInterface>>,
|
pub video_device: Rc<RefCell<dyn VideoInterface>>,
|
||||||
pub audio_device: Rc<RefCell<dyn AudioInterface>>,
|
pub audio_device: Rc<RefCell<dyn AudioInterface>>,
|
||||||
pub input_device: Rc<RefCell<dyn InputInterface>>,
|
pub input_device: Rc<RefCell<dyn InputInterface>>,
|
||||||
|
@ -55,6 +58,7 @@ impl GameBoyAdvance {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
bios_rom: Box<[u8]>,
|
bios_rom: Box<[u8]>,
|
||||||
gamepak: Cartridge,
|
gamepak: Cartridge,
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
video_device: Rc<RefCell<dyn VideoInterface>>,
|
video_device: Rc<RefCell<dyn VideoInterface>>,
|
||||||
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
||||||
input_device: Rc<RefCell<dyn InputInterface>>,
|
input_device: Rc<RefCell<dyn InputInterface>>,
|
||||||
|
@ -83,6 +87,7 @@ impl GameBoyAdvance {
|
||||||
cpu: cpu,
|
cpu: cpu,
|
||||||
sysbus: sysbus,
|
sysbus: sysbus,
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
video_device: video_device,
|
video_device: video_device,
|
||||||
audio_device: audio_device,
|
audio_device: audio_device,
|
||||||
input_device: input_device,
|
input_device: input_device,
|
||||||
|
@ -99,6 +104,7 @@ impl GameBoyAdvance {
|
||||||
|
|
||||||
pub fn from_saved_state(
|
pub fn from_saved_state(
|
||||||
savestate: &[u8],
|
savestate: &[u8],
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
video_device: Rc<RefCell<dyn VideoInterface>>,
|
video_device: Rc<RefCell<dyn VideoInterface>>,
|
||||||
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
||||||
input_device: Rc<RefCell<dyn InputInterface>>,
|
input_device: Rc<RefCell<dyn InputInterface>>,
|
||||||
|
@ -117,6 +123,7 @@ impl GameBoyAdvance {
|
||||||
|
|
||||||
interrupt_flags: interrupts,
|
interrupt_flags: interrupts,
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
video_device: video_device,
|
video_device: video_device,
|
||||||
audio_device: audio_device,
|
audio_device: audio_device,
|
||||||
input_device: input_device,
|
input_device: input_device,
|
||||||
|
@ -258,6 +265,7 @@ impl GameBoyAdvance {
|
||||||
cycles,
|
cycles,
|
||||||
&mut cycles_to_next_event,
|
&mut cycles_to_next_event,
|
||||||
self.sysbus.as_mut(),
|
self.sysbus.as_mut(),
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
&self.video_device,
|
&self.video_device,
|
||||||
);
|
);
|
||||||
io.sound
|
io.sound
|
||||||
|
@ -292,6 +300,7 @@ impl GameBoyAdvance {
|
||||||
cycles,
|
cycles,
|
||||||
&mut _ignored,
|
&mut _ignored,
|
||||||
self.sysbus.as_mut(),
|
self.sysbus.as_mut(),
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
&self.video_device,
|
&self.video_device,
|
||||||
);
|
);
|
||||||
io.sound.update(cycles, &mut _ignored, &self.audio_device);
|
io.sound.update(cycles, &mut _ignored, &self.audio_device);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -9,6 +11,7 @@ use super::dma::{DmaNotifer, TIMING_HBLANK, TIMING_VBLANK};
|
||||||
use super::interrupt::{self, Interrupt, InterruptConnect, SharedInterruptFlags};
|
use super::interrupt::{self, Interrupt, InterruptConnect, SharedInterruptFlags};
|
||||||
pub use super::sysbus::consts::*;
|
pub use super::sysbus::consts::*;
|
||||||
use super::util::BoxedMemory;
|
use super::util::BoxedMemory;
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
use super::VideoInterface;
|
use super::VideoInterface;
|
||||||
|
|
||||||
use crate::bitfield::Bit;
|
use crate::bitfield::Bit;
|
||||||
|
@ -172,6 +175,7 @@ impl Default for ObjBufferEntry {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
type VideoDeviceRcRefCell = Rc<RefCell<dyn VideoInterface>>;
|
type VideoDeviceRcRefCell = Rc<RefCell<dyn VideoInterface>>;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, DebugStub)]
|
#[derive(Serialize, Deserialize, Clone, DebugStub)]
|
||||||
|
@ -414,7 +418,7 @@ impl Gpu {
|
||||||
&mut self,
|
&mut self,
|
||||||
completed: GpuState,
|
completed: GpuState,
|
||||||
dma_notifier: &mut D,
|
dma_notifier: &mut D,
|
||||||
video_device: &VideoDeviceRcRefCell,
|
#[cfg(not(feature = "no_video_interface"))] video_device: &VideoDeviceRcRefCell,
|
||||||
) where
|
) where
|
||||||
D: DmaNotifer,
|
D: DmaNotifer,
|
||||||
{
|
{
|
||||||
|
@ -470,7 +474,10 @@ impl Gpu {
|
||||||
};
|
};
|
||||||
|
|
||||||
dma_notifier.notify(TIMING_VBLANK);
|
dma_notifier.notify(TIMING_VBLANK);
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
video_device.borrow_mut().render(&self.frame_buffer);
|
video_device.borrow_mut().render(&self.frame_buffer);
|
||||||
|
|
||||||
self.obj_buffer_reset();
|
self.obj_buffer_reset();
|
||||||
self.cycles_left_for_current_state = CYCLES_HDRAW;
|
self.cycles_left_for_current_state = CYCLES_HDRAW;
|
||||||
self.state = VBlankHDraw;
|
self.state = VBlankHDraw;
|
||||||
|
@ -508,14 +515,19 @@ impl Gpu {
|
||||||
mut cycles: usize,
|
mut cycles: usize,
|
||||||
cycles_to_next_event: &mut usize,
|
cycles_to_next_event: &mut usize,
|
||||||
dma_notifier: &mut D,
|
dma_notifier: &mut D,
|
||||||
video_device: &VideoDeviceRcRefCell,
|
#[cfg(not(feature = "no_video_interface"))] video_device: &VideoDeviceRcRefCell,
|
||||||
) where
|
) where
|
||||||
D: DmaNotifer,
|
D: DmaNotifer,
|
||||||
{
|
{
|
||||||
loop {
|
loop {
|
||||||
if self.cycles_left_for_current_state <= cycles {
|
if self.cycles_left_for_current_state <= cycles {
|
||||||
cycles -= self.cycles_left_for_current_state;
|
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 {
|
} else {
|
||||||
self.cycles_left_for_current_state -= cycles;
|
self.cycles_left_for_current_state -= cycles;
|
||||||
break;
|
break;
|
||||||
|
@ -638,6 +650,7 @@ mod tests {
|
||||||
$cycles,
|
$cycles,
|
||||||
&mut cycles_to_next_event,
|
&mut cycles_to_next_event,
|
||||||
&mut dma_notifier,
|
&mut dma_notifier,
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
&video_clone,
|
&video_clone,
|
||||||
);
|
);
|
||||||
total_cycles += $cycles;
|
total_cycles += $cycles;
|
||||||
|
|
|
@ -59,6 +59,7 @@ pub mod gdb;
|
||||||
#[cfg(feature = "debugger")]
|
#[cfg(feature = "debugger")]
|
||||||
pub mod debugger;
|
pub mod debugger;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
pub trait VideoInterface {
|
pub trait VideoInterface {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
fn render(&mut self, buffer: &[u32]) {}
|
fn render(&mut self, buffer: &[u32]) {}
|
||||||
|
@ -133,6 +134,8 @@ pub mod prelude {
|
||||||
pub use super::gpu::{DISPLAY_HEIGHT, DISPLAY_WIDTH};
|
pub use super::gpu::{DISPLAY_HEIGHT, DISPLAY_WIDTH};
|
||||||
pub use super::util::{read_bin_file, write_bin_file};
|
pub use super::util::{read_bin_file, write_bin_file};
|
||||||
pub use super::Bus;
|
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};
|
pub use super::{GBAError, GBAResult, GameBoyAdvance};
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue