Compare commits
5 Commits
de0d147685
...
6265c8af04
Author | SHA1 | Date |
---|---|---|
Rekai Nyangadzayi Musuka | 6265c8af04 | |
Rekai Nyangadzayi Musuka | 5482a8e75f | |
Rekai Nyangadzayi Musuka | 002dae6826 | |
Rekai Nyangadzayi Musuka | c863dc835c | |
Rekai Nyangadzayi Musuka | d4407cf849 |
14
src/apu.rs
14
src/apu.rs
|
@ -154,8 +154,11 @@ impl Apu {
|
||||||
let ch4_left = self.ctrl.output.ch4_left() as u8 as f32 * ch4_amplitude;
|
let ch4_left = self.ctrl.output.ch4_left() as u8 as f32 * ch4_amplitude;
|
||||||
let ch4_right = self.ctrl.output.ch4_right() as u8 as f32 * ch4_amplitude;
|
let ch4_right = self.ctrl.output.ch4_right() as u8 as f32 * ch4_amplitude;
|
||||||
|
|
||||||
let left = (ch1_left + ch2_left + ch3_left + ch4_left) / 4.0;
|
let left_mixed = (ch1_left + ch2_left + ch3_left + ch4_left) / 4.0;
|
||||||
let right = (ch1_right + ch2_right + ch3_right + ch4_right) / 4.0;
|
let right_mixed = (ch1_right + ch2_right + ch3_right + ch4_right) / 4.0;
|
||||||
|
|
||||||
|
let left = (self.ctrl.channel.left_volume() + 1.0) * left_mixed;
|
||||||
|
let right = (self.ctrl.channel.right_volume() + 1.0) * right_mixed;
|
||||||
|
|
||||||
prod.push(left)
|
prod.push(left)
|
||||||
.and(prod.push(right))
|
.and(prod.push(right))
|
||||||
|
@ -660,7 +663,7 @@ pub(crate) struct Channel3 {
|
||||||
impl BusIo for Channel3 {
|
impl BusIo for Channel3 {
|
||||||
fn read_byte(&self, addr: u16) -> u8 {
|
fn read_byte(&self, addr: u16) -> u8 {
|
||||||
if self.enabled {
|
if self.enabled {
|
||||||
self.wave_ram[self.offset as usize]
|
self.wave_ram[self.offset as usize / 2]
|
||||||
} else {
|
} else {
|
||||||
self.wave_ram[(addr - Self::WAVE_RAM_START_ADDR) as usize]
|
self.wave_ram[(addr - Self::WAVE_RAM_START_ADDR) as usize]
|
||||||
}
|
}
|
||||||
|
@ -668,7 +671,7 @@ impl BusIo for Channel3 {
|
||||||
|
|
||||||
fn write_byte(&mut self, addr: u16, byte: u8) {
|
fn write_byte(&mut self, addr: u16, byte: u8) {
|
||||||
if self.enabled {
|
if self.enabled {
|
||||||
self.wave_ram[self.offset as usize] = byte;
|
self.wave_ram[self.offset as usize / 2] = byte;
|
||||||
} else {
|
} else {
|
||||||
self.wave_ram[(addr - Self::WAVE_RAM_START_ADDR) as usize] = byte;
|
self.wave_ram[(addr - Self::WAVE_RAM_START_ADDR) as usize] = byte;
|
||||||
}
|
}
|
||||||
|
@ -742,7 +745,8 @@ impl Channel3 {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn amplitude(&self) -> f32 {
|
fn amplitude(&self) -> f32 {
|
||||||
let dac_input = self.read_sample(self.offset) >> self.volume.shift_count();
|
let dac_input =
|
||||||
|
(self.read_sample(self.offset) >> self.volume.shift_count()) * self.enabled as u8;
|
||||||
|
|
||||||
(dac_input as f32 / 7.5) - 1.0
|
(dac_input as f32 / 7.5) - 1.0
|
||||||
}
|
}
|
||||||
|
|
|
@ -503,10 +503,20 @@ impl From<SoundOutput> for u8 {
|
||||||
bitfield! {
|
bitfield! {
|
||||||
pub struct ChannelControl(u8);
|
pub struct ChannelControl(u8);
|
||||||
impl Debug;
|
impl Debug;
|
||||||
vin_so2, _: 7;
|
vin_left, _: 7;
|
||||||
so2_level, _: 6, 4;
|
_left_volume, _: 6, 4;
|
||||||
vin_so1, _: 3;
|
vin_right, _: 3;
|
||||||
so1_level, _: 2, 0;
|
_right_volume, _: 2, 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChannelControl {
|
||||||
|
pub(crate) fn left_volume(&self) -> f32 {
|
||||||
|
self._left_volume() as f32
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn right_volume(&self) -> f32 {
|
||||||
|
self._right_volume() as f32
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Copy for ChannelControl {}
|
impl Copy for ChannelControl {}
|
||||||
|
|
26
src/emu.rs
26
src/emu.rs
|
@ -11,7 +11,7 @@ pub const SM83_CYCLE_TIME: Duration = Duration::from_nanos(1_000_000_000 / SM83_
|
||||||
pub const CYCLES_IN_FRAME: Cycle = Cycle::new(456 * 154); // 456 Cycles times 154 scanlines
|
pub const CYCLES_IN_FRAME: Cycle = Cycle::new(456 * 154); // 456 Cycles times 154 scanlines
|
||||||
pub(crate) const SM83_CLOCK_SPEED: u64 = 0x40_0000; // Hz which is 4.194304Mhz
|
pub(crate) const SM83_CLOCK_SPEED: u64 = 0x40_0000; // Hz which is 4.194304Mhz
|
||||||
const DEFAULT_TITLE: &str = "DMG-01 Emulator";
|
const DEFAULT_TITLE: &str = "DMG-01 Emulator";
|
||||||
const GAMEPAD_ENABLED: bool = false;
|
const GAMEPAD_ENABLED: bool = true;
|
||||||
|
|
||||||
pub fn init(boot_path: Option<&str>, rom_path: &str) -> Result<SM83> {
|
pub fn init(boot_path: Option<&str>, rom_path: &str) -> Result<SM83> {
|
||||||
let mut cpu = match boot_path {
|
let mut cpu = match boot_path {
|
||||||
|
@ -37,14 +37,14 @@ pub fn run(
|
||||||
) -> Cycle {
|
) -> Cycle {
|
||||||
let mut elapsed = Cycle::new(0);
|
let mut elapsed = Cycle::new(0);
|
||||||
|
|
||||||
while elapsed < target {
|
if GAMEPAD_ENABLED {
|
||||||
if GAMEPAD_ENABLED {
|
if let Some(event) = gamepad.next_event() {
|
||||||
if let Some(event) = gamepad.next_event() {
|
joypad::handle_gamepad_input(game_boy.joypad_mut(), event);
|
||||||
joypad::handle_gamepad_input(game_boy.joypad_mut(), event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
joypad::handle_keyboard_input(game_boy.joypad_mut(), input);
|
joypad::handle_keyboard_input(game_boy.joypad_mut(), input);
|
||||||
|
while elapsed < target {
|
||||||
elapsed += game_boy.step();
|
elapsed += game_boy.step();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,14 +54,14 @@ pub fn run(
|
||||||
pub fn run_frame(game_boy: &mut SM83, gamepad: &mut Gilrs, input: &WinitInputHelper) -> Cycle {
|
pub fn run_frame(game_boy: &mut SM83, gamepad: &mut Gilrs, input: &WinitInputHelper) -> Cycle {
|
||||||
let mut elapsed = Cycle::new(0);
|
let mut elapsed = Cycle::new(0);
|
||||||
|
|
||||||
while elapsed < CYCLES_IN_FRAME {
|
if GAMEPAD_ENABLED {
|
||||||
if GAMEPAD_ENABLED {
|
if let Some(event) = gamepad.next_event() {
|
||||||
if let Some(event) = gamepad.next_event() {
|
joypad::handle_gamepad_input(game_boy.joypad_mut(), event);
|
||||||
joypad::handle_gamepad_input(game_boy.joypad_mut(), event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
joypad::handle_keyboard_input(game_boy.joypad_mut(), input);
|
joypad::handle_keyboard_input(game_boy.joypad_mut(), input);
|
||||||
|
while elapsed < CYCLES_IN_FRAME {
|
||||||
elapsed += game_boy.step();
|
elapsed += game_boy.step();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -120,49 +120,57 @@ pub fn handle_keyboard_input(pad: &mut Joypad, input: &WinitInputHelper) {
|
||||||
|
|
||||||
if input.key_pressed(VirtualKeyCode::Down) {
|
if input.key_pressed(VirtualKeyCode::Down) {
|
||||||
state.dpad_down.update(true, irq);
|
state.dpad_down.update(true, irq);
|
||||||
} else if input.key_released(VirtualKeyCode::Down) {
|
}
|
||||||
|
if input.key_released(VirtualKeyCode::Down) {
|
||||||
state.dpad_down.update(false, irq);
|
state.dpad_down.update(false, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.key_pressed(VirtualKeyCode::Up) {
|
if input.key_pressed(VirtualKeyCode::Up) {
|
||||||
state.dpad_up.update(true, irq);
|
state.dpad_up.update(true, irq);
|
||||||
} else if input.key_released(VirtualKeyCode::Up) {
|
}
|
||||||
|
if input.key_released(VirtualKeyCode::Up) {
|
||||||
state.dpad_up.update(false, irq);
|
state.dpad_up.update(false, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.key_pressed(VirtualKeyCode::Left) {
|
if input.key_pressed(VirtualKeyCode::Left) {
|
||||||
state.dpad_left.update(true, irq);
|
state.dpad_left.update(true, irq);
|
||||||
} else if input.key_released(VirtualKeyCode::Left) {
|
}
|
||||||
|
if input.key_released(VirtualKeyCode::Left) {
|
||||||
state.dpad_left.update(false, irq);
|
state.dpad_left.update(false, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.key_pressed(VirtualKeyCode::Right) {
|
if input.key_pressed(VirtualKeyCode::Right) {
|
||||||
state.dpad_right.update(true, irq);
|
state.dpad_right.update(true, irq);
|
||||||
} else if input.key_released(VirtualKeyCode::Right) {
|
}
|
||||||
|
if input.key_released(VirtualKeyCode::Right) {
|
||||||
state.dpad_right.update(false, irq);
|
state.dpad_right.update(false, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.key_pressed(VirtualKeyCode::T) {
|
if input.key_pressed(VirtualKeyCode::T) {
|
||||||
state.start.update(true, irq);
|
state.start.update(true, irq);
|
||||||
} else if input.key_released(VirtualKeyCode::T) {
|
}
|
||||||
|
if input.key_released(VirtualKeyCode::T) {
|
||||||
state.start.update(false, irq);
|
state.start.update(false, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.key_pressed(VirtualKeyCode::Y) {
|
if input.key_pressed(VirtualKeyCode::Y) {
|
||||||
state.select.update(true, irq);
|
state.select.update(true, irq);
|
||||||
} else if input.key_released(VirtualKeyCode::Y) {
|
}
|
||||||
|
if input.key_released(VirtualKeyCode::Y) {
|
||||||
state.select.update(false, irq);
|
state.select.update(false, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.key_pressed(VirtualKeyCode::Z) {
|
if input.key_pressed(VirtualKeyCode::Z) {
|
||||||
state.south.update(true, irq);
|
state.south.update(true, irq);
|
||||||
} else if input.key_released(VirtualKeyCode::Z) {
|
}
|
||||||
|
if input.key_released(VirtualKeyCode::Z) {
|
||||||
state.south.update(false, irq);
|
state.south.update(false, irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.key_pressed(VirtualKeyCode::X) {
|
if input.key_pressed(VirtualKeyCode::X) {
|
||||||
state.east.update(true, irq);
|
state.east.update(true, irq);
|
||||||
} else if input.key_released(VirtualKeyCode::X) {
|
}
|
||||||
|
if input.key_released(VirtualKeyCode::X) {
|
||||||
state.east.update(false, irq);
|
state.east.update(false, irq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue