fixes reset from exection completion

adds 'default.oc8'
adds control window size to state for load/save of settings maybe?
moves TestCompressionTool code into InstructionUtil
remove gemmautil and moves into gemma
This commit is contained in:
2024-11-08 09:42:28 -05:00
parent 67ca71ccb7
commit cddbe0c46e
41 changed files with 464 additions and 310 deletions
-1
View File
@@ -74,7 +74,6 @@ fn main() {
system.wait_for_instruction();
} else {
// do we need to release it?
if system.is_key_pressed(key_reg) {
system.release_key(key_reg);
}
+180 -161
View File
@@ -12,6 +12,8 @@ use log::debug;
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
use imgui::sys::ImGuiIO;
use gemma::chip8::instructions::Chip8CpuInstructions;
const ROM_ROOT: &str = "resources/roms";
@@ -43,70 +45,186 @@ impl GemmaImguiSupport {
pub fn video_display(system_to_control: &Chip8Computer, gui_state: &ImGuiUiState, ui: &Ui) {
// draw area size
let (width, height) = system_to_control.video_memory.get_resolution();
let draw_area_size = ui.io().display_size;
// println!("DRAW_AREA_SIZE = {}x{}", draw_area_size[0], draw_area_size[1]);
let cell_width = ((draw_area_size[0] as i32 / width) * 6) / 10;
let cell_height = ((draw_area_size[1] as i32 / height) * 6) / 10;
ui.window("Video")
.size([gui_state.video_window_size[0] as f32, gui_state.video_window_size[1] as f32], Condition::Once)
.build(|| {
let draw_area_size = ui.window_size();
let draw_offset = ui.window_pos();
// now lets move the draw_offset by 0,20 to get it off the window title bar
let draw_offset = [draw_offset[0], draw_offset[1] + 20.0];
// and reduce the draw area size by the same values. {}
let draw_area_size = [draw_area_size[0], draw_area_size[1] - 20.0];
// println!("DRAW_AREA_SIZE = {}x{}", draw_area_size[0], draw_area_size[1]);
let cell_width = ((draw_area_size[0] as i32 / width));
let cell_height = ((draw_area_size[1] as i32 / height));
let origin = ui.cursor_pos();
let fg = ui.get_foreground_draw_list();
if system_to_control.video_memory.is_highres() {
// ui.text("High Def Video here");
for current_row in 0..=height {
let y_offset = origin[1] as i32 + (current_row * cell_height);
for current_column in 0..=width {
let x_offset = origin[0] as i32 + (current_column * cell_width);
let current_origin = [x_offset as f32, y_offset as f32];
let current_limit = [
(x_offset + cell_width) as f32,
(y_offset + cell_height) as f32,
];
let memory_offset = (current_row * width + current_column) as u16;
let to_render = system_to_control.video_memory.peek(memory_offset);
let color: ImColor32 = if to_render {
gui_state.on_colour
} else {
gui_state.off_colour
};
fg.add_rect_filled_multicolor(
current_origin,
current_limit,
color,
color,
color,
color,
);
let origin = draw_offset;
let fg = ui.get_foreground_draw_list();
for current_row in 0..height {
let y_offset = origin[1] as i32 + (current_row * cell_height);
for current_column in 0..width {
let x_offset = origin[0] as i32 + (current_column * cell_width);
let current_origin = [x_offset as f32, y_offset as f32];
let current_limit = [
(x_offset + cell_width) as f32,
(y_offset + cell_height) as f32,
];
let memory_offset = (current_row * width + current_column) as u16;
let to_render = system_to_control.video_memory.peek(memory_offset);
let color: ImColor32 = if to_render {
gui_state.on_colour
} else {
gui_state.off_colour
};
fg.add_rect_filled_multicolor(
current_origin,
current_limit,
color,
color,
color,
color,
);
}
}
}).expect("cant draw the video i guess");
}
pub fn quirks_picker(system: &mut Chip8ComputerManager,
ui: &Ui) {
let selectors = [Chip8, SChipModern, XOChip];
for current_selector in selectors {
let mut working_selector =
ui.selectable_config(current_selector.clone().to_string());
match system.quirks_mode() {
Chip8 => {
working_selector = working_selector.selected(true);
}
SChipModern => {
working_selector = working_selector.selected(true);
}
XOChip => {
working_selector = working_selector.selected(true);
}
}
} else {
for current_row in 0..height {
let y_offset = origin[1] as i32 + (current_row * cell_height);
for current_column in 0..width {
let x_offset = origin[0] as i32 + (current_column * cell_width);
let current_origin = [x_offset as f32, y_offset as f32];
let current_limit = [
(x_offset + cell_width) as f32,
(y_offset + cell_height) as f32,
];
let memory_offset = (current_row * width + current_column) as u16;
let to_render = system_to_control.video_memory.peek(memory_offset);
let color: ImColor32 = if to_render {
gui_state.on_colour
} else {
gui_state.off_colour
};
fg.add_rect_filled_multicolor(
current_origin,
current_limit,
color,
color,
color,
color,
if working_selector.build() {
system.reset(current_selector);
println!("CLICK ON {}", &current_selector);
}
}
}
fn control_pickers(
system: &mut Chip8ComputerManager,
gui_state: &mut ImGuiUiState,
ui: &Ui,
) {
if CollapsingHeader::new("Controls").build(ui) {
// if the system has no program loaded hide the buttons.
let bytes: [u8; 2] = [
system.state().memory.peek(0x200),
system.state().memory.peek(0x201),
];
let show_buttons = true; // bytes[0] != 0 || bytes[1] == 0xe0;
if show_buttons {
if ui.button("Step") {
system.step();
};
ui.same_line();
if ui.button("Run") {
system.start();
}
}
ui.same_line();
if ui.button("Stop") {
system.stop();
}
ui.same_line();
if ui.button("Reset") {
system.reset(system.quirks_mode());
}
if ui.button("Dump Video Memory") {
println!("{}", system.dump_to_string(Video));
}
ui.same_line();
if ui.button("Dump Keypad State") {
println!("{}", system.dump_to_string(Keyboard));
}
ui.same_line();
if ui.button("Dump Registers") {
println!("{}", system.dump_to_string(Registers));
}
}
}
fn system_summary(
system: &Chip8ComputerManager,
ui: &Ui,
) {
/* System Step Counter */
ui.text(format!("Step {:04x}", system.num_cycles()).as_str());
ui.text(format!("Mode {}", system.quirks_mode()));
}
fn rom_lister(
system: &mut Chip8ComputerManager,
gui_state: &mut ImGuiUiState,
ui: &Ui,
) {
/* ROM Lister */
if CollapsingHeader::new("Roms").build(ui) {
let new_filename = GuiFileList::display_path(
gui_state.roms_root_path.clone(),
&gui_state.filename_to_load,
ui,
);
if !new_filename.is_empty() {
if new_filename != gui_state.filename_to_load {
debug!("NEW FILENAME SELECTED -> {new_filename}");
gui_state.filename_to_load = new_filename;
}
if ui.button("Load Program") {
let mut buffer: Vec<u8> = Vec::new();
let full_name = format!(
"{}/{}",
gui_state
.roms_root_path
.clone()
.as_os_str()
.to_string_lossy(),
gui_state.filename_to_load.to_string()
);
debug!("PREPARING TO LOAD {}", full_name);
let input_file = File::open(Path::new(&full_name));
input_file
.unwrap()
.read_to_end(&mut buffer)
.expect("Unable to read rom.");
system.load_new_program_to_system_memory(buffer);
}
}
}
}
fn display_options(
gui_state: &mut ImGuiUiState,
ui: &Ui,
) {
if CollapsingHeader::new("Options").build(ui) {
ui.checkbox("Show Memory", &mut gui_state.show_memory);
ui.same_line();
ui.checkbox("Show Video", &mut gui_state.show_video);
ui.same_line();
ui.checkbox("Show Registers", &mut gui_state.show_registers);
ui.same_line();
ui.checkbox("Show Keypad", &mut gui_state.show_keypad);
ui.input_int("Target IPS", &mut gui_state.target_ips)
.build();
};
}
pub fn system_controls(
system_to_control: &mut Chip8ComputerManager,
gui_state: &mut ImGuiUiState,
@@ -116,114 +234,15 @@ impl GemmaImguiSupport {
ui.window("!!!! CONTROLS !!!!")
.position([100.0, 640.0], Condition::FirstUseEver)
.build(|| {
/* System Step Counter */
ui.text(format!("Step {:04x}", system_to_control.num_cycles()).as_str());
ui.text(format!("Mode {}", system_to_control.quirks_mode()));
/* ROM Lister */
if CollapsingHeader::new("Roms").build(ui) {
let new_filename = GuiFileList::display_path(
gui_state.roms_root_path.clone(),
&gui_state.filename_to_load,
ui,
);
if !new_filename.is_empty() {
if new_filename != gui_state.filename_to_load {
debug!("NEW FILENAME SELECTED -> {new_filename}");
gui_state.filename_to_load = new_filename;
}
if ui.button("Load Program") {
let mut buffer: Vec<u8> = Vec::new();
let full_name = format!(
"{}/{}",
gui_state
.roms_root_path
.clone()
.as_os_str()
.to_string_lossy(),
gui_state.filename_to_load.to_string()
);
debug!("PREPARING TO LOAD {}", full_name);
GemmaImguiSupport::system_summary(system_to_control, ui);
let input_file = File::open(Path::new(&full_name));
input_file
.unwrap()
.read_to_end(&mut buffer)
.expect("Unable to read rom.");
system_to_control.load_new_program_to_system_memory(buffer);
}
}
}
GemmaImguiSupport::rom_lister(system_to_control, gui_state, ui);
if CollapsingHeader::new("Controls").build(ui) {
// if the system has no program loaded hide the buttons.
let bytes: [u8; 2] = [
system_to_control.state().memory.peek(0x200),
system_to_control.state().memory.peek(0x201),
];
let show_buttons = bytes[0] != 0 || bytes[1] == 0xe0;
GemmaImguiSupport::control_pickers(system_to_control, gui_state, ui);
if show_buttons {
if ui.button("Step") {
system_to_control.step();
};
ui.same_line();
if ui.button("Run") {
system_to_control.start();
}
}
ui.same_line();
if ui.button("Stop") {
system_to_control.stop();
}
ui.same_line();
if ui.button("Reset") {
system_to_control.reset(system_to_control.quirks_mode());
}
if ui.button("Dump Video Memory") {
println!("{}", system_to_control.dump_to_string(Video));
}
ui.same_line();
if ui.button("Dump Keypad State") {
debug!("{}", system_to_control.dump_to_string(Keyboard));
}
ui.same_line();
if ui.button("Dump Registers") {
debug!("{}", system_to_control.dump_to_string(Registers));
}
}
GemmaImguiSupport::display_options(gui_state, ui);
if CollapsingHeader::new("Options").build(ui) {
ui.checkbox("Show Memory", &mut gui_state.show_memory);
ui.same_line();
ui.checkbox("Show Video", &mut gui_state.show_video);
ui.same_line();
ui.checkbox("Show Registers", &mut gui_state.show_registers);
ui.same_line();
ui.checkbox("Show Keypad", &mut gui_state.show_keypad);
ui.input_int("Target IPS", &mut gui_state.target_ips)
.build();
};
let selectors = [Chip8, SChipModern, XOChip];
for current_selector in selectors {
let mut working_selector =
ui.selectable_config(current_selector.clone().to_string());
match system_to_control.quirks_mode() {
Chip8 => {
working_selector = working_selector.selected(true);
}
SChipModern => {
working_selector = working_selector.selected(true);
}
XOChip => {
working_selector = working_selector.selected(true);
}
}
if working_selector.build() {
system_to_control.reset(current_selector);
println!("CLICK ON {}", &current_selector);
}
}
GemmaImguiSupport::quirks_picker(system_to_control, ui);
});
}
@@ -232,7 +251,7 @@ impl GemmaImguiSupport {
.position([100.0, 640.0], Condition::FirstUseEver)
.build(|| {
ui.text("Registers");
for i in 1..0x10 {
for i in 0..0x10 {
ui.text(format!("V{:X}: {}", i, system.registers.peek(i)));
if i != 7 {
ui.same_line();
+17 -11
View File
@@ -1,7 +1,7 @@
use std::ffi::OsString;
use std::fs::read_dir;
use std::path::PathBuf;
use imgui::Ui;
use imgui::{ChildWindow, Ui};
use log::debug;
pub struct GuiFileList {}
@@ -20,16 +20,22 @@ impl GuiFileList {
known_files.sort();
for (index, entry) in known_files.iter().enumerate() {
let mut working_select = ui.selectable_config(entry.clone().into_string().unwrap().to_string());
if *entry.to_str().unwrap() == *selected_filename.as_str() {
working_select = working_select.selected(true);
}
if working_select.build() {
debug!("SELECTED {index} / {entry:?}");
working_filename = entry.clone().into_string().unwrap();
};
}
ui.child_window("Item List")
.size([0.0, 200.0])
.border(false)
.build(|| {
for (index, entry) in known_files.iter().enumerate() {
let mut working_select = ui.selectable_config(entry.clone().into_string().unwrap().to_string());
if *entry.to_str().unwrap() == *selected_filename.as_str() {
working_select = working_select.selected(true);
}
if working_select.build() {
debug!("SELECTED {index} / {entry:?}");
working_filename = entry.clone().into_string().unwrap();
};
}
});
working_filename
}
}
+1 -1
View File
@@ -179,7 +179,7 @@ pub fn create_context() -> imgui::Context {
}),
},
]);
imgui.set_ini_filename(None);
// imgui.set_ini_filename(None);
imgui
}
+10 -4
View File
@@ -16,7 +16,9 @@ pub struct ImGuiUiState {
pub frame_time: u32,
pub last_frame_instant: Instant,
pub target_ips: i32,
pub roms_root_path: PathBuf
pub roms_root_path: PathBuf,
pub video_window_size: [i32; 2],
pub control_window_size: [i32; 2]
}
impl Clone for ImGuiUiState {
@@ -33,7 +35,9 @@ impl Clone for ImGuiUiState {
frame_time: self.frame_time,
last_frame_instant: self.last_frame_instant,
target_ips: self.target_ips,
roms_root_path: self.roms_root_path.to_owned()
roms_root_path: self.roms_root_path.to_owned(),
video_window_size: self.video_window_size,
control_window_size: self.control_window_size
}
}
}
@@ -51,8 +55,10 @@ impl Default for ImGuiUiState {
is_running: false,
frame_time: 16,
last_frame_instant: Instant::now(),
target_ips: 200000,
roms_root_path: PathBuf::from(ROMPATH_DEFAULT)
target_ips: 20,
roms_root_path: PathBuf::from(ROMPATH_DEFAULT),
control_window_size: [200, 600],
video_window_size: [800, 600]
}
}
}