diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 963a8dd..b8bb0c7 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -5,7 +5,10 @@ mod nes_parser; +use std::fs::File; +use std::io::Error; use std::io::Read; +use std::path::PathBuf; use tauri::Manager; use nes_parser::INesVersion; @@ -16,6 +19,7 @@ struct Payload { #[derive(Clone, serde::Serialize)] struct INesData { + filepath: String, filename: String, prg_rom_size: u32, chr_rom_size: u32, @@ -47,7 +51,7 @@ fn select_file(app: tauri::AppHandle) { app.emit_all("error", Payload { message: "The selected file must have a .nes extension".into() }).unwrap(); return; } - let file_result = std::fs::File::open(&path_buf); + let file_result = File::open(&path_buf); if file_result.is_err() { app.emit_all("error", Payload { message: "Unable to open file".into() }).unwrap(); return; @@ -80,8 +84,11 @@ fn select_file(app: tauri::AppHandle) { let header = nes_parser::INesHeader::from_rom(&contents); match header { Ok(header) => { + let filepath: String = path_buf.display().to_string(); + let filename: String = path_buf.file_name().unwrap().to_os_string().into_string().unwrap(); app.emit_all("loaded_ines", INesData { - filename: path_buf.file_name().unwrap().to_os_string().into_string().unwrap(), + filepath: filepath, + filename: filename, prg_rom_size: header.prg_rom_size(), chr_rom_size: header.chr_rom_size(), mirroring_type: header.mirroring_type(), @@ -115,9 +122,63 @@ fn select_file(app: tauri::AppHandle) { }); } +#[tauri::command] +fn download_chr_ram(filepath: &str, app: tauri::AppHandle) { + let path_buf: PathBuf = PathBuf::from(filepath); + if !path_buf.is_file() { + app.emit_all("error", Payload { message: "File not found".into() }).unwrap(); + return; + } + let file_result: Result = File::open(&path_buf); + if file_result.is_err() { + app.emit_all("error", Payload { message: "Unable to open file".into() }).unwrap(); + return; + } + let mut file: File = file_result.unwrap(); + let mut contents: Vec = Vec::new(); + let read_result = file.read_to_end(&mut contents); + if read_result.is_err() { + app.emit_all("error", Payload { message: "Unable to read file".into() }).unwrap(); + return; + } + let version = nes_parser::parse_version(&contents); + match version { + Ok(INesVersion::INes20) => { + app.emit_all("error", Payload { message: "Can't handle iNES 2.0 ROMs yet".into() }).unwrap(); + } + Ok(INesVersion::INes) => { + let header = nes_parser::INesHeader::from_rom(&contents); + match header { + Ok(header) => { + if header.chr_rom_size() < 1 { + app.emit_all("error", Payload { message: "This ROM has no CHR ROM".into() }).unwrap(); + return; + } + let chr_rom_pointer: u32 = + 16 + // header size + (if header.has_trainer() { 512 } else { 0 }) + + header.prg_rom_size(); + let mut chr_rom: Vec = Vec::new(); + /* TODO find CHR ROM and download it */ + } + Err(error) => { + app.emit_all("error", Payload { message: nes_parser::get_error_message(error).into() }).unwrap(); + } + } + } + Ok(INesVersion::INesArchaic) => { + app.emit_all("error", Payload { message: "Can't handle archaic iNES ROMs yet".into() }).unwrap(); + } + Err(_) => { + app.emit_all("error", Payload { message: "Unable to recognize the iNES version".into() }).unwrap(); + } + } + println!("{}", path_buf.display()); +} + fn main() { tauri::Builder::default() - .invoke_handler(tauri::generate_handler![select_file]) + .invoke_handler(tauri::generate_handler![select_file, download_chr_ram]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/src/index.html b/src/index.html index 6c9ab46..d3e231e 100644 --- a/src/index.html +++ b/src/index.html @@ -21,6 +21,9 @@
    +
    +
      +

      diff --git a/src/script.js b/src/script.js index 5a54ae4..7f46280 100644 --- a/src/script.js +++ b/src/script.js @@ -8,7 +8,6 @@ window.addEventListener("DOMContentLoaded", (e) => { }); listen("loaded_ines", e => { - console.log(e); document.body.classList.remove( "no-file-selected", "is-loading", @@ -17,6 +16,7 @@ listen("loaded_ines", e => { document.body.classList.add("file-loaded"); fileProperties.innerHTML = ""; [ + ["File path", e.payload.filepath], ["File name", e.payload.filename], ["PRG ROM size", e.payload.prg_rom_size+" bytes"], ["CHR ROM size", e.payload.chr_rom_size+" bytes"], @@ -35,6 +35,18 @@ listen("loaded_ines", e => { domElement.innerHTML = ""+el[0]+": "+el[1]; fileProperties.appendChild(domElement); }); + if(e.payload.chr_rom_size > 0) { + let chrRomDownloadButton = document.createElement("button"); + chrRomDownloadButton.type = "button"; + chrRomDownloadButton.innerText = "Download CHR RAM"; + let filepath = e.payload.filepath; + chrRomDownloadButton.addEventListener("click", e => { + invoke("download_chr_ram", { + filepath: filepath, + }) + }); + actions.appendChild(chrRomDownloadButton); + } }); listen("loading", e => {