core: gba: Move VideoInterface & AudioInterface to GameBoyAdvance
In preparation for savestates, this is needed to avoid (de)serializing Rc<RefCell>'s Former-commit-id: c6dfe189d4f6104fc4b1b567529ec50714a2d74e
This commit is contained in:
parent
236dd601a9
commit
16142ee99d
|
@ -15,6 +15,9 @@ use super::super::{AudioInterface, InputInterface, VideoInterface};
|
|||
pub struct GameBoyAdvance {
|
||||
pub sysbus: Box<SysBus>,
|
||||
pub cpu: Core,
|
||||
|
||||
video_device: Rc<RefCell<dyn VideoInterface>>,
|
||||
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
||||
input_device: Rc<RefCell<dyn InputInterface>>,
|
||||
|
||||
cycles_to_next_event: usize,
|
||||
|
@ -29,12 +32,17 @@ impl GameBoyAdvance {
|
|||
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
||||
input_device: Rc<RefCell<dyn InputInterface>>,
|
||||
) -> GameBoyAdvance {
|
||||
let gpu = Box::new(Gpu::new(video_device));
|
||||
let sound_controller = Box::new(SoundController::new(audio_device));
|
||||
let gpu = Box::new(Gpu::new());
|
||||
let sound_controller = Box::new(SoundController::new(
|
||||
audio_device.borrow().get_sample_rate() as f32,
|
||||
));
|
||||
let io = IoDevices::new(gpu, sound_controller);
|
||||
GameBoyAdvance {
|
||||
cpu: cpu,
|
||||
sysbus: Box::new(SysBus::new(io, bios_rom, gamepak)),
|
||||
|
||||
video_device: video_device,
|
||||
audio_device: audio_device,
|
||||
input_device: input_device,
|
||||
|
||||
cycles_to_next_event: 1,
|
||||
|
@ -138,8 +146,10 @@ impl GameBoyAdvance {
|
|||
&mut self.sysbus,
|
||||
&mut irqs,
|
||||
&mut cycles_to_next_event,
|
||||
&self.video_device,
|
||||
);
|
||||
io.sound.update(cycles, &mut cycles_to_next_event);
|
||||
io.sound
|
||||
.update(cycles, &mut cycles_to_next_event, &self.audio_device);
|
||||
self.cycles_to_next_event = cycles_to_next_event;
|
||||
io.intc.request_irqs(irqs);
|
||||
}
|
||||
|
|
|
@ -184,8 +184,6 @@ type VideoDeviceRcRefCell = Rc<RefCell<dyn VideoInterface>>;
|
|||
|
||||
#[derive(DebugStub)]
|
||||
pub struct Gpu {
|
||||
#[debug_stub = "video handle"]
|
||||
video_device: VideoDeviceRcRefCell,
|
||||
pub state: GpuState,
|
||||
|
||||
/// how many cycles left until next gpu state ?
|
||||
|
@ -221,10 +219,8 @@ pub struct Gpu {
|
|||
}
|
||||
|
||||
impl Gpu {
|
||||
pub fn new(video_device: VideoDeviceRcRefCell) -> Gpu {
|
||||
pub fn new() -> Gpu {
|
||||
Gpu {
|
||||
video_device: video_device,
|
||||
|
||||
dispcnt: DisplayControl(0x80),
|
||||
dispstat: DisplayStatus(0),
|
||||
bg: [
|
||||
|
@ -377,6 +373,7 @@ impl Gpu {
|
|||
completed: GpuState,
|
||||
sb: &mut SysBus,
|
||||
irqs: &mut IrqBitmask,
|
||||
video_device: &VideoDeviceRcRefCell,
|
||||
) {
|
||||
match self.state {
|
||||
HDraw => {
|
||||
|
@ -419,7 +416,7 @@ impl Gpu {
|
|||
};
|
||||
|
||||
sb.io.dmac.notify_vblank();
|
||||
self.video_device.borrow_mut().render(&self.frame_buffer);
|
||||
video_device.borrow_mut().render(&self.frame_buffer);
|
||||
self.cycles_left_for_current_state = CYCLES_SCANLINE;
|
||||
}
|
||||
}
|
||||
|
@ -446,11 +443,12 @@ impl Gpu {
|
|||
sb: &mut SysBus,
|
||||
irqs: &mut IrqBitmask,
|
||||
cycles_to_next_event: &mut usize,
|
||||
video_device: &VideoDeviceRcRefCell,
|
||||
) {
|
||||
if self.cycles_left_for_current_state <= cycles {
|
||||
let overshoot = cycles - self.cycles_left_for_current_state;
|
||||
|
||||
self.on_state_completed(self.state, sb, irqs);
|
||||
self.on_state_completed(self.state, sb, irqs, video_device);
|
||||
|
||||
// handle the overshoot
|
||||
if overshoot < self.cycles_left_for_current_state {
|
||||
|
|
|
@ -64,9 +64,6 @@ type AudioDeviceRcRefCell = Rc<RefCell<dyn AudioInterface>>;
|
|||
|
||||
#[derive(DebugStub)]
|
||||
pub struct SoundController {
|
||||
#[debug_stub = "AudioDeviceRcRefCell"]
|
||||
audio_device: AudioDeviceRcRefCell,
|
||||
|
||||
sample_rate_to_cpu_freq: usize, // how many "cycles" are a sample?
|
||||
cycles: usize, // cycles count when we last provided a new sample.
|
||||
|
||||
|
@ -107,12 +104,9 @@ pub struct SoundController {
|
|||
}
|
||||
|
||||
impl SoundController {
|
||||
pub fn new(audio_device: AudioDeviceRcRefCell) -> SoundController {
|
||||
let resampler =
|
||||
CosineResampler::new(32768_f32, audio_device.borrow().get_sample_rate() as f32);
|
||||
pub fn new(audio_device_sample_rate: f32) -> SoundController {
|
||||
let resampler = CosineResampler::new(32768_f32, audio_device_sample_rate);
|
||||
SoundController {
|
||||
audio_device: audio_device,
|
||||
|
||||
sample_rate_to_cpu_freq: 12345,
|
||||
cycles: 0,
|
||||
mse: false,
|
||||
|
@ -321,7 +315,12 @@ impl SoundController {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, cycles: usize, cycles_to_next_event: &mut usize) {
|
||||
pub fn update(
|
||||
&mut self,
|
||||
cycles: usize,
|
||||
cycles_to_next_event: &mut usize,
|
||||
audio_device: &AudioDeviceRcRefCell,
|
||||
) {
|
||||
self.cycles += cycles;
|
||||
while self.cycles >= self.cycles_per_sample {
|
||||
self.cycles -= self.cycles_per_sample;
|
||||
|
@ -338,7 +337,7 @@ impl SoundController {
|
|||
}
|
||||
}
|
||||
|
||||
let mut audio = self.audio_device.borrow_mut();
|
||||
let mut audio = audio_device.borrow_mut();
|
||||
self.resampler
|
||||
.push_sample((sample[0], sample[1]), &mut *audio);
|
||||
}
|
||||
|
|
Reference in a new issue