Deprecate InputDevice trait
Former-commit-id: 4d25e16d0a6a0a55a5204c28230620dba3531e08 Former-commit-id: da149cb9ebb1258693272a4e9daa615902d99e6e
This commit is contained in:
parent
91bb17f6dc
commit
407818d32a
|
@ -9,7 +9,6 @@ use rustboyadvance_core::prelude::*;
|
||||||
|
|
||||||
struct BenchmarkHardware {}
|
struct BenchmarkHardware {}
|
||||||
impl AudioInterface for BenchmarkHardware {}
|
impl AudioInterface for BenchmarkHardware {}
|
||||||
impl InputInterface for BenchmarkHardware {}
|
|
||||||
|
|
||||||
fn create_gba() -> GameBoyAdvance {
|
fn create_gba() -> GameBoyAdvance {
|
||||||
// TODO: do I really want this file in my repository ?
|
// TODO: do I really want this file in my repository ?
|
||||||
|
|
|
@ -15,9 +15,9 @@ use super::sound::SoundController;
|
||||||
use super::sysbus::SysBus;
|
use super::sysbus::SysBus;
|
||||||
use super::timer::Timers;
|
use super::timer::Timers;
|
||||||
|
|
||||||
|
use super::AudioInterface;
|
||||||
#[cfg(not(feature = "no_video_interface"))]
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
use super::VideoInterface;
|
use super::VideoInterface;
|
||||||
use super::{AudioInterface, InputInterface};
|
|
||||||
|
|
||||||
use arm7tdmi::{self, Arm7tdmiCore};
|
use arm7tdmi::{self, Arm7tdmiCore};
|
||||||
use rustboyadvance_utils::Shared;
|
use rustboyadvance_utils::Shared;
|
||||||
|
@ -31,7 +31,6 @@ pub struct GameBoyAdvance {
|
||||||
#[cfg(not(feature = "no_video_interface"))]
|
#[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>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
@ -70,7 +69,6 @@ impl GameBoyAdvance {
|
||||||
gamepak: Cartridge,
|
gamepak: Cartridge,
|
||||||
#[cfg(not(feature = "no_video_interface"))] video_device: Rc<RefCell<dyn VideoInterface>>,
|
#[cfg(not(feature = "no_video_interface"))] video_device: Rc<RefCell<dyn VideoInterface>>,
|
||||||
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
||||||
input_device: Rc<RefCell<dyn InputInterface>>,
|
|
||||||
) -> GameBoyAdvance {
|
) -> GameBoyAdvance {
|
||||||
// Warn the user if the bios is not the real one
|
// Warn the user if the bios is not the real one
|
||||||
match check_real_bios(&bios_rom) {
|
match check_real_bios(&bios_rom) {
|
||||||
|
@ -110,14 +108,10 @@ impl GameBoyAdvance {
|
||||||
cpu,
|
cpu,
|
||||||
sysbus,
|
sysbus,
|
||||||
io_devs,
|
io_devs,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_video_interface"))]
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
video_device,
|
video_device,
|
||||||
audio_device,
|
audio_device,
|
||||||
input_device,
|
|
||||||
|
|
||||||
scheduler,
|
scheduler,
|
||||||
|
|
||||||
interrupt_flags,
|
interrupt_flags,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -132,7 +126,6 @@ impl GameBoyAdvance {
|
||||||
rom: Box<[u8]>,
|
rom: Box<[u8]>,
|
||||||
#[cfg(not(feature = "no_video_interface"))] video_device: Rc<RefCell<dyn VideoInterface>>,
|
#[cfg(not(feature = "no_video_interface"))] video_device: Rc<RefCell<dyn VideoInterface>>,
|
||||||
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
audio_device: Rc<RefCell<dyn AudioInterface>>,
|
||||||
input_device: Rc<RefCell<dyn InputInterface>>,
|
|
||||||
) -> bincode::Result<GameBoyAdvance> {
|
) -> bincode::Result<GameBoyAdvance> {
|
||||||
let decoded: Box<SaveState> = bincode::deserialize_from(savestate)?;
|
let decoded: Box<SaveState> = bincode::deserialize_from(savestate)?;
|
||||||
|
|
||||||
|
@ -162,14 +155,10 @@ impl GameBoyAdvance {
|
||||||
cpu: arm7tdmi,
|
cpu: arm7tdmi,
|
||||||
sysbus,
|
sysbus,
|
||||||
io_devs,
|
io_devs,
|
||||||
|
|
||||||
interrupt_flags: interrupts,
|
interrupt_flags: interrupts,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_video_interface"))]
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
video_device,
|
video_device,
|
||||||
audio_device,
|
audio_device,
|
||||||
input_device,
|
|
||||||
|
|
||||||
scheduler,
|
scheduler,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -218,12 +207,16 @@ impl GameBoyAdvance {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn key_poll(&mut self) {
|
pub fn get_key_state(&mut self) -> &u16 {
|
||||||
self.sysbus.io.keyinput = self.input_device.borrow_mut().poll();
|
&self.sysbus.io.keyinput
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn get_key_state_mut(&mut self) -> &mut u16 {
|
||||||
|
&mut self.sysbus.io.keyinput
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn frame(&mut self) {
|
pub fn frame(&mut self) {
|
||||||
self.key_poll();
|
|
||||||
static mut OVERSHOOT: usize = 0;
|
static mut OVERSHOOT: usize = 0;
|
||||||
unsafe {
|
unsafe {
|
||||||
OVERSHOOT = self.run(CYCLES_FULL_REFRESH - OVERSHOOT);
|
OVERSHOOT = self.run(CYCLES_FULL_REFRESH - OVERSHOOT);
|
||||||
|
@ -419,7 +412,6 @@ mod tests {
|
||||||
#[cfg(not(feature = "no_video_interface"))]
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
impl VideoInterface for DummyInterface {}
|
impl VideoInterface for DummyInterface {}
|
||||||
impl AudioInterface for DummyInterface {}
|
impl AudioInterface for DummyInterface {}
|
||||||
impl InputInterface for DummyInterface {}
|
|
||||||
|
|
||||||
fn make_mock_gba(rom: &[u8]) -> GameBoyAdvance {
|
fn make_mock_gba(rom: &[u8]) -> GameBoyAdvance {
|
||||||
let bios = vec![0; 0x4000].into_boxed_slice();
|
let bios = vec![0; 0x4000].into_boxed_slice();
|
||||||
|
@ -436,7 +428,6 @@ mod tests {
|
||||||
#[cfg(not(feature = "no_video_interface"))]
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
dummy.clone(),
|
dummy.clone(),
|
||||||
dummy.clone(),
|
dummy.clone(),
|
||||||
dummy.clone(),
|
|
||||||
);
|
);
|
||||||
gba.skip_bios();
|
gba.skip_bios();
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,10 @@ impl IoDevices {
|
||||||
pub fn set_sysbus_ptr(&mut self, ptr: SysBusPtr) {
|
pub fn set_sysbus_ptr(&mut self, ptr: SysBusPtr) {
|
||||||
self.sysbus_ptr = ptr;
|
self.sysbus_ptr = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_key_state(&mut self, state: u16) {
|
||||||
|
self.keyinput = state;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InterruptConnect for IoDevices {
|
impl InterruptConnect for IoDevices {
|
||||||
|
|
|
@ -131,7 +131,7 @@ pub mod prelude {
|
||||||
pub use super::Bus;
|
pub use super::Bus;
|
||||||
#[cfg(not(feature = "no_video_interface"))]
|
#[cfg(not(feature = "no_video_interface"))]
|
||||||
pub use super::VideoInterface;
|
pub use super::VideoInterface;
|
||||||
pub use super::{AudioInterface, InputInterface, StereoSample};
|
pub use super::{AudioInterface, StereoSample};
|
||||||
pub use super::{GBAError, GBAResult, GameBoyAdvance};
|
pub use super::{GBAError, GBAResult, GameBoyAdvance};
|
||||||
pub use rustboyadvance_utils::{read_bin_file, write_bin_file};
|
pub use rustboyadvance_utils::{read_bin_file, write_bin_file};
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,6 @@ impl BenchmarkHardware {
|
||||||
|
|
||||||
impl VideoInterface for BenchmarkHardware {}
|
impl VideoInterface for BenchmarkHardware {}
|
||||||
impl AudioInterface for BenchmarkHardware {}
|
impl AudioInterface for BenchmarkHardware {}
|
||||||
impl InputInterface for BenchmarkHardware {}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
if env::args().count() < 3 {
|
if env::args().count() < 3 {
|
||||||
|
@ -44,7 +43,6 @@ fn main() {
|
||||||
gamepak,
|
gamepak,
|
||||||
dummy.clone(),
|
dummy.clone(),
|
||||||
dummy.clone(),
|
dummy.clone(),
|
||||||
dummy.clone(),
|
|
||||||
);
|
);
|
||||||
gba.skip_bios();
|
gba.skip_bios();
|
||||||
|
|
||||||
|
|
|
@ -38,12 +38,6 @@ impl AudioInterface for Hardware {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputInterface for Hardware {
|
|
||||||
fn poll(&mut self) -> u16 {
|
|
||||||
self.key_state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Renderer {
|
struct Renderer {
|
||||||
renderer_ref: GlobalRef,
|
renderer_ref: GlobalRef,
|
||||||
frame_buffer_ref: GlobalRef,
|
frame_buffer_ref: GlobalRef,
|
||||||
|
@ -325,7 +319,7 @@ impl EmulatorContext {
|
||||||
|
|
||||||
let start_time = Instant::now();
|
let start_time = Instant::now();
|
||||||
// check key state
|
// check key state
|
||||||
self.hwif.borrow_mut().key_state = self.keypad.get_key_state(env);
|
*self.gba.get_key_state_mut() = self.keypad.get_key_state(env);
|
||||||
|
|
||||||
// run frame
|
// run frame
|
||||||
self.gba.frame();
|
self.gba.frame();
|
||||||
|
|
|
@ -18,15 +18,31 @@ use rustboyadvance_utils::audio::AudioRingBuffer;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::default::Default;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
struct HwInterface {
|
#[derive(Default)]
|
||||||
key_state: u16,
|
struct AudioDevice {
|
||||||
audio_ring_buffer: AudioRingBuffer,
|
audio_ring_buffer: AudioRingBuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HwInterface {
|
impl AudioInterface for AudioDevice {
|
||||||
fn set_button_state(&mut self, button: JoypadButton, is_pressed: bool) {
|
fn push_sample(&mut self, samples: &[i16]) {
|
||||||
|
let prod = self.audio_ring_buffer.producer();
|
||||||
|
for s in samples.iter() {
|
||||||
|
let _ = prod.push(*s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct RustBoyAdvanceCore {
|
||||||
|
gba: Option<GameBoyAdvance>,
|
||||||
|
game_data: Option<GameData>,
|
||||||
|
audio: Option<Rc<RefCell<AudioDevice>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_button_state(key_state: &mut u16, button: JoypadButton, is_pressed: bool) {
|
||||||
let mapped_button = match button {
|
let mapped_button = match button {
|
||||||
JoypadButton::A => GbaButton::ButtonA,
|
JoypadButton::A => GbaButton::ButtonA,
|
||||||
JoypadButton::B => GbaButton::ButtonB,
|
JoypadButton::B => GbaButton::ButtonB,
|
||||||
|
@ -40,30 +56,7 @@ impl HwInterface {
|
||||||
JoypadButton::R1 => GbaButton::ButtonR,
|
JoypadButton::R1 => GbaButton::ButtonR,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
self.key_state.set_bit(mapped_button as usize, !is_pressed);
|
key_state.set_bit(mapped_button as usize, !is_pressed);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AudioInterface for HwInterface {
|
|
||||||
fn push_sample(&mut self, samples: &[i16]) {
|
|
||||||
let prod = self.audio_ring_buffer.producer();
|
|
||||||
for s in samples.iter() {
|
|
||||||
let _ = prod.push(*s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InputInterface for HwInterface {
|
|
||||||
fn poll(&mut self) -> u16 {
|
|
||||||
self.key_state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct RustBoyAdvanceCore {
|
|
||||||
gba: Option<GameBoyAdvance>,
|
|
||||||
game_data: Option<GameData>,
|
|
||||||
hwif: Option<Rc<RefCell<HwInterface>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl libretro_backend::Core for RustBoyAdvanceCore {
|
impl libretro_backend::Core for RustBoyAdvanceCore {
|
||||||
|
@ -113,18 +106,10 @@ impl libretro_backend::Core for RustBoyAdvanceCore {
|
||||||
.video(240, 160, 60.0, PixelFormat::ARGB8888)
|
.video(240, 160, 60.0, PixelFormat::ARGB8888)
|
||||||
.audio(44100.0);
|
.audio(44100.0);
|
||||||
|
|
||||||
let hwif = Rc::new(RefCell::new(HwInterface {
|
let audio = Rc::new(RefCell::new(AudioDevice::default()));
|
||||||
key_state: rustboyadvance_core::keypad::KEYINPUT_ALL_RELEASED,
|
let gba = GameBoyAdvance::new(bios.into_boxed_slice(), gamepak, audio.clone());
|
||||||
audio_ring_buffer: Default::default(),
|
|
||||||
}));
|
|
||||||
let gba = GameBoyAdvance::new(
|
|
||||||
bios.into_boxed_slice(),
|
|
||||||
gamepak,
|
|
||||||
hwif.clone(),
|
|
||||||
hwif.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
self.hwif = Some(hwif);
|
self.audio = Some(audio);
|
||||||
self.gba = Some(gba);
|
self.gba = Some(gba);
|
||||||
self.game_data = Some(game_data);
|
self.game_data = Some(game_data);
|
||||||
LoadGameResult::Success(av_info)
|
LoadGameResult::Success(av_info)
|
||||||
|
@ -136,17 +121,19 @@ impl libretro_backend::Core for RustBoyAdvanceCore {
|
||||||
fn on_run(&mut self, handle: &mut RuntimeHandle) {
|
fn on_run(&mut self, handle: &mut RuntimeHandle) {
|
||||||
let joypad_port = 0;
|
let joypad_port = 0;
|
||||||
|
|
||||||
// gba and hwif are `Some` after the game is loaded, so avoiding overhead of unwrap
|
// gba and audio are `Some` after the game is loaded, so avoiding overhead of unwrap
|
||||||
let gba = unsafe { self.gba.as_mut().unsafe_unwrap() };
|
let gba = unsafe { self.gba.as_mut().unsafe_unwrap() };
|
||||||
let hwif = unsafe { self.hwif.as_mut().unsafe_unwrap() };
|
let audio = unsafe { self.audio.as_mut().unsafe_unwrap() };
|
||||||
|
|
||||||
|
let key_state = gba.borrow_mut().get_key_state_mut();
|
||||||
macro_rules! update_controllers {
|
macro_rules! update_controllers {
|
||||||
( $( $button:ident ),+ ) => (
|
( $( $button:ident ),+ ) => (
|
||||||
$(
|
$(
|
||||||
hwif.borrow_mut().set_button_state( JoypadButton::$button, handle.is_joypad_button_pressed( joypad_port, JoypadButton::$button ) );
|
set_button_state(key_state, JoypadButton::$button, handle.is_joypad_button_pressed( joypad_port, JoypadButton::$button ) );
|
||||||
)+
|
)+
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
drop(key_state);
|
||||||
|
|
||||||
update_controllers!(A, B, Start, Select, Left, Up, Right, Down, L1, R1);
|
update_controllers!(A, B, Start, Select, Left, Up, Right, Down, L1, R1);
|
||||||
|
|
||||||
|
@ -166,8 +153,8 @@ impl libretro_backend::Core for RustBoyAdvanceCore {
|
||||||
// upload sound samples
|
// upload sound samples
|
||||||
{
|
{
|
||||||
let mut audio_samples = [0; 4096 * 2];
|
let mut audio_samples = [0; 4096 * 2];
|
||||||
let mut hwif = hwif.borrow_mut();
|
let mut audio = audio.borrow_mut();
|
||||||
let consumer = hwif.audio_ring_buffer.consumer();
|
let consumer = audio.audio_ring_buffer.consumer();
|
||||||
let count = consumer.pop_slice(&mut audio_samples);
|
let count = consumer.pop_slice(&mut audio_samples);
|
||||||
|
|
||||||
handle.upload_audio_frame(&audio_samples[..count]);
|
handle.upload_audio_frame(&audio_samples[..count]);
|
||||||
|
|
|
@ -1,50 +1,38 @@
|
||||||
|
use rustboyadvance_core::GameBoyAdvance;
|
||||||
use sdl2::controller::Axis;
|
use sdl2::controller::Axis;
|
||||||
use sdl2::controller::Button;
|
use sdl2::controller::Button;
|
||||||
use sdl2::keyboard::Scancode;
|
use sdl2::keyboard::Scancode;
|
||||||
|
|
||||||
use rustboyadvance_core::keypad as gba_keypad;
|
use rustboyadvance_core::keypad as gba_keypad;
|
||||||
use rustboyadvance_core::InputInterface;
|
|
||||||
|
|
||||||
use bit;
|
use bit;
|
||||||
use bit::BitIndex;
|
use bit::BitIndex;
|
||||||
|
|
||||||
pub struct Sdl2Input {
|
pub fn on_keyboard_key_down(gba: &mut GameBoyAdvance, scancode: Scancode) {
|
||||||
keyinput: u16,
|
if let Some(key) = scancode_to_keypad(scancode) {
|
||||||
axis_keyinput: u16,
|
gba.get_key_state_mut().set_bit(key as usize, false);
|
||||||
}
|
|
||||||
|
|
||||||
impl InputInterface for Sdl2Input {
|
|
||||||
fn poll(&mut self) -> u16 {
|
|
||||||
!(!self.keyinput | !self.axis_keyinput)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sdl2Input {
|
pub fn on_keyboard_key_up(gba: &mut GameBoyAdvance, scancode: Scancode) {
|
||||||
pub fn on_keyboard_key_down(&mut self, scancode: Scancode) {
|
|
||||||
if let Some(key) = scancode_to_keypad(scancode) {
|
if let Some(key) = scancode_to_keypad(scancode) {
|
||||||
self.keyinput.set_bit(key as usize, false);
|
gba.get_key_state_mut().set_bit(key as usize, true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn on_keyboard_key_up(&mut self, scancode: Scancode) {
|
pub fn on_controller_button_down(gba: &mut GameBoyAdvance, button: Button) {
|
||||||
if let Some(key) = scancode_to_keypad(scancode) {
|
|
||||||
self.keyinput.set_bit(key as usize, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_controller_button_down(&mut self, button: Button) {
|
|
||||||
if let Some(key) = controller_button_to_keypad(button) {
|
if let Some(key) = controller_button_to_keypad(button) {
|
||||||
self.keyinput.set_bit(key as usize, false);
|
gba.get_key_state_mut().set_bit(key as usize, false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn on_controller_button_up(&mut self, button: Button) {
|
pub fn on_controller_button_up(gba: &mut GameBoyAdvance, button: Button) {
|
||||||
if let Some(key) = controller_button_to_keypad(button) {
|
if let Some(key) = controller_button_to_keypad(button) {
|
||||||
self.keyinput.set_bit(key as usize, true);
|
gba.get_key_state_mut().set_bit(key as usize, true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn on_axis_motion(&mut self, axis: Axis, val: i16) {
|
pub fn on_axis_motion(gba: &mut GameBoyAdvance, axis: Axis, val: i16) {
|
||||||
use gba_keypad::Keys as GbaKeys;
|
use gba_keypad::Keys as GbaKeys;
|
||||||
let keys = match axis {
|
let keys = match axis {
|
||||||
Axis::LeftX => (GbaKeys::Left, GbaKeys::Right),
|
Axis::LeftX => (GbaKeys::Left, GbaKeys::Right),
|
||||||
|
@ -56,17 +44,17 @@ impl Sdl2Input {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let key_state = gba.get_key_state_mut();
|
||||||
// Axis motion is an absolute value in the range
|
// Axis motion is an absolute value in the range
|
||||||
// [-32768, 32767]. Let's simulate a very rough dead
|
// [-32768, 32767]. Let's simulate a very rough dead
|
||||||
// zone to ignore spurious events.
|
// zone to ignore spurious events.
|
||||||
let dead_zone = 10_000;
|
let dead_zone = 10_000;
|
||||||
if val > dead_zone || val < -dead_zone {
|
if val > dead_zone || val < -dead_zone {
|
||||||
let key = if val < 0 { keys.0 } else { keys.1 };
|
let key = if val < 0 { keys.0 } else { keys.1 };
|
||||||
self.axis_keyinput.set_bit(key as usize, false);
|
key_state.set_bit(key as usize, false);
|
||||||
} else {
|
} else {
|
||||||
self.axis_keyinput.set_bit(keys.0 as usize, true);
|
key_state.set_bit(keys.0 as usize, true);
|
||||||
self.axis_keyinput.set_bit(keys.1 as usize, true);
|
key_state.set_bit(keys.1 as usize, true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,10 +89,3 @@ fn controller_button_to_keypad(button: Button) -> Option<gba_keypad::Keys> {
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_input() -> Sdl2Input {
|
|
||||||
Sdl2Input {
|
|
||||||
keyinput: gba_keypad::KEYINPUT_ALL_RELEASED,
|
|
||||||
axis_keyinput: gba_keypad::KEYINPUT_ALL_RELEASED,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ mod input;
|
||||||
mod video;
|
mod video;
|
||||||
|
|
||||||
use audio::{create_audio_player, create_dummy_player};
|
use audio::{create_audio_player, create_dummy_player};
|
||||||
use input::create_input;
|
use input;
|
||||||
use video::{create_video_interface, SCREEN_HEIGHT, SCREEN_WIDTH};
|
use video::{create_video_interface, SCREEN_HEIGHT, SCREEN_WIDTH};
|
||||||
|
|
||||||
use rustboyadvance_core::cartridge::BackupType;
|
use rustboyadvance_core::cartridge::BackupType;
|
||||||
|
@ -253,7 +253,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
..
|
..
|
||||||
} => match scancode {
|
} => match scancode {
|
||||||
Scancode::Space => frame_limiter = false,
|
Scancode::Space => frame_limiter = false,
|
||||||
k => input.borrow_mut().on_keyboard_key_down(k),
|
k => input::on_keyboard_key_down(&mut gba, k),
|
||||||
},
|
},
|
||||||
Event::KeyUp {
|
Event::KeyUp {
|
||||||
scancode: Some(scancode),
|
scancode: Some(scancode),
|
||||||
|
@ -291,17 +291,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Scancode::Space => frame_limiter = true,
|
Scancode::Space => frame_limiter = true,
|
||||||
k => input.borrow_mut().on_keyboard_key_up(k),
|
k => input::on_keyboard_key_up(&mut gba, k),
|
||||||
},
|
},
|
||||||
Event::ControllerButtonDown { button, .. } => match button {
|
Event::ControllerButtonDown { button, .. } => match button {
|
||||||
Button::RightStick => frame_limiter = !frame_limiter,
|
Button::RightStick => frame_limiter = !frame_limiter,
|
||||||
b => input.borrow_mut().on_controller_button_down(b),
|
b => input::on_controller_button_down(&mut gba, b),
|
||||||
},
|
},
|
||||||
Event::ControllerButtonUp { button, .. } => {
|
Event::ControllerButtonUp { button, .. } => {
|
||||||
input.borrow_mut().on_controller_button_up(button);
|
input::on_controller_button_up(&mut gba, button);
|
||||||
}
|
}
|
||||||
Event::ControllerAxisMotion { axis, value, .. } => {
|
Event::ControllerAxisMotion { axis, value, .. } => {
|
||||||
input.borrow_mut().on_axis_motion(axis, value);
|
input::on_axis_motion(&mut gba, axis, value);
|
||||||
}
|
}
|
||||||
Event::ControllerDeviceRemoved { which, .. } => {
|
Event::ControllerDeviceRemoved { which, .. } => {
|
||||||
let removed = if let Some(active_controller) = &active_controller {
|
let removed = if let Some(active_controller) = &active_controller {
|
||||||
|
@ -339,7 +339,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
gamepak,
|
gamepak,
|
||||||
video.clone(),
|
video.clone(),
|
||||||
audio.clone(),
|
audio.clone(),
|
||||||
input.clone(),
|
|
||||||
);
|
);
|
||||||
gba.skip_bios();
|
gba.skip_bios();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ pub struct Emulator {
|
||||||
|
|
||||||
struct Interface {
|
struct Interface {
|
||||||
frame: Vec<u8>,
|
frame: Vec<u8>,
|
||||||
keyinput: u16,
|
|
||||||
sample_rate: i32,
|
sample_rate: i32,
|
||||||
audio_ctx: AudioContext,
|
audio_ctx: AudioContext,
|
||||||
audio_ring_buffer: AudioRingBuffer,
|
audio_ring_buffer: AudioRingBuffer,
|
||||||
|
@ -39,7 +38,6 @@ impl Interface {
|
||||||
fn new(audio_ctx: AudioContext) -> Result<Interface, JsValue> {
|
fn new(audio_ctx: AudioContext) -> Result<Interface, JsValue> {
|
||||||
Ok(Interface {
|
Ok(Interface {
|
||||||
frame: vec![0; 240 * 160 * 4],
|
frame: vec![0; 240 * 160 * 4],
|
||||||
keyinput: gba_keypad::KEYINPUT_ALL_RELEASED,
|
|
||||||
sample_rate: audio_ctx.sample_rate() as i32,
|
sample_rate: audio_ctx.sample_rate() as i32,
|
||||||
audio_ctx: audio_ctx,
|
audio_ctx: audio_ctx,
|
||||||
audio_ring_buffer: Default::default(),
|
audio_ring_buffer: Default::default(),
|
||||||
|
@ -77,12 +75,6 @@ impl AudioInterface for Interface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputInterface for Interface {
|
|
||||||
fn poll(&mut self) -> u16 {
|
|
||||||
self.keyinput
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
impl Emulator {
|
impl Emulator {
|
||||||
#[wasm_bindgen(constructor)]
|
#[wasm_bindgen(constructor)]
|
||||||
|
@ -141,17 +133,15 @@ impl Emulator {
|
||||||
|
|
||||||
pub fn key_down(&mut self, event_key: &str) {
|
pub fn key_down(&mut self, event_key: &str) {
|
||||||
debug!("Key down: {}", event_key);
|
debug!("Key down: {}", event_key);
|
||||||
let mut interface = self.interface.borrow_mut();
|
|
||||||
if let Some(key) = Emulator::map_key(event_key) {
|
if let Some(key) = Emulator::map_key(event_key) {
|
||||||
interface.keyinput.set_bit(key as usize, false);
|
self.gba.get_key_state().set_bit(key as usize, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn key_up(&mut self, event_key: &str) {
|
pub fn key_up(&mut self, event_key: &str) {
|
||||||
debug!("Key up: {}", event_key);
|
debug!("Key up: {}", event_key);
|
||||||
let mut interface = self.interface.borrow_mut();
|
|
||||||
if let Some(key) = Emulator::map_key(event_key) {
|
if let Some(key) = Emulator::map_key(event_key) {
|
||||||
interface.keyinput.set_bit(key as usize, true);
|
self.gba.get_key_state().set_bit(key as usize, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue