Add minifb based binary, currently it has better performance than the SDL2.
SDL2 rendering is really bottlenecking currently.. Former-commit-id: 8e04b799f248209a138990b2389e740b0d1d9f0f
This commit is contained in:
parent
385016f24a
commit
3c7a734270
|
@ -29,6 +29,11 @@ cpal="0.10.0"
|
|||
name = "rba-sdl2"
|
||||
path = "src/plat/sdl2/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "rba-minifb"
|
||||
path = "src/plat/minifb/main.rs"
|
||||
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
debug = true
|
32
src/plat/minifb/cli.yml
Normal file
32
src/plat/minifb/cli.yml
Normal file
|
@ -0,0 +1,32 @@
|
|||
name: rba-sdl2
|
||||
author: Michel Heily <michelheily@gmail.com>
|
||||
about: RustBoyAdvance SDL2 port
|
||||
args:
|
||||
- bios:
|
||||
help: Sets the bios file to use
|
||||
short: b
|
||||
required: false
|
||||
default_value: gba_bios.bin
|
||||
- game_rom:
|
||||
long: game-rom
|
||||
takes_value: true
|
||||
help: Sets the game-rom file to use
|
||||
required: true
|
||||
index: 1
|
||||
- skip_bios:
|
||||
long: skip-bios
|
||||
help: Skip running bios and start from the ROM instead
|
||||
- no_framerate_limit:
|
||||
long: no-framerate-limit
|
||||
help: Run without frame limiter
|
||||
- debug:
|
||||
long: debug
|
||||
help: Start with the debugger attached
|
||||
- script_file:
|
||||
long: script-file
|
||||
short: f
|
||||
takes_value: true
|
||||
help: Text file with debugger commands to run
|
||||
required: false
|
||||
requires:
|
||||
debug
|
155
src/plat/minifb/main.rs
Normal file
155
src/plat/minifb/main.rs
Normal file
|
@ -0,0 +1,155 @@
|
|||
extern crate sdl2;
|
||||
|
||||
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::prelude::*;
|
||||
use rustboyadvance_ng::util::FpsCounter;
|
||||
use rustboyadvance_ng::core::keypad;
|
||||
|
||||
extern crate bit;
|
||||
use bit::BitIndex;
|
||||
extern crate 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) -> u32 {
|
||||
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 debug = matches.occurrences_of("debug") != 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 = Cartridge::from_path(rom_path).unwrap();
|
||||
let mut cpu = arm7tdmi::Core::new();
|
||||
if skip_bios {
|
||||
cpu.skip_bios();
|
||||
}
|
||||
let cpu = cpu;
|
||||
|
||||
let sdl_context = sdl2::init().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<MiniFb, MiniFb, MiniFb> =
|
||||
GameBoyAdvance::new(cpu, bios_bin, cart, minifb.clone(), minifb.clone(), minifb.clone());
|
||||
|
||||
if debug {
|
||||
gba.cpu.set_verbose(true);
|
||||
let mut debugger = Debugger::new(gba);
|
||||
println!("starting debugger...");
|
||||
debugger.repl(matches.value_of("script_file")).unwrap();
|
||||
println!("ending debugger...");
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in a new issue