laptop work

This commit is contained in:
Trevor Merritt 2024-09-21 14:31:21 -04:00
parent a12b5f254c
commit c8259157c5
8 changed files with 175 additions and 55 deletions

42
Cargo.lock generated
View File

@ -885,6 +885,7 @@ dependencies = [
"imgui-glium-renderer",
"imgui-winit-support",
"pretty_env_logger",
"rand 0.9.0-alpha.2",
"ratatui",
"winit 0.27.5",
]
@ -2554,8 +2555,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.0-alpha.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e256ff62cee3e03def855c4d4260106d2bb1696fdc01af03e9935b993720a5"
dependencies = [
"rand_chacha 0.9.0-alpha.2",
"rand_core 0.9.0-alpha.2",
"zerocopy",
]
[[package]]
@ -2565,7 +2577,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0-alpha.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d299e9db34f6623b2a9e86c015d6e173d5f46d64d4b9b8cc46ae8a982a50b04c"
dependencies = [
"ppv-lite86",
"rand_core 0.9.0-alpha.2",
]
[[package]]
@ -2577,6 +2599,16 @@ dependencies = [
"getrandom",
]
[[package]]
name = "rand_core"
version = "0.9.0-alpha.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4e93f5a5e3c528cda9acb0928c31b2ba868c551cc46e67b778075e34aab9906"
dependencies = [
"getrandom",
"zerocopy",
]
[[package]]
name = "ratatui"
version = "0.28.0"
@ -2624,8 +2656,8 @@ dependencies = [
"once_cell",
"paste",
"profiling",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"simd_helpers",
"system-deps",
"thiserror",

View File

@ -14,3 +14,4 @@ imgui-winit-support = { version = "0.12.0" }
winit = { version = "0.27", features = ["x11", "mint"] }
pretty_env_logger = "0.5.0"
copypasta = "0.8"
rand = "0.9.0-alpha.2"

View File

@ -5,9 +5,12 @@ use emmaemu::{
use imgui::*;
use ratatui::symbols::half_block;
use sys::{ImColor, ImVec2, ImVector_ImU32};
use rand::random;
use emmaemu::chip8::system_memory::Chip8SystemMemory;
use support::emmagui_support::EmmaGui;
mod support;
fn hello_world_window(ui: &Ui) {
let mut value = 1;
@ -34,21 +37,20 @@ fn hello_world_window(ui: &Ui) {
fn main() {
let system = Chip8Computer::default();
let mut system = Chip8Computer::default();
support::simple_init(file!(), move |_, ui| {
hello_world_window(ui);
// hello_world_window(ui);
let mut to_display = Box::new(Vec::new());
for i in 0..0xFF {
to_display.push(i);
}
EmmaGui::hex_memory_display(to_display, 0x7F, 0x80,ui);
EmmaGui::system_controls(&mut system, ui);
EmmaGui::registers_view(&system, ui);
EmmaGui::hex_memory_display(system.memory.clone(), 0x100, 0x10,ui);
EmmaGui::system_memory_render(system.memory, ui);
// EmmaGui::system_memory_render(system.memory, ui);
system.memory.gui_render(ui);
// system.memory.gui_render(ui);
});
}

View File

@ -1,50 +1,124 @@
use imgui::{Condition, ImColor32, Ui};
use emmaemu::chip8::computer::Chip8Computer;
use emmaemu::chip8::system_memory::Chip8SystemMemory;
use emmaemu::constants::{CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH};
pub struct EmmaGui {}
const CELL_WIDTH: i32 = 5i32;
const CELL_HEIGHT: i32 = 5i32;
impl EmmaGui {
pub fn hex_memory_display(bytes: Box<Vec<u8>>, rows: i32, cols: i32, ui: &Ui) {
// display a block of data
for current_row in 0..rows {
for current_column in 0..cols {
let data_offset = current_row * cols + current_column;
ui.text(format!("{:02x}", bytes[data_offset as usize]));
pub fn system_controls(system_to_control: &mut Chip8Computer, ui: &Ui) {
ui.window("!!!! CONTROLS !!!!")
.size([200.0, 200.0], Condition::FirstUseEver)
.build(|| {
ui.text("Computer Controls");
if ui.button("Step") {
system_to_control.step_system();
};
if ui.button("Load Program") {
println!("Load a program to start at 0x200");
}
if ui.button("Clear System Memory") {
println!("Clear Memory");
}
});
}
pub fn registers_view(system: &Chip8Computer, ui: &Ui) {
ui.window("Registers")
.size([400.0, 500.0], Condition::FirstUseEver)
.build(|| {
ui.text("Registers");
for i in 0..0x10 {
ui.text(format!("V{:X}: {}", i, system.registers[i as usize]));
if i != 7 {
ui.same_line();
}
}
ui.text("");
ui.text(format!("I: {:03X}", system.i_register));
ui.same_line();
ui.text(format!("ST: {:02X}", system.sound_timer));
ui.same_line();
ui.text(format!("DT: {:02X}", system.delay_timer));
ui.text(format!("PC: {:02X}", system.pc));
ui.text(format!("SP: {:02X}", system.sp));});
}
pub fn system_memory_render(memory: Chip8SystemMemory, ui: &Ui) {
ui.window("System Memory")
.size([300.0, 100.0], Condition::FirstUseEver)
.build(|| {
ui.text("Rendering System Memory Here");
let draw_list = ui.get_foreground_draw_list();
let mut idx = 0;
for row in 0..CHIP8_VIDEO_HEIGHT {
for column in 0..CHIP8_VIDEO_WIDTH {
let x_offset = column * CELL_WIDTH;
let y_offset = row * CELL_WIDTH;
let start_point = [x_offset as f32, y_offset as f32];
let end_point = [(x_offset + CELL_WIDTH) as f32,
(y_offset + CELL_HEIGHT) as f32
];
let memory_offset = (row * CHIP8_VIDEO_WIDTH) + column;
let target_color = if memory.peek(memory_offset as u16) == 0 {
ImColor32::BLACK
} else {
ImColor32::WHITE
};
draw_list.add_rect([x_offset as f32, y_offset as f32],
[(x_offset + CELL_WIDTH) as f32, (y_offset + CELL_HEIGHT) as f32],
target_color).build();
idx += 1;
}
}
pub fn hex_memory_display(bytes: Chip8SystemMemory, rows: i32, cols: i32, ui: &Ui) {
ui.window("System Memory")
.size([400.0, 300.0], Condition::FirstUseEver)
.build(|| {
let mut current_x_hover: i32 = 0;
let mut current_y_hover: i32 = 0;
// display a block of data
for current_row in 0..rows {
ui.text(format!("{:02x}", current_row * cols));
ui.same_line();
for current_column in 0..cols {
let data_offset = current_row * cols + current_column;
let formatted_text = format!("{:02x}", bytes.peek(data_offset as u16));
let text_location = ui.cursor_screen_pos();
let text_size = ui.calc_text_size(formatted_text.clone());
let bounding_box = imgui::sys::ImVec2 {
x: text_location[0] + text_size[0],
y: text_location[1] + text_size[1],
};
});
if ui.is_mouse_hovering_rect(text_location, [bounding_box.x, bounding_box.y]) {
// Optionally change the text color to indicate it's interactable
ui.text_colored([1.0, 0.0, 0.0, 1.0], formatted_text);
current_x_hover = current_column;
current_y_hover = current_row;
// Check if the left mouse button is clicked while hovering over the text
if ui.is_mouse_clicked(imgui::MouseButton::Left) {
println!("Text was clicked!");
// Perform any action here, e.g., call a function, trigger an event, etc.
}
} else {
// Default color text when not hovering
ui.text(formatted_text);
}
if current_column != (cols - 1) {
ui.same_line();
}
}
}
ui.text(format!("Offset 0x{:03x}", current_x_hover * cols + current_y_hover));
});
}
pub fn system_memory_render(memory: Chip8SystemMemory, ui: &Ui) {
ui.window("System Memory")
.size([300.0, 100.0], Condition::FirstUseEver)
.build(|| {
ui.text("Rendering System Memory Here");
let draw_list = ui.get_foreground_draw_list();
let mut idx = 0;
for row in 0..CHIP8_VIDEO_HEIGHT {
for column in 0..CHIP8_VIDEO_WIDTH {
let x_offset = column * CELL_WIDTH;
let y_offset = row * CELL_WIDTH;
let start_point = [x_offset as f32, y_offset as f32];
let end_point = [(x_offset + CELL_WIDTH) as f32,
(y_offset + CELL_HEIGHT) as f32
];
let memory_offset = (row * CHIP8_VIDEO_WIDTH) + column;
let target_color = if memory.peek(memory_offset as u16) == 0 {
ImColor32::BLACK
} else {
ImColor32::WHITE
};
draw_list.add_rect([x_offset as f32, y_offset as f32],
[(x_offset + CELL_WIDTH) as f32, (y_offset + CELL_HEIGHT) as f32],
target_color).build();
idx += 1;
}
}
});
}
}

View File

@ -47,11 +47,12 @@ impl Chip8Computer {
let low_byte = self.memory.clone().peek(self.pc + 1) as u16;
working_instruction = high_byte | low_byte;
let decided_instruction =
let decoded_instruction =
Chip8Computer::decode_instruction(self.clone(), working_instruction);
println!("DECODED INSTRUCTION = {:?}", decoded_instruction);
match (self.state, decided_instruction) {
match (self.state, decoded_instruction) {
(Chip8CpuStates::WaitingForInstruction, Chip8CpuInstructions::SysAddr(target_address)) => {
self.pc = target_address as u16;
},

View File

@ -1,3 +1,4 @@
#[derive(Debug)]
pub enum Chip8CpuInstructions {
SysAddr(i16), // 0x0nnn Exit to System Call
CLS, // * 0x00E0 Clear Screen

View File

@ -5,6 +5,7 @@ use ratatui::{style::Style, widgets::Widget};
use crate::constants::{CHIP8_MEMORY_SIZE, CHIP8_VIDEO_HEIGHT, CHIP8_VIDEO_WIDTH};
pub const CHIP8_PROGRAM_LOAD_OFFSET: i32 = 0x200;
pub const CHIP8FONT_0: [u8; 5] = [0xF0, 0x90, 0x90, 0x90, 0xF0];
pub const CHIP8FONT_1: [u8; 5] = [0x20, 0x60, 0x20, 0x20, 0x70];
pub const CHIP8FONT_2: [u8; 5] = [0xF0, 0x10, 0xF0, 0x80, 0xF0];
@ -53,10 +54,7 @@ const cell_width: i32 = 5i32;
const cell_height: i32 = 5i32;
impl Chip8SystemMemory {
pub fn gui_render(self, ui: &Ui) {
}
pub fn peek(self, address: u16) -> u8 {
pub fn peek(self, address: u16) -> u8 {
self.memory[address as usize]
}
@ -65,6 +63,17 @@ impl Chip8SystemMemory {
self
}
pub fn load_program(to_load_into: [u8; CHIP8_MEMORY_SIZE as usize], program_data: Box<Vec<u8>>) -> [u8; CHIP8_MEMORY_SIZE as usize] {
let mut load_target = to_load_into.clone();
// loop through the program data starting at 0x200
for load_index in 0..program_data.len() {
load_target[load_index + CHIP8_PROGRAM_LOAD_OFFSET as usize] = program_data[load_index];
}
load_target
}
pub fn load_to_memory(
to_load_into: [u8; CHIP8_MEMORY_SIZE as usize],
) -> [u8; CHIP8_MEMORY_SIZE as usize] {

View File

@ -1,5 +1,5 @@
pub const CHIP8_REGISTER_COUNT: i32 = 16;
pub const CHIP8_MEMORY_SIZE: i32 = 2048i32;
pub const CHIP8_MEMORY_SIZE: i32 = 4096i32;
pub const CHIP8_VIDEO_WIDTH: i32 = 64i32;
pub const CHIP8_VIDEO_HEIGHT: i32 = 32i32;
pub const CHIP8_VIDEO_MEMORY: usize = (CHIP8_VIDEO_HEIGHT * CHIP8_VIDEO_WIDTH) as usize;