working on gemmaegui to build a usable UI
This commit is contained in:
@@ -9,50 +9,20 @@ use imgui::*;
|
||||
use sys::{ImColor, ImVec2, ImVector_ImU32};
|
||||
use rand::random;
|
||||
use gemma::chip8::system_memory::Chip8SystemMemory;
|
||||
use support::emmagui_support::EmmaGui;
|
||||
use support::{emmagui_support::EmmaGui, ui_state::UiState};
|
||||
|
||||
mod support;
|
||||
|
||||
struct UiState {
|
||||
pub show_registers: bool,
|
||||
pub show_memory: bool,
|
||||
pub show_video: bool,
|
||||
pub filename_to_load: String,
|
||||
pub on_colour: ImColor32,
|
||||
pub off_colour: ImColor32,
|
||||
pub is_running: bool,
|
||||
pub frame_time: f32,
|
||||
}
|
||||
/// Keypad Mappings for my Linux box
|
||||
/// 1 2 3 C
|
||||
/// 4 5 6 D
|
||||
/// 7 8 9 E
|
||||
/// A 0 B F
|
||||
|
||||
impl Clone for UiState {
|
||||
fn clone(&self) -> Self {
|
||||
UiState {
|
||||
show_registers: self.show_registers,
|
||||
show_memory: self.show_memory,
|
||||
show_video: self.show_video,
|
||||
filename_to_load: self.filename_to_load.to_string(),
|
||||
on_colour: self.on_colour,
|
||||
off_colour: self.off_colour,
|
||||
is_running: self.is_running,
|
||||
frame_time: self.frame_time,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for UiState {
|
||||
fn default() -> Self {
|
||||
UiState {
|
||||
show_registers: false,
|
||||
show_memory: false,
|
||||
show_video: true,
|
||||
filename_to_load: String::new(),
|
||||
on_colour: ImColor32::from_rgb(0xff, 0xff, 0x00),
|
||||
off_colour: ImColor32::from_rgb(0x00, 0xff, 0xff),
|
||||
is_running: false,
|
||||
frame_time: 10.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
const LIN_KEYS: [(u16, u8); 0x10] = [(537, 0x01),(538, 0x02),(539, 0x03),(540, 0x0c),
|
||||
(562, 0x04),(568, 0x05),(550, 0x06),(563, 0x0d),
|
||||
(546, 7),(564, 8),(549, 9),(551, 0xe),
|
||||
(571, 0xa),(569, 0),(548, 0xb),(569, 0xf)];
|
||||
|
||||
fn main() {
|
||||
pretty_env_logger::init();
|
||||
@@ -62,9 +32,35 @@ fn main() {
|
||||
|
||||
support::simple_init(file!(), move |_, ui| {
|
||||
let current_time = Instant::now();
|
||||
|
||||
let down_keys = ui.io().keys_down;
|
||||
for (key_code, key_reg) in LIN_KEYS {
|
||||
if down_keys[key_code as usize] {
|
||||
system.keypad.push_key(key_reg);
|
||||
} else {
|
||||
// do we need to release it?
|
||||
if system.keypad.pressed(key_reg) {
|
||||
system.keypad.release_key(key_reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
// println!("KEYS DOWN = {:?}", ui.io().keys_down);
|
||||
let time_since_last_tick = current_time.duration_since(last_tick_time).as_millis();
|
||||
if ui_state.is_running && time_since_last_tick > ui_state.frame_time as u128 {
|
||||
system.step_system();
|
||||
match system.state {
|
||||
gemma::chip8::cpu_states::Chip8CpuStates::WaitingForInstruction => {
|
||||
// this is the 'regular' mode for the CPU when we get here
|
||||
system.step_system();
|
||||
},
|
||||
gemma::chip8::cpu_states::Chip8CpuStates::WaitingForKey => {
|
||||
// waiting for a keychange...
|
||||
},
|
||||
gemma::chip8::cpu_states::Chip8CpuStates::ExecutingInstruction => { // should never see this.
|
||||
},
|
||||
gemma::chip8::cpu_states::Chip8CpuStates::Error => {
|
||||
panic!("System in undefined state.");
|
||||
},
|
||||
}
|
||||
last_tick_time = current_time;
|
||||
}
|
||||
|
||||
@@ -82,5 +78,9 @@ fn main() {
|
||||
let active_instruction = system.registers.peek_pc();
|
||||
EmmaGui::hex_memory_display(system.memory.clone(), (0x100, 0x10), active_instruction as i16, ui);
|
||||
}
|
||||
|
||||
if ui_state.show_keypad {
|
||||
EmmaGui::keypad_display(&system, ui);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use gemma::constants::CHIP8_KEYBOARD;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::{Path, PathBuf};
|
||||
@@ -10,6 +11,8 @@ use gemma::chip8::system_memory::Chip8SystemMemory;
|
||||
use gemma::constants::{CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH};
|
||||
use crate::UiState;
|
||||
|
||||
use super::ui_state;
|
||||
|
||||
pub struct EmmaGui {}
|
||||
|
||||
const CELL_WIDTH: i32 = 5i32;
|
||||
@@ -39,6 +42,23 @@ impl GuiFileList {
|
||||
|
||||
|
||||
impl EmmaGui {
|
||||
pub fn keypad_display(system_to_display: &Chip8Computer, ui: &Ui) {
|
||||
ui.text("Keypad");
|
||||
|
||||
for row in CHIP8_KEYBOARD {
|
||||
for key in row {
|
||||
let label = if system_to_display.keypad.pressed(key) {
|
||||
format!("*{:1x}*", key)
|
||||
} else {
|
||||
format!("{:1x}", key)
|
||||
};
|
||||
ui.text(format!("{}", label));
|
||||
ui.same_line();
|
||||
}
|
||||
ui.text("");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn video_display(system_to_control: &Chip8Computer, gui_state: &UiState, ui: &Ui) {
|
||||
// draw area size
|
||||
let draw_area_size = ui.io().display_size;
|
||||
@@ -46,7 +66,7 @@ impl EmmaGui {
|
||||
let cell_height = ((draw_area_size[1] as i32 / 32) * 6) / 10;
|
||||
|
||||
ui.window(format!("Display {cell_width}x{cell_height}"))
|
||||
.size([300.0, 300.0], Condition::FirstUseEver)
|
||||
.size([300.0, 300.0], Condition::Once)
|
||||
.build(|| {
|
||||
let origin = ui.cursor_screen_pos();
|
||||
let fg = ui.get_window_draw_list();
|
||||
@@ -94,16 +114,19 @@ impl EmmaGui {
|
||||
if ui.button("Step") {
|
||||
system_to_control.step_system();
|
||||
};
|
||||
ui.same_line();
|
||||
if ui.button("Run") {
|
||||
gui_state.is_running = true;
|
||||
debug!("STARTING THE SYSTEM");
|
||||
}
|
||||
ui.same_line();
|
||||
if ui.button("Stop") {
|
||||
gui_state.is_running = false;
|
||||
debug!("STOPPING THE SYSTEM");
|
||||
}
|
||||
ui.same_line();
|
||||
if ui.button("Reset") {
|
||||
gui_state.is_running = false;
|
||||
*system_to_control = Chip8Computer::new();
|
||||
}
|
||||
if ui.button("Dump Video Memory") {
|
||||
|
||||
@@ -10,6 +10,7 @@ use imgui_winit_support::{HiDpiMode, WinitPlatform};
|
||||
use std::path::Path;
|
||||
use std::time::Instant;
|
||||
|
||||
pub mod ui_state;
|
||||
pub mod emmagui_support;
|
||||
use copypasta::{ClipboardContext, ClipboardProvider};
|
||||
use imgui::ClipboardBackend;
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
use imgui::ImColor32;
|
||||
|
||||
|
||||
pub struct UiState {
|
||||
pub show_registers: bool,
|
||||
pub show_memory: bool,
|
||||
pub show_video: bool,
|
||||
pub show_keypad: bool,
|
||||
pub filename_to_load: String,
|
||||
pub on_colour: ImColor32,
|
||||
pub off_colour: ImColor32,
|
||||
pub is_running: bool,
|
||||
pub frame_time: f32,
|
||||
}
|
||||
|
||||
impl Clone for UiState {
|
||||
fn clone(&self) -> Self {
|
||||
UiState {
|
||||
show_registers: self.show_registers,
|
||||
show_memory: self.show_memory,
|
||||
show_video: self.show_video,
|
||||
show_keypad: self.show_keypad,
|
||||
filename_to_load: self.filename_to_load.to_string(),
|
||||
on_colour: self.on_colour,
|
||||
off_colour: self.off_colour,
|
||||
is_running: self.is_running,
|
||||
frame_time: self.frame_time,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for UiState {
|
||||
fn default() -> Self {
|
||||
UiState {
|
||||
show_registers: false,
|
||||
show_memory: false,
|
||||
show_video: true,
|
||||
show_keypad: true,
|
||||
filename_to_load: String::new(),
|
||||
on_colour: ImColor32::from_rgb(0xff, 0xff, 0x00),
|
||||
off_colour: ImColor32::from_rgb(0x00, 0xff, 0xff),
|
||||
is_running: false,
|
||||
frame_time: 10.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user