From 78288bca4b7c7b9c94d019795339d527c35d112b Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 1 Feb 2024 01:16:39 +0100 Subject: [PATCH] allow loading zip files --- Cargo.lock | 13 +++++++++++++ yarge-frontend-sdl/Cargo.toml | 4 +++- yarge-frontend-sdl/src/main.rs | 29 ++++++++++++++++++++++++++--- yarge-frontend-sdl/src/menu.rs | 2 +- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7c13ca..5d516e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4101,6 +4101,7 @@ dependencies = [ "windows 0.52.0", "winres", "yarge-core", + "zip", ] [[package]] @@ -4189,6 +4190,18 @@ dependencies = [ "zvariant", ] +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] + [[package]] name = "zvariant" version = "3.15.0" diff --git a/yarge-frontend-sdl/Cargo.toml b/yarge-frontend-sdl/Cargo.toml index 380ae63..38b6303 100644 --- a/yarge-frontend-sdl/Cargo.toml +++ b/yarge-frontend-sdl/Cargo.toml @@ -17,6 +17,7 @@ bincode = "1.3" anyhow = "1.0" dirs = { version = "5.0", optional = true } dark-light = { version = "1.0", optional = true } +zip = { version = "0.6", default-features = false, features = ["deflate"], optional = true } [target.'cfg(windows)'.dependencies] windows = { version = "0.52", optional = true } @@ -25,12 +26,13 @@ windows = { version = "0.52", optional = true } winres = { version = "0.1", optional = true } [features] -default = ["global_config", "hidpi", "system-theme"] +default = ["global_config", "hidpi", "system-theme", "archive"] production = ["windows-icon"] global_config = ["dep:dirs"] hidpi = ["dep:windows", "windows/Win32_UI_HiDpi"] system-theme = ["dep:dark-light"] windows-icon = ["dep:winres"] +archive = ["dep:zip"] [package.metadata.deb] maintainer = "griffi-gh " diff --git a/yarge-frontend-sdl/src/main.rs b/yarge-frontend-sdl/src/main.rs index 7e88c5f..1012d9e 100644 --- a/yarge-frontend-sdl/src/main.rs +++ b/yarge-frontend-sdl/src/main.rs @@ -1,9 +1,10 @@ #![cfg_attr(target_os = "windows", cfg_attr(feature = "production", windows_subsystem = "windows"))] use yarge_core::{ + consts::{WIDTH as GB_WIDTH, HEIGHT as GB_HEIGHT}, Gameboy, Key as GbKey, - consts::{WIDTH as GB_WIDTH, HEIGHT as GB_HEIGHT} + YargeError }; use sdl2::{ pixels::{PixelFormatEnum, Color}, @@ -12,7 +13,7 @@ use sdl2::{ render::BlendMode, }; use clap::Parser; -use std::{path::PathBuf, time::Instant}; +use std::{io::Read, path::PathBuf, time::Instant}; mod audio; mod menu; @@ -69,6 +70,28 @@ impl Default for URStorage { } } +/// Load ROM file, with support for ZIP files +pub(crate) fn load_rom_helper(gb: &mut Gameboy, data: &[u8]) -> Result<(), YargeError> { + //TODO handle failures more gracefully + #[cfg(feature = "archive")] + if data[0..2] == [0x50, 0x4B] { + println!("looks like a zip file"); + let cursor = std::io::Cursor::new(data); + let mut zip = zip::ZipArchive::new(cursor).unwrap(); + if zip.is_empty() { + panic!("zip is empty"); + } + if zip.file_names().count() > 1 { + panic!("zip contains more than one file"); + } + let mut buf = vec![]; + zip.by_index(0).unwrap().read_to_end(&mut buf).unwrap(); + gb.load_rom(&buf)?; + return Ok(()) + } + gb.load_rom(data) +} + fn main() { //Set dpi aware flag on windows #[cfg(all(windows, feature = "hidpi"))] { @@ -103,7 +126,7 @@ fn main() { //Load the ROM file if let Some(path) = args.rom_path.as_ref() { let rom = std::fs::read(path).expect("Failed to load the ROM file"); - gb.load_rom(&rom).expect("Invalid ROM file"); + load_rom_helper(&mut gb, &rom).expect("Invalid ROM file"); config.last_rom = Some(path.into()); } diff --git a/yarge-frontend-sdl/src/menu.rs b/yarge-frontend-sdl/src/menu.rs index 662267a..2a200cf 100644 --- a/yarge-frontend-sdl/src/menu.rs +++ b/yarge-frontend-sdl/src/menu.rs @@ -273,7 +273,7 @@ impl Menu { pub fn load_file(&mut self, path: PathBuf, gb: &mut Gameboy, config: &Configuration) { let data = fs::read(path).unwrap(); gb.reset(); - gb.load_rom(&data[..]).unwrap(); + crate::load_rom_helper(gb, &data[..]).unwrap(); SaveManager::load_idk(gb, config.save_slot); SaveManager::save(gb, config.save_slot).unwrap(); //Create save file }