From a56f51556387d1c45170b53352a442814323b9bd Mon Sep 17 00:00:00 2001 From: Michel Heily Date: Fri, 1 May 2020 17:56:26 +0300 Subject: [PATCH] sdl2 UI improvements, Auto download Normmatt BIOS Former-commit-id: 9a8bb7f68ba7638e758b01cef17654b6057b1db3 Former-commit-id: 83dc923063d75a167662474446f9fa7eb0ee836b --- platform/rustboyadvance-sdl2/Cargo.toml | 14 +-- platform/rustboyadvance-sdl2/build.rs | 4 +- platform/rustboyadvance-sdl2/src/main.rs | 125 ++++++++++++++++++----- 3 files changed, 112 insertions(+), 31 deletions(-) diff --git a/platform/rustboyadvance-sdl2/Cargo.toml b/platform/rustboyadvance-sdl2/Cargo.toml index effc389..cc0da24 100644 --- a/platform/rustboyadvance-sdl2/Cargo.toml +++ b/platform/rustboyadvance-sdl2/Cargo.toml @@ -5,16 +5,16 @@ authors = ["Michel Heily "] edition = "2018" [dependencies] -rustboyadvance-core = {path = "../../rustboyadvance-core/"} -sdl2 = {version = "0.33.0", features = ["image"]} +rustboyadvance-core = { path = "../../rustboyadvance-core/" } +sdl2 = { version = "0.33.0", features = ["image"] } ringbuf = "0.2.1" bytesize = "1.0.0" -clap = {version = "2.33", features = ["color", "yaml"]} +clap = { version = "2.33", features = ["color", "yaml"] } log = "0.4.8" -flexi_logger = {version = "0.14", features = ["colors"]} +flexi_logger = { version = "0.14", features = ["colors"] } bit = "^0.1" -spin_sleep="0.3.7" - +spin_sleep = "0.3.7" +reqwest = { version = "0.10", features = ["blocking"] } [target.'cfg(windows)'.build-dependencies] winres = "0.1" @@ -22,4 +22,4 @@ winres = "0.1" [features] debugger = ["rustboyadvance-core/debugger"] gdb = ["rustboyadvance-core/gdb"] -arm7tdmi_dispatch_table = ["rustboyadvance-core/arm7tdmi_dispatch_table"] \ No newline at end of file +arm7tdmi_dispatch_table = ["rustboyadvance-core/arm7tdmi_dispatch_table"] diff --git a/platform/rustboyadvance-sdl2/build.rs b/platform/rustboyadvance-sdl2/build.rs index 5a1463d..3adf4ad 100644 --- a/platform/rustboyadvance-sdl2/build.rs +++ b/platform/rustboyadvance-sdl2/build.rs @@ -12,7 +12,9 @@ fn main() { let target = env::var("TARGET").unwrap(); 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 mut lib_dir = manifest_dir.clone(); let mut dll_dir = manifest_dir.clone(); diff --git a/platform/rustboyadvance-sdl2/src/main.rs b/platform/rustboyadvance-sdl2/src/main.rs index 2f03f5b..8844d2f 100644 --- a/platform/rustboyadvance-sdl2/src/main.rs +++ b/platform/rustboyadvance-sdl2/src/main.rs @@ -2,7 +2,10 @@ use sdl2; use sdl2::event::Event; use sdl2::image::{InitFlag, LoadTexture}; use sdl2::keyboard::Keycode; +use sdl2::messagebox::*; use sdl2::pixels::Color; +use sdl2::rect::Rect; +use sdl2::render::{Texture, WindowCanvas}; use sdl2::EventPump; @@ -13,6 +16,7 @@ use std::cell::RefCell; use std::rc::Rc; use std::fs; +use std::io::Read; use std::path::{Path, PathBuf}; use std::process; use std::time; @@ -27,6 +31,8 @@ extern crate log; use flexi_logger; use flexi_logger::*; +use reqwest; + mod audio; mod input; mod video; @@ -43,22 +49,88 @@ use rustboyadvance_core::util::FpsCounter; const LOG_DIR: &str = ".logs"; 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 { rom_filename.with_extension("savestate") } /// 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 { + 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 { for event in event_pump.poll_iter() { match event { Event::DropFile { filename, .. } => { - return filename; + return Ok(filename); } 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>, Box> { + 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> { info!("Initializing SDL2 context"); 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 video_subsystem = sdl_context.video()?; @@ -96,35 +190,20 @@ fn main() -> Result<(), Box> { .build()?; let mut canvas = window.into_canvas().accelerated().build()?; - canvas.set_logical_size(SCREEN_WIDTH as u32, SCREEN_HEIGHT as u32)?; - - // 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"); + canvas.set_logical_size(CANVAS_WIDTH, CANVAS_HEIGHT)?; let mut rom_path = match matches.value_of("game_rom") { Some(path) => path.to_string(), _ => { 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 rom_name = Path::new(&rom_path).file_name().unwrap().to_str().unwrap();