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