chirp-imgui: Argument parsing + colors in Settings
This commit is contained in:
parent
dcbdd1383d
commit
861020a8ab
52
src/bin/chirp-imgui/args.rs
Normal file
52
src/bin/chirp-imgui/args.rs
Normal file
@ -0,0 +1,52 @@
|
||||
//! Parses arguments into a struct
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::Emulator;
|
||||
use chirp::Mode;
|
||||
use gumdrop::*;
|
||||
|
||||
/// Parses a hexadecimal string into a u16
|
||||
fn parse_hex(value: &str) -> std::result::Result<u16, std::num::ParseIntError> {
|
||||
u16::from_str_radix(value, 16)
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Options, Hash)]
|
||||
pub struct Arguments {
|
||||
#[options(help = "Load a ROM to run on Chirp.", required, free)]
|
||||
pub file: PathBuf,
|
||||
#[options(help = "Print this help message.")]
|
||||
help: bool,
|
||||
#[options(help = "Enable debug mode at startup.")]
|
||||
pub debug: bool,
|
||||
#[options(help = "Enable pause mode at startup.")]
|
||||
pub pause: bool,
|
||||
#[options(help = "Set the instructions-per-frame rate.")]
|
||||
pub speed: Option<usize>,
|
||||
// #[options(help = "Enable performance benchmarking on stderr (requires -S)")]
|
||||
// pub perf: bool,
|
||||
#[options(help = "Run in (Chip8, SChip, XOChip) mode.")]
|
||||
pub mode: Option<Mode>,
|
||||
#[options(help = "Set the target framerate.", default = "60", meta = "FR")]
|
||||
pub frame_rate: u64,
|
||||
}
|
||||
|
||||
impl Arguments {
|
||||
pub fn parse() -> Arguments {
|
||||
Arguments::parse_args_default_or_exit()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Arguments> for Emulator {
|
||||
fn from(value: Arguments) -> Self {
|
||||
let mut emu = Emulator::new(value.speed.unwrap_or(10), value.file);
|
||||
if let Some(mode) = value.mode {
|
||||
emu.set_quirks(mode.into());
|
||||
}
|
||||
if value.pause {
|
||||
emu.pause()
|
||||
}
|
||||
emu.set_disasm(value.debug);
|
||||
emu
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
use super::Drawable;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||
pub struct Menubar {
|
||||
pub(super) active: bool,
|
||||
pub file: File,
|
||||
@ -86,12 +86,12 @@ impl Drawable for Help {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Clone, Debug, Default, PartialEq, PartialOrd)]
|
||||
pub struct Settings {
|
||||
pub(super) target_ipf: usize,
|
||||
pub(super) quirks: chirp::Quirks,
|
||||
pub(super) mode_index: usize,
|
||||
pub(super) colors: [[u8; 4]; 2],
|
||||
pub(super) colors: [[f32; 4]; 2],
|
||||
pub(super) applied: bool,
|
||||
}
|
||||
|
||||
@ -100,6 +100,12 @@ impl Drawable for Settings {
|
||||
self.applied = false;
|
||||
ui.menu("Settings", || {
|
||||
use chirp::Mode::*;
|
||||
ui.menu("Foreground Color", || {
|
||||
self.applied |= ui.color_picker4("", &mut self.colors[0])
|
||||
});
|
||||
ui.menu("Background Color", || {
|
||||
self.applied |= ui.color_picker4("", &mut self.colors[1])
|
||||
});
|
||||
const MODES: [chirp::Mode; 3] = [Chip8, SChip, XOChip];
|
||||
if ui.combo_simple_string("Mode", &mut self.mode_index, &MODES) {
|
||||
self.quirks = MODES[self.mode_index].into();
|
||||
@ -115,7 +121,7 @@ impl Drawable for Settings {
|
||||
| ui.checkbox("Screen wraps at edge", &mut self.quirks.screen_wrap)
|
||||
| ui.checkbox("Shift ops ignore vY", &mut self.quirks.shift)
|
||||
| ui.checkbox("Jumps behave eratically", &mut self.quirks.stupid_jumps)
|
||||
}
|
||||
};
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -127,7 +133,32 @@ impl Settings {
|
||||
pub fn quirks(&mut self) -> &mut chirp::Quirks {
|
||||
&mut self.quirks
|
||||
}
|
||||
pub fn applied(&mut self) -> Option<(usize, chirp::Quirks)> {
|
||||
self.applied.then_some((self.target_ipf, self.quirks))
|
||||
pub fn set_mode(&mut self, mode: chirp::Mode) {
|
||||
self.mode_index = mode as usize;
|
||||
}
|
||||
pub fn set_color(&mut self, fg: &[u8; 4], bg: &[u8; 4]) {
|
||||
for (idx, component) in fg.iter().enumerate() {
|
||||
self.colors[0][idx] = *component as f32 / 255.0;
|
||||
}
|
||||
for (idx, component) in bg.iter().enumerate() {
|
||||
self.colors[1][idx] = *component as f32 / 255.0;
|
||||
}
|
||||
}
|
||||
pub fn applied(&mut self) -> Option<(usize, chirp::Quirks, [u8; 4], [u8; 4])> {
|
||||
let (fg, bg) = (self.colors[0], self.colors[1]);
|
||||
let fg = [
|
||||
(fg[0] * 255.0) as u8,
|
||||
(fg[1] * 255.0) as u8,
|
||||
(fg[2] * 255.0) as u8,
|
||||
(fg[3] * 255.0) as u8,
|
||||
];
|
||||
let bg = [
|
||||
(bg[0] * 255.0) as u8,
|
||||
(bg[1] * 255.0) as u8,
|
||||
(bg[2] * 255.0) as u8,
|
||||
(bg[3] * 255.0) as u8,
|
||||
];
|
||||
self.applied
|
||||
.then_some((self.target_ipf, self.quirks, fg, bg))
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,12 @@
|
||||
#![deny(clippy::all)]
|
||||
#![allow(dead_code)] // TODO: finish writing the code
|
||||
|
||||
mod args;
|
||||
mod emu;
|
||||
mod error;
|
||||
mod gui;
|
||||
|
||||
use crate::args::Arguments;
|
||||
use crate::emu::*;
|
||||
use crate::gui::*;
|
||||
use pixels::{Pixels, SurfaceTexture};
|
||||
@ -28,17 +30,11 @@ struct Application {
|
||||
}
|
||||
|
||||
fn main() -> Result<(), error::Error> {
|
||||
let rom_path;
|
||||
if let Some(path) = std::env::args().nth(1) {
|
||||
rom_path = path;
|
||||
} else {
|
||||
panic!("Supply a rom!");
|
||||
}
|
||||
|
||||
let args = Arguments::parse();
|
||||
let event_loop = EventLoop::new();
|
||||
let mut input = WinitInputHelper::new();
|
||||
|
||||
let size = LogicalSize::new(128 * 6, 64 * 6);
|
||||
let size = LogicalSize::new(128 * 8, 64 * 8);
|
||||
let window = WindowBuilder::new()
|
||||
.with_title("Chirp")
|
||||
.with_inner_size(size)
|
||||
@ -52,13 +48,18 @@ fn main() -> Result<(), error::Error> {
|
||||
Pixels::new(128, 64, surface_texture)?
|
||||
};
|
||||
|
||||
let mut app = Application::new(
|
||||
Emulator::new(INIT_SPEED, rom_path),
|
||||
Gui::new(&window, &pixels),
|
||||
);
|
||||
|
||||
let mut gui = Gui::new(&window, &pixels);
|
||||
// set initial parameters
|
||||
*app.gui.menubar.settings.target_ipf() = INIT_SPEED;
|
||||
if let Some(mode) = args.mode {
|
||||
gui.menubar.settings.set_mode(mode);
|
||||
}
|
||||
|
||||
gui.menubar.settings.set_color(FOREGROUND, BACKGROUND);
|
||||
*gui.menubar.settings.target_ipf() = args.speed.unwrap_or(INIT_SPEED);
|
||||
|
||||
let mut app = Application::new(args.into(), gui);
|
||||
|
||||
// Copy quirks from the running Emulator, for consistency
|
||||
*app.gui.menubar.settings.quirks() = app.emu.quirks();
|
||||
|
||||
// Run event loop
|
||||
@ -114,10 +115,10 @@ fn main() -> Result<(), error::Error> {
|
||||
state.emu.input(&input)?;
|
||||
|
||||
// Apply settings
|
||||
if let Some((ipf, quirks)) = state.gui.menubar.settings.applied() {
|
||||
if let Some((ipf, quirks, fg, bg)) = state.gui.menubar.settings.applied() {
|
||||
state.emu.ipf = ipf;
|
||||
state.emu.set_quirks(quirks);
|
||||
println!("'A");
|
||||
state.emu.colors = [fg, bg];
|
||||
}
|
||||
|
||||
// Update the scale factor
|
||||
|
Loading…
Reference in New Issue
Block a user