This commit is contained in:
Mateusz Faderewski 2023-03-03 17:01:14 +01:00
parent 6d3d807d39
commit ad4f4db137
4 changed files with 286 additions and 68 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,11 @@
use crate::sc64;
use chrono::Local;
use colored::Colorize;
use panic_message::panic_message;
use std::{
io::{ErrorKind, Read, Write},
net::{TcpListener, TcpStream},
panic,
sync::mpsc::{channel, Receiver, Sender},
thread::{sleep, spawn},
time::Duration,
@ -77,7 +80,7 @@ impl Handler {
let filename = &self.generate_filename("binaryout", "bin");
let mut file = std::fs::File::create(filename)?;
file.write_all(data)?;
println!("Wrote {} bytes to {}", data.len(), filename);
println!("Wrote {} bytes to [{}]", data.len(), filename);
Ok(())
}
@ -89,7 +92,7 @@ impl Handler {
fn handle_datatype_screenshot(&mut self, _data: &[u8]) -> Result<(), sc64::Error> {
if let Some(header) = self.header.take() {
// TODO: support screenshot datatype
println!("Screenshot datatype not supported yet {:?}", header);
println!("Screenshot datatype not supported yet {:02X?}", header);
} else {
println!("Got screenshot packet without header data");
}
@ -130,7 +133,7 @@ pub fn new(gdb_port: Option<u16>) -> Result<Handler, sc64::Error> {
listener.set_nonblocking(true).map_err(|_| {
sc64::Error::new("Couldn't set GDB TCP socket listener as non-blocking")
})?;
spawn(move || gdb_loop(listener, gdb_loop_tx, gdb_loop_rx));
spawn(move || gdb_thread(listener, gdb_loop_tx, gdb_loop_rx));
}
Ok(Handler {
@ -140,6 +143,15 @@ pub fn new(gdb_port: Option<u16>) -> Result<Handler, sc64::Error> {
})
}
fn gdb_thread(listener: TcpListener, gdb_tx: Sender<Vec<u8>>, gdb_rx: Receiver<Vec<u8>>) {
match panic::catch_unwind(|| gdb_loop(listener, gdb_tx, gdb_rx)) {
Ok(_) => {}
Err(payload) => {
eprintln!("{}", panic_message(&payload).red());
}
};
}
fn gdb_loop(listener: TcpListener, gdb_tx: Sender<Vec<u8>>, gdb_rx: Receiver<Vec<u8>>) {
for tcp_stream in listener.incoming() {
match tcp_stream {

View File

@ -217,7 +217,10 @@ impl From<TvType> for sc64::TvType {
fn main() {
let cli = Cli::parse();
panic::set_hook(Box::new(|_| {}));
#[cfg(not(debug_assertions))]
{
panic::set_hook(Box::new(|_| {}));
}
match panic::catch_unwind(|| handle_command(&cli.command, cli.sn)) {
Ok(_) => {}
@ -260,10 +263,11 @@ fn handle_upload_command(sn: Option<String>, args: &UploadArgs) -> Result<(), sc
let save: SaveType = if let Some(save_type) = args.save_type.clone() {
save_type
} else {
log_wait(format!("Calculating ROM hash"), || {
n64::guess_save_type(&mut rom_file)
})?
.into()
let (save_type, name) = n64::guess_save_type(&mut rom_file)?;
if let Some(name) = name {
println!("Detected ROM name: {name}");
};
save_type.into()
};
let save_type: sc64::SaveType = save.into();
@ -362,6 +366,7 @@ fn handle_debug_command(sn: Option<String>, args: &DebugArgs) -> Result<(), sc64
} else if let Some(gdb_packet) = debug_handler.receive_gdb_packet() {
sc64.send_debug_packet(gdb_packet)?;
} else {
// TODO: handle user input
thread::sleep(Duration::from_millis(1));
}
}

View File

@ -9,23 +9,29 @@ pub enum SaveType {
Flashram,
}
const HASH_CHUNK_LENGTH: usize = 64 * 1024;
const HASH_CHUNK_LENGTH: usize = 256 * 1024;
pub fn guess_save_type<T: Read + Seek>(reader: &mut T) -> Result<SaveType, Error> {
pub fn guess_save_type<T: Read + Seek>(
reader: &mut T,
) -> Result<(SaveType, Option<String>), Error> {
let mut ed64_header = vec![0u8; 4];
reader.seek(std::io::SeekFrom::Start(0x3C))?;
reader.read(&mut ed64_header)?;
if &ed64_header[0..2] == b"ED" {
return Ok(match ed64_header[3] >> 4 {
1 => SaveType::Eeprom4k,
2 => SaveType::Eeprom16k,
3 => SaveType::Sram,
4 => SaveType::SramBanked,
5 => SaveType::Flashram,
6 => SaveType::Sram,
_ => SaveType::None,
});
return Ok((
match ed64_header[3] >> 4 {
1 => SaveType::Eeprom4k,
2 => SaveType::Eeprom16k,
3 => SaveType::Sram,
4 => SaveType::SramBanked,
5 => SaveType::Flashram,
6 => SaveType::Sram,
_ => SaveType::None,
},
None,
));
}
let mut pi_config = vec![0u8; 4];
@ -48,7 +54,6 @@ pub fn guess_save_type<T: Read + Seek>(reader: &mut T) -> Result<SaveType, Error
let mut buffer = vec![0u8; HASH_CHUNK_LENGTH];
reader.rewind()?;
loop {
let chunk = reader.read(&mut buffer)?;
if chunk > 0 {
@ -66,15 +71,18 @@ pub fn guess_save_type<T: Read + Seek>(reader: &mut T) -> Result<SaveType, Error
.expect("Error during mupen64plus.ini parse operation");
if let Some(section) = database.section(Some(hash)) {
if let Some(save_type) = section.get("SaveType") {
return Ok(match save_type {
"Eeprom 4KB" => SaveType::Eeprom4k,
"Eeprom 16KB" => SaveType::Eeprom16k,
"SRAM" => SaveType::Sram,
"Flash RAM" => SaveType::Flashram,
_ => SaveType::None,
});
return Ok((
match save_type {
"Eeprom 4KB" => SaveType::Eeprom4k,
"Eeprom 16KB" => SaveType::Eeprom16k,
"SRAM" => SaveType::Sram,
"Flash RAM" => SaveType::Flashram,
_ => SaveType::None,
},
section.get("GoodName").map(|s| s.to_string()),
));
}
}
Ok(SaveType::None)
Ok((SaveType::None, None))
}