Add "press SPACE to turbo" to sdl2 binary, like in old-school emulators :P

Former-commit-id: 95dfddfac193ac846f179ec607a8f7c3fc0e21a4
This commit is contained in:
Michel Heily 2019-12-20 18:11:14 +02:00
parent cb630ffb8e
commit 31eb12cb6a
3 changed files with 63 additions and 38 deletions

View file

@ -16,9 +16,6 @@ args:
- skip_bios: - skip_bios:
long: skip-bios long: skip-bios
help: Skip running bios and start from the ROM instead help: Skip running bios and start from the ROM instead
- no_framerate_limit:
long: no-framerate-limit
help: Run without frame limiter
- debug: - debug:
long: debug long: debug
help: Start with the debugger attached help: Start with the debugger attached

View file

@ -1,5 +1,4 @@
use sdl2::keyboard::Keycode; use sdl2::keyboard::Keycode;
use sdl2::{event::Event, EventPump};
use rustboyadvance_ng::core::keypad as gba_keypad; use rustboyadvance_ng::core::keypad as gba_keypad;
use rustboyadvance_ng::InputInterface; use rustboyadvance_ng::InputInterface;
@ -8,38 +7,28 @@ extern crate bit;
use bit::BitIndex; use bit::BitIndex;
pub struct Sdl2Input { pub struct Sdl2Input {
event_pump: EventPump,
keyinput: u16, keyinput: u16,
} }
impl InputInterface for Sdl2Input { impl InputInterface for Sdl2Input {
fn poll(&mut self) -> u16 { fn poll(&mut self) -> u16 {
for event in self.event_pump.poll_iter() {
match event {
Event::KeyDown {
keycode: Some(keycode),
..
} => {
if let Some(key) = keycode_to_keypad(keycode) {
self.keyinput.set_bit(key as usize, false);
}
}
Event::KeyUp {
keycode: Some(keycode),
..
} => {
if let Some(key) = keycode_to_keypad(keycode) {
self.keyinput.set_bit(key as usize, true);
}
}
Event::Quit { .. } => panic!("quit!"),
_ => {}
}
}
self.keyinput self.keyinput
} }
} }
impl Sdl2Input {
pub fn on_keyboard_key_down(&mut self, keycode: Keycode) {
if let Some(key) = keycode_to_keypad(keycode) {
self.keyinput.set_bit(key as usize, false);
}
}
pub fn on_keyboard_key_up(&mut self, keycode: Keycode) {
if let Some(key) = keycode_to_keypad(keycode) {
self.keyinput.set_bit(key as usize, true);
}
}
}
fn keycode_to_keypad(keycode: Keycode) -> Option<gba_keypad::Keys> { fn keycode_to_keypad(keycode: Keycode) -> Option<gba_keypad::Keys> {
match keycode { match keycode {
Keycode::Up => Some(gba_keypad::Keys::Up), Keycode::Up => Some(gba_keypad::Keys::Up),
@ -49,16 +38,15 @@ fn keycode_to_keypad(keycode: Keycode) -> Option<gba_keypad::Keys> {
Keycode::Z => Some(gba_keypad::Keys::ButtonB), Keycode::Z => Some(gba_keypad::Keys::ButtonB),
Keycode::X => Some(gba_keypad::Keys::ButtonA), Keycode::X => Some(gba_keypad::Keys::ButtonA),
Keycode::Return => Some(gba_keypad::Keys::Start), Keycode::Return => Some(gba_keypad::Keys::Start),
Keycode::Space => Some(gba_keypad::Keys::Select), Keycode::Backspace => Some(gba_keypad::Keys::Select),
Keycode::A => Some(gba_keypad::Keys::ButtonL), Keycode::A => Some(gba_keypad::Keys::ButtonL),
Keycode::S => Some(gba_keypad::Keys::ButtonR), Keycode::S => Some(gba_keypad::Keys::ButtonR),
_ => None, _ => None,
} }
} }
pub fn create_keyboard(sdl: &sdl2::Sdl) -> Sdl2Input { pub fn create_input() -> Sdl2Input {
Sdl2Input { Sdl2Input {
event_pump: sdl.event_pump().unwrap(),
keyinput: gba_keypad::KEYINPUT_ALL_RELEASED, keyinput: gba_keypad::KEYINPUT_ALL_RELEASED,
} }
} }

View file

@ -1,4 +1,6 @@
extern crate sdl2; extern crate sdl2;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -10,24 +12,23 @@ use std::time;
extern crate clap; extern crate clap;
mod audio; mod audio;
mod keyboard; mod input;
mod video; mod video;
use audio::{create_audio_player, Sdl2AudioPlayer}; use audio::{create_audio_player, Sdl2AudioPlayer};
use keyboard::{create_keyboard, Sdl2Input}; use input::{create_input, Sdl2Input};
use video::{create_video_interface, Sdl2Video}; use video::{create_video_interface, Sdl2Video};
#[macro_use]
extern crate rustboyadvance_ng; extern crate rustboyadvance_ng;
use rustboyadvance_ng::prelude::*; use rustboyadvance_ng::prelude::*;
use rustboyadvance_ng::util::FpsCounter; use rustboyadvance_ng::util::FpsCounter;
fn main() { fn main() {
let mut frame_limiter = true;
let yaml = load_yaml!("cli.yml"); let yaml = load_yaml!("cli.yml");
let matches = clap::App::from_yaml(yaml).get_matches(); let matches = clap::App::from_yaml(yaml).get_matches();
let skip_bios = matches.occurrences_of("skip_bios") != 0; let skip_bios = matches.occurrences_of("skip_bios") != 0;
let no_framerate_limit = matches.occurrences_of("no_framerate_limit") != 0;
let debug = matches.occurrences_of("debug") != 0; let debug = matches.occurrences_of("debug") != 0;
let bios_path = Path::new(matches.value_of("bios").unwrap_or_default()); let bios_path = Path::new(matches.value_of("bios").unwrap_or_default());
@ -45,11 +46,19 @@ fn main() {
let sdl_context = sdl2::init().unwrap(); let sdl_context = sdl2::init().unwrap();
let video = Rc::new(RefCell::new(create_video_interface(&sdl_context))); let video = Rc::new(RefCell::new(create_video_interface(&sdl_context)));
let audio = Rc::new(RefCell::new(create_audio_player(&sdl_context))); let audio = Rc::new(RefCell::new(create_audio_player(&sdl_context)));
let keyboard = Rc::new(RefCell::new(create_keyboard(&sdl_context))); let input = Rc::new(RefCell::new(create_input()));
let mut fps_counter = FpsCounter::default(); let mut fps_counter = FpsCounter::default();
let mut gba: GameBoyAdvance<Sdl2Video, Sdl2AudioPlayer, Sdl2Input> = let mut gba: GameBoyAdvance<Sdl2Video, Sdl2AudioPlayer, Sdl2Input> = GameBoyAdvance::new(
GameBoyAdvance::new(cpu, bios_bin, cart, video.clone(), audio.clone(), keyboard.clone()); cpu,
bios_bin,
cart,
video.clone(),
audio.clone(),
input.clone(),
);
let mut event_pump = sdl_context.event_pump().unwrap();
if debug { if debug {
gba.cpu.set_verbose(true); gba.cpu.set_verbose(true);
@ -62,6 +71,37 @@ fn main() {
loop { loop {
let start_time = time::Instant::now(); let start_time = time::Instant::now();
for event in event_pump.poll_iter() {
match event {
Event::KeyDown {
keycode: Some(Keycode::Space),
..
} => {
frame_limiter = false;
}
Event::KeyUp {
keycode: Some(Keycode::Space),
..
} => {
frame_limiter = true;
}
Event::KeyDown {
keycode: Some(keycode),
..
} => {
input.borrow_mut().on_keyboard_key_down(keycode);
}
Event::KeyUp {
keycode: Some(keycode),
..
} => {
input.borrow_mut().on_keyboard_key_up(keycode);
}
Event::Quit { .. } => panic!("quit!"),
_ => {}
}
}
gba.frame(); gba.frame();
if let Some(fps) = fps_counter.tick() { if let Some(fps) = fps_counter.tick() {
@ -69,7 +109,7 @@ fn main() {
video.borrow_mut().set_window_title(&title); video.borrow_mut().set_window_title(&title);
} }
if !no_framerate_limit { if frame_limiter {
let time_passed = start_time.elapsed(); let time_passed = start_time.elapsed();
let delay = frame_time.checked_sub(time_passed); let delay = frame_time.checked_sub(time_passed);
match delay { match delay {