From 77f78d431b02b04501fb2b81524a190f96b9ffa7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Wed, 26 Apr 2023 23:24:00 +0100
Subject: [PATCH] feat: initial support for clap CLI arg parsing Allows for
 more flexibility passing command line arguments.

---
 frontends/sdl/Cargo.toml  |  4 ++++
 frontends/sdl/src/main.rs | 18 ++++++++++++++++--
 src/gb.rs                 | 18 ++++++++++++++++++
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/frontends/sdl/Cargo.toml b/frontends/sdl/Cargo.toml
index 619b6e53..396386a5 100644
--- a/frontends/sdl/Cargo.toml
+++ b/frontends/sdl/Cargo.toml
@@ -13,6 +13,10 @@ debug = ["boytacean/debug"]
 pedantic = ["boytacean/pedantic"]
 cpulog = ["boytacean/cpulog"]
 
+[dependencies.clap]
+version = "4"
+features = ["derive"]
+
 [dependencies.boytacean]
 path = "../.."
 
diff --git a/frontends/sdl/src/main.rs b/frontends/sdl/src/main.rs
index 9013fb93..1bc7d23e 100644
--- a/frontends/sdl/src/main.rs
+++ b/frontends/sdl/src/main.rs
@@ -13,6 +13,7 @@ use boytacean::{
     ppu::{PaletteInfo, PpuMode, DISPLAY_HEIGHT, DISPLAY_WIDTH},
 };
 use chrono::Utc;
+use clap::Parser;
 use graphics::{surface_from_bytes, Graphics};
 use image::ColorType;
 use sdl2::{event::Event, keyboard::Keycode, pixels::PixelFormatEnum, Sdl};
@@ -455,8 +456,21 @@ impl Emulator {
     }
 }
 
+#[derive(Parser, Debug)]
+#[command(author, version, about, long_about = None)]
+struct Args {
+    #[arg(short, long, default_value_t = String::from("cgb"))]
+    mode: String,
+
+    #[arg(short, long, default_value_t = String::from("../../res/roms.prop/tetris_dx.gbc"))]
+    rom_path: String,
+}
+
 fn main() {
-    let mode = GameBoyMode::Cgb;
+    // parses the provided command line arguments and uses them to
+    // obtain structured values
+    let args = Args::parse();
+    let mode = GameBoyMode::from_str(&args.mode);
 
     // prints the current version of the emulator (informational message)
     println!("Boytacean v{} - {}", VERSION, mode);
@@ -484,7 +498,7 @@ fn main() {
     // ROM file and starts running it
     let mut emulator = Emulator::new(game_boy);
     emulator.start(SCREEN_SCALE);
-    emulator.load_rom(Some("../../res/roms.prop/tetris_dx.gbc"));
+    emulator.load_rom(Some(&args.rom_path));
     //emulator.load_rom(Some("../../res/roms/demo/pocket.gb"));
     emulator.toggle_palette();
     emulator.run();
diff --git a/src/gb.rs b/src/gb.rs
index 47560371..b4ddc0ce 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -56,6 +56,24 @@ impl GameBoyMode {
             GameBoyMode::Sgb => "Super Game Boy (SGB)",
         }
     }
+
+    pub fn from_u8(value: u8) -> GameBoyMode {
+        match value {
+            1 => GameBoyMode::Dmg,
+            2 => GameBoyMode::Cgb,
+            3 => GameBoyMode::Sgb,
+            _ => panic!("Invalid mode value: {}", value),
+        }
+    }
+
+    pub fn from_str(value: &str) -> GameBoyMode {
+        match value {
+            "dmg" => GameBoyMode::Dmg,
+            "cgb" => GameBoyMode::Cgb,
+            "sgb" => GameBoyMode::Sgb,
+            _ => panic!("Invalid mode value: {}", value),
+        }
+    }
 }
 
 impl Display for GameBoyMode {
-- 
GitLab