sdl2 UI improvements, Auto download Normmatt BIOS
Former-commit-id: 9a8bb7f68ba7638e758b01cef17654b6057b1db3 Former-commit-id: 83dc923063d75a167662474446f9fa7eb0ee836b
This commit is contained in:
parent
1cac88d73a
commit
a56f515563
|
@ -5,16 +5,16 @@ authors = ["Michel Heily <michelheily@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rustboyadvance-core = {path = "../../rustboyadvance-core/"}
|
rustboyadvance-core = { path = "../../rustboyadvance-core/" }
|
||||||
sdl2 = {version = "0.33.0", features = ["image"]}
|
sdl2 = { version = "0.33.0", features = ["image"] }
|
||||||
ringbuf = "0.2.1"
|
ringbuf = "0.2.1"
|
||||||
bytesize = "1.0.0"
|
bytesize = "1.0.0"
|
||||||
clap = {version = "2.33", features = ["color", "yaml"]}
|
clap = { version = "2.33", features = ["color", "yaml"] }
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
flexi_logger = {version = "0.14", features = ["colors"]}
|
flexi_logger = { version = "0.14", features = ["colors"] }
|
||||||
bit = "^0.1"
|
bit = "^0.1"
|
||||||
spin_sleep="0.3.7"
|
spin_sleep = "0.3.7"
|
||||||
|
reqwest = { version = "0.10", features = ["blocking"] }
|
||||||
|
|
||||||
[target.'cfg(windows)'.build-dependencies]
|
[target.'cfg(windows)'.build-dependencies]
|
||||||
winres = "0.1"
|
winres = "0.1"
|
||||||
|
@ -22,4 +22,4 @@ winres = "0.1"
|
||||||
[features]
|
[features]
|
||||||
debugger = ["rustboyadvance-core/debugger"]
|
debugger = ["rustboyadvance-core/debugger"]
|
||||||
gdb = ["rustboyadvance-core/gdb"]
|
gdb = ["rustboyadvance-core/gdb"]
|
||||||
arm7tdmi_dispatch_table = ["rustboyadvance-core/arm7tdmi_dispatch_table"]
|
arm7tdmi_dispatch_table = ["rustboyadvance-core/arm7tdmi_dispatch_table"]
|
||||||
|
|
|
@ -12,7 +12,9 @@ fn main() {
|
||||||
|
|
||||||
let target = env::var("TARGET").unwrap();
|
let target = env::var("TARGET").unwrap();
|
||||||
if target.contains("pc-windows") {
|
if target.contains("pc-windows") {
|
||||||
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("Failed to get CARGO_MANIFEST_DIR"));
|
let manifest_dir = PathBuf::from(
|
||||||
|
env::var("CARGO_MANIFEST_DIR").expect("Failed to get CARGO_MANIFEST_DIR"),
|
||||||
|
);
|
||||||
let out_dir = PathBuf::from(env::var("OUT_DIR").expect("Failed to get OUT_DIR"));
|
let out_dir = PathBuf::from(env::var("OUT_DIR").expect("Failed to get OUT_DIR"));
|
||||||
let mut lib_dir = manifest_dir.clone();
|
let mut lib_dir = manifest_dir.clone();
|
||||||
let mut dll_dir = manifest_dir.clone();
|
let mut dll_dir = manifest_dir.clone();
|
||||||
|
|
|
@ -2,7 +2,10 @@ use sdl2;
|
||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
use sdl2::image::{InitFlag, LoadTexture};
|
use sdl2::image::{InitFlag, LoadTexture};
|
||||||
use sdl2::keyboard::Keycode;
|
use sdl2::keyboard::Keycode;
|
||||||
|
use sdl2::messagebox::*;
|
||||||
use sdl2::pixels::Color;
|
use sdl2::pixels::Color;
|
||||||
|
use sdl2::rect::Rect;
|
||||||
|
use sdl2::render::{Texture, WindowCanvas};
|
||||||
|
|
||||||
use sdl2::EventPump;
|
use sdl2::EventPump;
|
||||||
|
|
||||||
|
@ -13,6 +16,7 @@ use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::io::Read;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::process;
|
use std::process;
|
||||||
use std::time;
|
use std::time;
|
||||||
|
@ -27,6 +31,8 @@ extern crate log;
|
||||||
use flexi_logger;
|
use flexi_logger;
|
||||||
use flexi_logger::*;
|
use flexi_logger::*;
|
||||||
|
|
||||||
|
use reqwest;
|
||||||
|
|
||||||
mod audio;
|
mod audio;
|
||||||
mod input;
|
mod input;
|
||||||
mod video;
|
mod video;
|
||||||
|
@ -43,22 +49,88 @@ use rustboyadvance_core::util::FpsCounter;
|
||||||
const LOG_DIR: &str = ".logs";
|
const LOG_DIR: &str = ".logs";
|
||||||
const DEFAULT_GDB_SERVER_ADDR: &'static str = "localhost:1337";
|
const DEFAULT_GDB_SERVER_ADDR: &'static str = "localhost:1337";
|
||||||
|
|
||||||
|
const CANVAS_WIDTH: u32 = SCREEN_WIDTH;
|
||||||
|
const CANVAS_HEIGHT: u32 = SCREEN_HEIGHT;
|
||||||
|
|
||||||
fn get_savestate_path(rom_filename: &Path) -> PathBuf {
|
fn get_savestate_path(rom_filename: &Path) -> PathBuf {
|
||||||
rom_filename.with_extension("savestate")
|
rom_filename.with_extension("savestate")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits for the user to drag a rom file to window
|
/// Waits for the user to drag a rom file to window
|
||||||
fn wait_for_rom(event_pump: &mut EventPump) -> String {
|
fn wait_for_rom(canvas: &mut WindowCanvas, event_pump: &mut EventPump) -> Result<String, String> {
|
||||||
|
let texture_creator = canvas.texture_creator();
|
||||||
|
let icon_texture = texture_creator
|
||||||
|
.load_texture("assets/icon_cropped_small.png")
|
||||||
|
.expect("failed to load icon");
|
||||||
|
let background = Color::RGB(0xDD, 0xDD, 0xDD);
|
||||||
loop {
|
loop {
|
||||||
for event in event_pump.poll_iter() {
|
for event in event_pump.poll_iter() {
|
||||||
match event {
|
match event {
|
||||||
Event::DropFile { filename, .. } => {
|
Event::DropFile { filename, .. } => {
|
||||||
return filename;
|
return Ok(filename);
|
||||||
}
|
}
|
||||||
Event::Quit { .. } => process::exit(0),
|
Event::Quit { .. } => process::exit(0),
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
canvas.set_draw_color(background);
|
||||||
|
canvas.clear();
|
||||||
|
canvas.copy(
|
||||||
|
&icon_texture,
|
||||||
|
None,
|
||||||
|
Some(Rect::from_center(
|
||||||
|
((CANVAS_WIDTH / 2) as i32, (CANVAS_HEIGHT / 2) as i32),
|
||||||
|
160,
|
||||||
|
100,
|
||||||
|
)),
|
||||||
|
)?;
|
||||||
|
canvas.present();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ask_download_bios() -> Result<Option<Vec<u8>>, Box<dyn std::error::Error>> {
|
||||||
|
const OPEN_SOURCE_BIOS_URL: &'static str =
|
||||||
|
"https://github.com/Nebuleon/ReGBA/raw/master/bios/gba_bios.bin";
|
||||||
|
|
||||||
|
let buttons: Vec<_> = vec![
|
||||||
|
ButtonData {
|
||||||
|
flags: MessageBoxButtonFlag::NOTHING,
|
||||||
|
button_id: 100,
|
||||||
|
text: "No, Exit!",
|
||||||
|
},
|
||||||
|
ButtonData {
|
||||||
|
flags: MessageBoxButtonFlag::NOTHING,
|
||||||
|
button_id: 101,
|
||||||
|
text: "Yes",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let res = show_message_box(
|
||||||
|
MessageBoxFlag::WARNING,
|
||||||
|
buttons.as_slice(),
|
||||||
|
"bios not found",
|
||||||
|
"would you like to me download an open source bios for you?",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
match res {
|
||||||
|
ClickedButton::CloseButton => Ok(None),
|
||||||
|
ClickedButton::CustomButton(button) => match button.button_id {
|
||||||
|
101 => {
|
||||||
|
let mut resp = reqwest::blocking::get(OPEN_SOURCE_BIOS_URL)?;
|
||||||
|
let mut bios = Vec::with_capacity(16 * 1024);
|
||||||
|
resp.read_to_end(&mut bios)?;
|
||||||
|
show_simple_message_box(
|
||||||
|
MessageBoxFlag::INFORMATION,
|
||||||
|
"Download Finished!",
|
||||||
|
"Download Finished!",
|
||||||
|
None,
|
||||||
|
)?;
|
||||||
|
Ok(Some(bios))
|
||||||
|
}
|
||||||
|
_ => Ok(None),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +156,28 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
|
||||||
info!("Initializing SDL2 context");
|
info!("Initializing SDL2 context");
|
||||||
let sdl_context = sdl2::init().expect("failed to initialize sdl2");
|
let sdl_context = sdl2::init().expect("failed to initialize sdl2");
|
||||||
|
|
||||||
|
let bios_path = Path::new(matches.value_of("bios").unwrap_or_default());
|
||||||
|
let bios_bin = match read_bin_file(bios_path) {
|
||||||
|
Ok(bios) => bios,
|
||||||
|
_ => match ask_download_bios() {
|
||||||
|
Ok(Some(bios)) => {
|
||||||
|
info!("saving downloaded bios to {}", bios_path.display());
|
||||||
|
write_bin_file(bios_path, &bios)?;
|
||||||
|
|
||||||
|
bios
|
||||||
|
}
|
||||||
|
Ok(None) => {
|
||||||
|
info!("Exiting");
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("error when downloading bios: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let mut event_pump = sdl_context.event_pump()?;
|
let mut event_pump = sdl_context.event_pump()?;
|
||||||
|
|
||||||
let video_subsystem = sdl_context.video()?;
|
let video_subsystem = sdl_context.video()?;
|
||||||
|
@ -96,35 +190,20 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
.build()?;
|
.build()?;
|
||||||
let mut canvas = window.into_canvas().accelerated().build()?;
|
let mut canvas = window.into_canvas().accelerated().build()?;
|
||||||
|
|
||||||
canvas.set_logical_size(SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32)?;
|
canvas.set_logical_size(CANVAS_WIDTH, CANVAS_HEIGHT)?;
|
||||||
|
|
||||||
// Display the icon as a placeholder
|
|
||||||
canvas.set_draw_color(Color::RGB(0x40, 0x22, 0x20)); // default background color for the icon
|
|
||||||
canvas.clear();
|
|
||||||
let texture_creator = canvas.texture_creator();
|
|
||||||
let icon_texture = texture_creator
|
|
||||||
.load_texture("assets/icon_cropped_small.png")
|
|
||||||
.expect("failed to load icon");
|
|
||||||
canvas.copy(&icon_texture, None, None)?;
|
|
||||||
canvas.present();
|
|
||||||
|
|
||||||
// TODO also set window icon
|
|
||||||
|
|
||||||
let video = Rc::new(RefCell::new(create_video_interface(canvas)));
|
|
||||||
let audio = Rc::new(RefCell::new(create_audio_player(&sdl_context)));
|
|
||||||
let input = Rc::new(RefCell::new(create_input()));
|
|
||||||
|
|
||||||
let bios_path = Path::new(matches.value_of("bios").unwrap_or_default());
|
|
||||||
let bios_bin = read_bin_file(bios_path).expect("cannot read bios file");
|
|
||||||
|
|
||||||
let mut rom_path = match matches.value_of("game_rom") {
|
let mut rom_path = match matches.value_of("game_rom") {
|
||||||
Some(path) => path.to_string(),
|
Some(path) => path.to_string(),
|
||||||
_ => {
|
_ => {
|
||||||
info!("[!] Rom file missing, please drag a rom file into the emulator window...");
|
info!("[!] Rom file missing, please drag a rom file into the emulator window...");
|
||||||
wait_for_rom(&mut event_pump)
|
wait_for_rom(&mut canvas, &mut event_pump)?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let video = Rc::new(RefCell::new(create_video_interface(canvas)));
|
||||||
|
let audio = Rc::new(RefCell::new(create_audio_player(&sdl_context)));
|
||||||
|
let input = Rc::new(RefCell::new(create_input()));
|
||||||
|
|
||||||
let mut savestate_path = get_savestate_path(&Path::new(&rom_path));
|
let mut savestate_path = get_savestate_path(&Path::new(&rom_path));
|
||||||
|
|
||||||
let mut rom_name = Path::new(&rom_path).file_name().unwrap().to_str().unwrap();
|
let mut rom_name = Path::new(&rom_path).file_name().unwrap().to_str().unwrap();
|
||||||
|
|
Reference in a new issue