132 lines
4.7 KiB
Rust
132 lines
4.7 KiB
Rust
use std::io::{BufRead, BufReader};
|
|
use std::net::TcpStream;
|
|
use gemma::chip8::computer_manager::Chip8ComputerManager;
|
|
use gemma::chip8::quirk_modes::QuirkMode;
|
|
use crate::telnet_utils::list_of_files_in_directory;
|
|
use std::io::Write;
|
|
use std::path::Path;
|
|
use gemma::constants::RESOURCES_ROOT;
|
|
use crate::constants::*;
|
|
|
|
const ERROR_CANT_NOTIFY: &str = "Unable to notify client";
|
|
const MENU_TEXT: &str = r#"
|
|
---------------------------
|
|
status -> Current status of the Instance
|
|
new -> Start New Instance
|
|
* list -> list available files to load into Chip-8 Instance
|
|
* load <filename> -> Load Chip-8 Program from server
|
|
help -> display this help
|
|
step -> step chip-8 machine 1 step
|
|
* steps <number> -> Step a fixed number of steps
|
|
* memory -> dump current memory from chip-8 instance
|
|
* video -> dump current video from chip-8 instance
|
|
* window <start> <length> -> display a window of memory
|
|
disconnect -> close connection
|
|
---------------------------
|
|
"#;
|
|
|
|
pub fn handle_client(mut stream: TcpStream) {
|
|
// each client gets their own instance of a Chip-8 system
|
|
let mut chip8 = Chip8ComputerManager::default();
|
|
|
|
let peer_addr = stream.peer_addr().unwrap();
|
|
println!("New CX From {}", peer_addr);
|
|
|
|
let mut reader = BufReader::new(stream.try_clone().unwrap());
|
|
let mut line = String::new();
|
|
|
|
write!(stream, "Welcome to Gemma Telnet Server\n").unwrap();
|
|
write!(stream, "{}", MENU_TEXT).unwrap();
|
|
|
|
let mut time_to_die: bool = false;
|
|
|
|
while !time_to_die {
|
|
|
|
// clear the buffer
|
|
line.clear();
|
|
|
|
// read from the client to the buffer
|
|
let bytes = reader.read_line(&mut line).unwrap();
|
|
if bytes == 0 {
|
|
println!("Connection closed by {}", peer_addr);
|
|
break;
|
|
}
|
|
|
|
// display the message received
|
|
eprint!("RX {}: {}", peer_addr, line);
|
|
|
|
// split the line into <command> <param1> <param2> (if params exist)
|
|
|
|
let mut result = line.split(" ");
|
|
let command = result.next().unwrap();
|
|
let p1 = result.next();
|
|
let p2 = result.next();
|
|
|
|
let mut message_to_send: String = "Unrecognized Command".to_string();
|
|
|
|
match command.trim() {
|
|
CMD_STATUS => {
|
|
message_to_send = chip8.status_as_string();
|
|
}
|
|
CMD_DISCONNECT => {
|
|
message_to_send = "Disconnecting User".to_string();
|
|
time_to_die = true;
|
|
break;
|
|
}
|
|
CMD_NEW => {
|
|
message_to_send = "Starting new Chip-8 Instance".to_string();
|
|
chip8.reset(QuirkMode::Chip8);
|
|
}
|
|
CMD_LIST => {
|
|
message_to_send =
|
|
format!("Listing files in path: \n{}",
|
|
list_of_files_in_directory(
|
|
&mut Path::new("/home/tmerritt/Projects/trevors_chip8_toy/resources/roms".into())
|
|
)
|
|
);
|
|
}
|
|
CMD_LOAD => {
|
|
let file_to_use = p1.unwrap_or("default.ch8").trim();
|
|
// chip8 = Chip8ComputerManager::from(chip8).load_new_program_to_system_memory()
|
|
message_to_send = format!("Preparing to load {} from disk.",
|
|
file_to_use);
|
|
chip8.load_new_program_from_disk_to_system_memory(
|
|
Path::new(format!("{}/roms/{}", RESOURCES_ROOT, file_to_use).as_str())
|
|
);
|
|
}
|
|
CMD_HELP => {
|
|
message_to_send = MENU_TEXT.to_string();
|
|
}
|
|
CMD_STEPS => {
|
|
if chip8.core_should_run {
|
|
let num_steps = p1.unwrap_or("0").trim();
|
|
message_to_send = format!("Advancing {} steps.", num_steps);
|
|
for _ in 0..num_steps.parse().unwrap_or(0) {
|
|
chip8.tick();
|
|
}
|
|
} else {
|
|
message_to_send = "Not Ready to Step".to_string();
|
|
}
|
|
}
|
|
CMD_STEP => {
|
|
if chip8.core_should_run {
|
|
message_to_send = "Advancing 1 step.".to_string();
|
|
chip8.tick();
|
|
} else {
|
|
message_to_send = "Not Ready To Step".to_string();
|
|
}
|
|
}
|
|
CMD_WINDOW => {
|
|
message_to_send = format!("Memory window from {} to {}",
|
|
p1.unwrap_or("0x0000").trim(),
|
|
p2.unwrap_or("0xFFFF").trim());
|
|
}
|
|
_ => {}
|
|
}
|
|
|
|
write!(stream, "{}\n", message_to_send).expect(ERROR_CANT_NOTIFY);
|
|
|
|
stream.flush().unwrap();
|
|
}
|
|
}
|