This repository has been archived on 2024-12-14. You can view files and clone it, but cannot push or open issues or pull requests.
rustboyadvance-ng/rustboyadvance-minifb/src/main.rs
Michel Heily 84db854a06 chore: Make GameBoyAdvance the the bios argument as boxed slice rather then a Vec
On windows, the Vec may sit on the stack..


Former-commit-id: b8aa77858291c1b7ee6bfbfbec92646f18e819de
2020-02-28 15:11:02 +02:00

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);
}
};
}
}
}