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
3 changed files with 27 additions and 20 deletions
|
@ -15,6 +15,9 @@ use super::super::{AudioInterface, InputInterface, VideoInterface};
|
||||||
pub struct GameBoyAdvance {
|
pub struct GameBoyAdvance {
|
||||||
pub sysbus: Box<SysBus>,
|
pub sysbus: Box<SysBus>,
|
||||||
pub cpu: Core,
|
pub cpu: Core,
|
||||||
|
|
||||||
|
video_device: Rc<RefCell<dyn VideoInterface>>,
|
||||||
|
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
||||||
input_device: Rc<RefCell<dyn InputInterface>>,
|
input_device: Rc<RefCell<dyn InputInterface>>,
|
||||||
|
|
||||||
cycles_to_next_event: usize,
|
cycles_to_next_event: usize,
|
||||||
|
@ -29,12 +32,17 @@ impl GameBoyAdvance {
|
||||||
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
||||||
input_device: Rc<RefCell<dyn InputInterface>>,
|
input_device: Rc<RefCell<dyn InputInterface>>,
|
||||||
) -> GameBoyAdvance {
|
) -> GameBoyAdvance {
|
||||||
let gpu = Box::new(Gpu::new(video_device));
|
let gpu = Box::new(Gpu::new());
|
||||||
let sound_controller = Box::new(SoundController::new(audio_device));
|
let sound_controller = Box::new(SoundController::new(
|
||||||
|
audio_device.borrow().get_sample_rate() as f32,
|
||||||
|
));
|
||||||
let io = IoDevices::new(gpu, sound_controller);
|
let io = IoDevices::new(gpu, sound_controller);
|
||||||
GameBoyAdvance {
|
GameBoyAdvance {
|
||||||
cpu: cpu,
|
cpu: cpu,
|
||||||
sysbus: Box::new(SysBus::new(io, bios_rom, gamepak)),
|
sysbus: Box::new(SysBus::new(io, bios_rom, gamepak)),
|
||||||
|
|
||||||
|
video_device: video_device,
|
||||||
|
audio_device: audio_device,
|
||||||
input_device: input_device,
|
input_device: input_device,
|
||||||
|
|
||||||
cycles_to_next_event: 1,
|
cycles_to_next_event: 1,
|
||||||
|
@ -138,8 +146,10 @@ impl GameBoyAdvance {
|
||||||
&mut self.sysbus,
|
&mut self.sysbus,
|
||||||
&mut irqs,
|
&mut irqs,
|
||||||
&mut cycles_to_next_event,
|
&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;
|
self.cycles_to_next_event = cycles_to_next_event;
|
||||||
io.intc.request_irqs(irqs);
|
io.intc.request_irqs(irqs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,8 +184,6 @@ type VideoDeviceRcRefCell = Rc<RefCell<dyn VideoInterface>>;
|
||||||
|
|
||||||
#[derive(DebugStub)]
|
#[derive(DebugStub)]
|
||||||
pub struct Gpu {
|
pub struct Gpu {
|
||||||
#[debug_stub = "video handle"]
|
|
||||||
video_device: VideoDeviceRcRefCell,
|
|
||||||
pub state: GpuState,
|
pub state: GpuState,
|
||||||
|
|
||||||
/// how many cycles left until next gpu state ?
|
/// how many cycles left until next gpu state ?
|
||||||
|
@ -221,10 +219,8 @@ pub struct Gpu {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gpu {
|
impl Gpu {
|
||||||
pub fn new(video_device: VideoDeviceRcRefCell) -> Gpu {
|
pub fn new() -> Gpu {
|
||||||
Gpu {
|
Gpu {
|
||||||
video_device: video_device,
|
|
||||||
|
|
||||||
dispcnt: DisplayControl(0x80),
|
dispcnt: DisplayControl(0x80),
|
||||||
dispstat: DisplayStatus(0),
|
dispstat: DisplayStatus(0),
|
||||||
bg: [
|
bg: [
|
||||||
|
@ -377,6 +373,7 @@ impl Gpu {
|
||||||
completed: GpuState,
|
completed: GpuState,
|
||||||
sb: &mut SysBus,
|
sb: &mut SysBus,
|
||||||
irqs: &mut IrqBitmask,
|
irqs: &mut IrqBitmask,
|
||||||
|
video_device: &VideoDeviceRcRefCell,
|
||||||
) {
|
) {
|
||||||
match self.state {
|
match self.state {
|
||||||
HDraw => {
|
HDraw => {
|
||||||
|
@ -419,7 +416,7 @@ impl Gpu {
|
||||||
};
|
};
|
||||||
|
|
||||||
sb.io.dmac.notify_vblank();
|
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;
|
self.cycles_left_for_current_state = CYCLES_SCANLINE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -446,11 +443,12 @@ impl Gpu {
|
||||||
sb: &mut SysBus,
|
sb: &mut SysBus,
|
||||||
irqs: &mut IrqBitmask,
|
irqs: &mut IrqBitmask,
|
||||||
cycles_to_next_event: &mut usize,
|
cycles_to_next_event: &mut usize,
|
||||||
|
video_device: &VideoDeviceRcRefCell,
|
||||||
) {
|
) {
|
||||||
if self.cycles_left_for_current_state <= cycles {
|
if self.cycles_left_for_current_state <= cycles {
|
||||||
let overshoot = cycles - self.cycles_left_for_current_state;
|
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
|
// handle the overshoot
|
||||||
if overshoot < self.cycles_left_for_current_state {
|
if overshoot < self.cycles_left_for_current_state {
|
||||||
|
|
|
@ -64,9 +64,6 @@ type AudioDeviceRcRefCell = Rc<RefCell<dyn AudioInterface>>;
|
||||||
|
|
||||||
#[derive(DebugStub)]
|
#[derive(DebugStub)]
|
||||||
pub struct SoundController {
|
pub struct SoundController {
|
||||||
#[debug_stub = "AudioDeviceRcRefCell"]
|
|
||||||
audio_device: AudioDeviceRcRefCell,
|
|
||||||
|
|
||||||
sample_rate_to_cpu_freq: usize, // how many "cycles" are a sample?
|
sample_rate_to_cpu_freq: usize, // how many "cycles" are a sample?
|
||||||
cycles: usize, // cycles count when we last provided a new sample.
|
cycles: usize, // cycles count when we last provided a new sample.
|
||||||
|
|
||||||
|
@ -107,12 +104,9 @@ pub struct SoundController {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SoundController {
|
impl SoundController {
|
||||||
pub fn new(audio_device: AudioDeviceRcRefCell) -> SoundController {
|
pub fn new(audio_device_sample_rate: f32) -> SoundController {
|
||||||
let resampler =
|
let resampler = CosineResampler::new(32768_f32, audio_device_sample_rate);
|
||||||
CosineResampler::new(32768_f32, audio_device.borrow().get_sample_rate() as f32);
|
|
||||||
SoundController {
|
SoundController {
|
||||||
audio_device: audio_device,
|
|
||||||
|
|
||||||
sample_rate_to_cpu_freq: 12345,
|
sample_rate_to_cpu_freq: 12345,
|
||||||
cycles: 0,
|
cycles: 0,
|
||||||
mse: false,
|
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;
|
self.cycles += cycles;
|
||||||
while self.cycles >= self.cycles_per_sample {
|
while self.cycles >= self.cycles_per_sample {
|
||||||
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
|
self.resampler
|
||||||
.push_sample((sample[0], sample[1]), &mut *audio);
|
.push_sample((sample[0], sample[1]), &mut *audio);
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue