
On windows, the Vec may sit on the stack.. Former-commit-id: b8aa77858291c1b7ee6bfbfbec92646f18e819de
144 lines
3.8 KiB
Rust
144 lines
3.8 KiB
Rust
use std::cell::RefCell;
|
|
use std::rc::Rc;
|
|
|
|
use std::path::Path;
|
|
use std::time;
|
|
|
|
#[macro_use]
|
|
extern crate clap;
|
|
|
|
#[macro_use]
|
|
extern crate rustboyadvance_ng;
|
|
use rustboyadvance_ng::core::keypad;
|
|
use rustboyadvance_ng::prelude::*;
|
|
use rustboyadvance_ng::util::FpsCounter;
|
|
|
|
use bit::BitIndex;
|
|
use minifb;
|
|
use minifb::{Key, Window, WindowOptions};
|
|
|
|
struct MiniFb {
|
|
window: minifb::Window,
|
|
}
|
|
|
|
impl VideoInterface for MiniFb {
|
|
fn render(&mut self, buffer: &[u32]) {
|
|
self.window.update_with_buffer(buffer).unwrap();
|
|
}
|
|
}
|
|
|
|
impl InputInterface for MiniFb {
|
|
fn poll(&mut self) -> u16 {
|
|
let mut keyinput = keypad::KEYINPUT_ALL_RELEASED;
|
|
keyinput.set_bit(keypad::Keys::Up as usize, !self.window.is_key_down(Key::Up));
|
|
keyinput.set_bit(
|
|
keypad::Keys::Down as usize,
|
|
!self.window.is_key_down(Key::Down),
|
|
);
|
|
keyinput.set_bit(
|
|
keypad::Keys::Left as usize,
|
|
!self.window.is_key_down(Key::Left),
|
|
);
|
|
keyinput.set_bit(
|
|
keypad::Keys::Right as usize,
|
|
!self.window.is_key_down(Key::Right),
|
|
);
|
|
keyinput.set_bit(
|
|
keypad::Keys::ButtonB as usize,
|
|
!self.window.is_key_down(Key::Z),
|
|
);
|
|
keyinput.set_bit(
|
|
keypad::Keys::ButtonA as usize,
|
|
!self.window.is_key_down(Key::X),
|
|
);
|
|
keyinput.set_bit(
|
|
keypad::Keys::Start as usize,
|
|
!self.window.is_key_down(Key::Enter),
|
|
);
|
|
keyinput.set_bit(
|
|
keypad::Keys::Select as usize,
|
|
!self.window.is_key_down(Key::Space),
|
|
);
|
|
keyinput.set_bit(
|
|
keypad::Keys::ButtonL as usize,
|
|
!self.window.is_key_down(Key::A),
|
|
);
|
|
keyinput.set_bit(
|
|
keypad::Keys::ButtonR as usize,
|
|
!self.window.is_key_down(Key::S),
|
|
);
|
|
keyinput
|
|
}
|
|
}
|
|
|
|
impl AudioInterface for MiniFb {
|
|
fn get_sample_rate(&self) -> i32 {
|
|
0
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let yaml = load_yaml!("cli.yml");
|
|
let matches = clap::App::from_yaml(yaml).get_matches();
|
|
|
|
let skip_bios = matches.occurrences_of("skip_bios") != 0;
|
|
let no_framerate_limit = matches.occurrences_of("no_framerate_limit") != 0;
|
|
|
|
let bios_path = Path::new(matches.value_of("bios").unwrap_or_default());
|
|
let rom_path = Path::new(matches.value_of("game_rom").unwrap());
|
|
let rom_name = rom_path.file_name().unwrap().to_str().unwrap();
|
|
|
|
let bios_bin = read_bin_file(bios_path).unwrap();
|
|
let cart = GamepakBuilder::new().file(rom_path).build().unwrap();
|
|
|
|
let minifb = Rc::new(RefCell::new(MiniFb {
|
|
window: Window::new(
|
|
"rustboyadvance-ng",
|
|
240,
|
|
160,
|
|
WindowOptions {
|
|
borderless: true,
|
|
scale: minifb::Scale::X4,
|
|
..Default::default()
|
|
},
|
|
)
|
|
.unwrap(),
|
|
}));
|
|
|
|
let mut fps_counter = FpsCounter::default();
|
|
let mut gba = GameBoyAdvance::new(
|
|
bios_bin.into_boxed_slice(),
|
|
cart,
|
|
minifb.clone(),
|
|
minifb.clone(),
|
|
minifb.clone(),
|
|
);
|
|
|
|
if skip_bios {
|
|
gba.skip_bios();
|
|
}
|
|
|
|
let frame_time = time::Duration::new(0, 1_000_000_000u32 / 60);
|
|
loop {
|
|
let start_time = time::Instant::now();
|
|
|
|
gba.frame();
|
|
|
|
if let Some(fps) = fps_counter.tick() {
|
|
let title = format!("{} ({} fps)", rom_name, fps);
|
|
// video.borrow_mut().set_window_title(&title);
|
|
minifb.borrow_mut().window.set_title(&title);
|
|
}
|
|
|
|
if !no_framerate_limit {
|
|
let time_passed = start_time.elapsed();
|
|
let delay = frame_time.checked_sub(time_passed);
|
|
match delay {
|
|
None => {}
|
|
Some(delay) => {
|
|
::std::thread::sleep(delay);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|