From 654ff622f89e05900be55406e46ad8aaffdc0914 Mon Sep 17 00:00:00 2001 From: EliseZeroTwo Date: Tue, 2 Jan 2024 14:09:33 -0700 Subject: [PATCH] feat: switch from chrono to time --- Cargo.lock | 88 ++++++++++--------------- Cargo.toml | 1 + meowgb-core/Cargo.toml | 1 - meowgb-core/src/gameboy.rs | 10 +-- meowgb-core/src/gameboy/bootrom.rs | 66 +++++++++---------- meowgb-core/src/gameboy/cpu.rs | 2 +- meowgb-core/src/gameboy/cpu/prefixed.rs | 2 +- meowgb-core/src/gameboy/ppu.rs | 16 +++-- meowgb-core/src/gameboy/serial.rs | 10 +-- meowgb-tests/src/main.rs | 85 ++++++++++++++---------- meowgb/Cargo.toml | 2 +- meowgb/src/main.rs | 18 ++--- 12 files changed, 153 insertions(+), 148 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c141340..49aa86f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,12 +82,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -340,20 +334,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" -[[package]] -name = "chrono" -version = "0.4.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-targets 0.48.5", -] - [[package]] name = "clap" version = "4.4.12" @@ -577,6 +557,15 @@ dependencies = [ "syn", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "digest" version = "0.10.7" @@ -834,29 +823,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "iana-time-zone" -version = "0.1.59" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - [[package]] name = "icrate" version = "0.0.4" @@ -1063,7 +1029,6 @@ checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" name = "meowgb" version = "0.1.0" dependencies = [ - "chrono", "clap", "config", "env_logger", @@ -1072,6 +1037,7 @@ dependencies = [ "pixels", "serde", "thiserror", + "time", "winit", "winit_input_helper", ] @@ -1081,7 +1047,6 @@ name = "meowgb-core" version = "0.1.0" dependencies = [ "bmp", - "chrono", "log", "meowgb-opcode", "paste", @@ -1428,6 +1393,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "proc-macro-crate" version = "2.0.1" @@ -1751,6 +1722,24 @@ dependencies = [ "syn", ] +[[package]] +name = "time" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +dependencies = [ + "deranged", + "powerfmt", + "serde", + "time-core", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + [[package]] name = "toml" version = "0.5.11" @@ -2108,15 +2097,6 @@ dependencies = [ "windows-targets 0.42.2", ] -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.0", -] - [[package]] name = "windows-sys" version = "0.45.0" diff --git a/Cargo.toml b/Cargo.toml index 0f5d33a..013cf41 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,4 @@ [workspace] resolver = "2" members = ["meowgb", "meowgb-core", "meowgb-opcode", "meowgb-tests"] +default-members = ["meowgb"] \ No newline at end of file diff --git a/meowgb-core/Cargo.toml b/meowgb-core/Cargo.toml index b1475b5..ab87a15 100644 --- a/meowgb-core/Cargo.toml +++ b/meowgb-core/Cargo.toml @@ -10,6 +10,5 @@ log = "0.4.14" paste = "1.0.6" meowgb-opcode = { path = "../meowgb-opcode" } bmp = "0.5.0" -chrono = "0.4.19" thiserror = "1.0.30" sha1 = { version = "0.10.6", features = ["std"] } \ No newline at end of file diff --git a/meowgb-core/src/gameboy.rs b/meowgb-core/src/gameboy.rs index 7ce3fbb..0e5f5b5 100644 --- a/meowgb-core/src/gameboy.rs +++ b/meowgb-core/src/gameboy.rs @@ -9,6 +9,8 @@ pub mod serial; mod sound; mod timer; +use std::time::{Duration, Instant}; + use interrupts::Interrupts; use joypad::Joypad; use mapper::Mapper; @@ -206,7 +208,7 @@ impl Gameboy { log::info!("\n-- Registers --\nAF: {:04X}\nBC: {:04X}\nDE: {:04X}\nHL: {:04X}\nSP: {:04X}\nPC: {:04X}\nZero: {}\nSubtract: {}\nHalf-Carry: {}\nCarry: {}\n-- Interrupts --\nIME: {}\nIE VBlank: {}\nIE LCD Stat: {}\nIE Timer: {}\nIE Serial: {}\nIE Joypad: {}\nIF VBlank: {}\nIF LCD Stat: {}\nIF Timer: {}\nIF Serial: {}\nIF Joypad: {}\n", self.registers.get_af(), self.registers.get_bc(), self.registers.get_de(), self.registers.get_hl(), self.registers.get_sp(), self.registers.pc, self.registers.get_zero(), self.registers.get_subtract(), self.registers.get_half_carry(), self.registers.get_carry(), self.interrupts.ime, self.interrupts.read_ie_vblank(), self.interrupts.read_ie_lcd_stat(), self.interrupts.read_ie_timer(), self.interrupts.read_ie_serial(), self.interrupts.read_ie_joypad(), self.interrupts.read_if_vblank(), self.interrupts.read_if_lcd_stat(), self.interrupts.read_if_timer(), self.interrupts.read_if_serial(), self.interrupts.read_if_joypad()); } - pub fn tick_4(&mut self) -> (bool, Option) { + pub fn tick_4(&mut self) -> (bool, Option) { let mut request_redraw = false; let mut debug_time = None; for _ in 0..4 { @@ -221,7 +223,7 @@ impl Gameboy { (request_redraw, debug_time) } - pub fn tick(&mut self) -> (bool, Option) { + pub fn tick(&mut self) -> (bool, Option) { if self.tick_count == 0 { if self.breakpoints[self.registers.pc as usize] && !self.single_step { self.single_step = true; @@ -231,7 +233,7 @@ impl Gameboy { let mut diff = None; if self.trigger_bp || (self.single_step && self.registers.cycle == 0) { - let entered_step = chrono::Utc::now(); + let entered_step = Instant::now(); self.trigger_bp = false; self.single_step = true; let mut input = String::new(); @@ -389,7 +391,7 @@ impl Gameboy { Err(stdin_err) => panic!("Failed to lock stdin: {:?}", stdin_err), } - diff = Some((chrono::Utc::now() - entered_step).num_milliseconds()); + diff = Some(entered_step.elapsed()); if exit { return (false, diff); } diff --git a/meowgb-core/src/gameboy/bootrom.rs b/meowgb-core/src/gameboy/bootrom.rs index 9145888..0d7aa62 100644 --- a/meowgb-core/src/gameboy/bootrom.rs +++ b/meowgb-core/src/gameboy/bootrom.rs @@ -1,48 +1,48 @@ -use std::{path::Path, io::Read}; +use std::{io::Read, path::Path}; use sha1::{Digest, Sha1}; #[derive(Debug, thiserror::Error)] pub enum BootromParseError { - #[error("Bootrom file cannot be found")] - BootromNotFound, - #[error("IO error whilst reading bootrom: {0}")] - Io(#[from] std::io::Error), - #[error("Bootrom size is {0} bytes, expected 256 bytes")] - InvalidSize(u64), - #[error("Bootrom has an invalid SHA1 (expected \"4ed31ec6b0b175bb109c0eb5fd3d193da823339f\")")] - InvalidHash, - #[error("Failed to open bootrom file: {0}")] - FileOpen(std::io::Error), - #[error("Failed to read bootrom file: {0}")] - FileRead(std::io::Error), + #[error("Bootrom file cannot be found")] + BootromNotFound, + #[error("IO error whilst reading bootrom: {0}")] + Io(#[from] std::io::Error), + #[error("Bootrom size is {0} bytes, expected 256 bytes")] + InvalidSize(u64), + #[error("Bootrom has an invalid SHA1 (expected \"4ed31ec6b0b175bb109c0eb5fd3d193da823339f\")")] + InvalidHash, + #[error("Failed to open bootrom file: {0}")] + FileOpen(std::io::Error), + #[error("Failed to read bootrom file: {0}")] + FileRead(std::io::Error), } pub fn verify_parse_bootrom(path: &Path) -> Result<[u8; 0x100], BootromParseError> { - if !path.is_file() { - return Err(BootromParseError::BootromNotFound); - } + if !path.is_file() { + return Err(BootromParseError::BootromNotFound); + } - let mut bootrom_slice = [0u8; 0x100]; + let mut bootrom_slice = [0u8; 0x100]; - let mut file = std::fs::File::open(path).map_err(BootromParseError::FileOpen)?; - let metadata = file.metadata()?; + let mut file = std::fs::File::open(path).map_err(BootromParseError::FileOpen)?; + let metadata = file.metadata()?; - if metadata.len() != 256 { - return Err(BootromParseError::InvalidSize(metadata.len())); - } + if metadata.len() != 256 { + return Err(BootromParseError::InvalidSize(metadata.len())); + } - file.read_exact(&mut bootrom_slice).map_err(BootromParseError::FileRead)?; + file.read_exact(&mut bootrom_slice).map_err(BootromParseError::FileRead)?; - let mut hash_ctx = Sha1::new(); - hash_ctx.update(&bootrom_slice); - let digest = hash_ctx.finalize(); + let mut hash_ctx = Sha1::new(); + hash_ctx.update(&bootrom_slice); + let digest = hash_ctx.finalize(); - if digest.as_slice() - != b"\x4e\xd3\x1e\xc6\xb0\xb1\x75\xbb\x10\x9c\x0e\xb5\xfd\x3d\x19\x3d\xa8\x23\x33\x9f" - { - return Err(BootromParseError::InvalidHash); - } + if digest.as_slice() + != b"\x4e\xd3\x1e\xc6\xb0\xb1\x75\xbb\x10\x9c\x0e\xb5\xfd\x3d\x19\x3d\xa8\x23\x33\x9f" + { + return Err(BootromParseError::InvalidHash); + } - Ok(bootrom_slice) -} \ No newline at end of file + Ok(bootrom_slice) +} diff --git a/meowgb-core/src/gameboy/cpu.rs b/meowgb-core/src/gameboy/cpu.rs index 8e3ecf1..8b44ab7 100644 --- a/meowgb-core/src/gameboy/cpu.rs +++ b/meowgb-core/src/gameboy/cpu.rs @@ -4,7 +4,7 @@ mod load_store_move; mod misc; mod prefixed; -use super::{Gameboy, serial::SerialWriter}; +use super::{serial::SerialWriter, Gameboy}; macro_rules! define_register { ($lident:ident, $rident:ident) => { diff --git a/meowgb-core/src/gameboy/cpu/prefixed.rs b/meowgb-core/src/gameboy/cpu/prefixed.rs index bf54e9b..840738f 100644 --- a/meowgb-core/src/gameboy/cpu/prefixed.rs +++ b/meowgb-core/src/gameboy/cpu/prefixed.rs @@ -1,7 +1,7 @@ use meowgb_opcode::opcode; use super::CycleResult; -use crate::gameboy::{Gameboy, serial::SerialWriter}; +use crate::gameboy::{serial::SerialWriter, Gameboy}; pub fn prefixed_handler(state: &mut Gameboy) -> CycleResult { let opcode = match state.registers.current_prefixed_opcode { diff --git a/meowgb-core/src/gameboy/ppu.rs b/meowgb-core/src/gameboy/ppu.rs index 70eb3eb..c26c41e 100644 --- a/meowgb-core/src/gameboy/ppu.rs +++ b/meowgb-core/src/gameboy/ppu.rs @@ -564,8 +564,7 @@ impl Ppu { oam_entry.y.wrapping_sub(16).wrapping_add(sprite_height as u8); if oam_entry.x > 0 - && self.ly < real_oam_y - && self.ly >= oam_entry.y.wrapping_sub(16) + && self.ly < real_oam_y && self.ly >= oam_entry.y.wrapping_sub(16) && self.sprite_count < 10 { self.sprite_buffer[self.sprite_count] = Some(oam_entry); @@ -764,7 +763,8 @@ impl Ppu { if self.window_enabled() && wx_match && self.wy_match { window_drawn = true; - let window_x = (drawn_pixels as u8).wrapping_sub(self.wx.wrapping_sub(7)) as usize; + let window_x = + (drawn_pixels as u8).wrapping_sub(self.wx.wrapping_sub(7)) as usize; let window_y = self.ly.wrapping_sub(self.wy) as usize; let tilemap_idx = window_x / 8 + ((window_y / 8) * 32); let tilemap_value = self.read_window_tile_map()[tilemap_idx]; @@ -910,9 +910,10 @@ impl Ppu { } } - let now = chrono::Utc::now(); + let now = + std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs(); std::fs::create_dir_all("./bmp").unwrap(); - let file_name = format!("./bmp/fb-{}.bmp", now.timestamp()); + let file_name = format!("./bmp/fb-{}.bmp", now); image.save(file_name.as_str()).unwrap(); file_name } @@ -945,9 +946,10 @@ impl Ppu { } } - let now = chrono::Utc::now(); + let now = + std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs(); std::fs::create_dir_all("./bmp").unwrap(); - let file_name = format!("./bmp/bg-data-{}.bmp", now.timestamp()); + let file_name = format!("./bmp/bg-data-{}.bmp", now); image.save(file_name.as_str()).unwrap(); } diff --git a/meowgb-core/src/gameboy/serial.rs b/meowgb-core/src/gameboy/serial.rs index 56dd5e7..a1acf03 100644 --- a/meowgb-core/src/gameboy/serial.rs +++ b/meowgb-core/src/gameboy/serial.rs @@ -5,10 +5,12 @@ pub trait SerialWriter { } impl SerialWriter for T { - fn write_byte(&mut self, byte: u8) { - self.write_all(&[byte]).expect(format!("writing serial to {} failed", std::any::type_name::()).as_str()); - self.flush().expect(format!("flushing serial to {} failed", std::any::type_name::()).as_str()); - } + fn write_byte(&mut self, byte: u8) { + self.write_all(&[byte]) + .expect(format!("writing serial to {} failed", std::any::type_name::()).as_str()); + self.flush() + .expect(format!("flushing serial to {} failed", std::any::type_name::()).as_str()); + } } pub struct Serial { diff --git a/meowgb-tests/src/main.rs b/meowgb-tests/src/main.rs index 54c1f34..4a3cb30 100644 --- a/meowgb-tests/src/main.rs +++ b/meowgb-tests/src/main.rs @@ -1,7 +1,11 @@ -use std::{path::{PathBuf, Path}, sync::{RwLock, Arc}, time::{Duration, Instant}}; +use std::{ + path::{Path, PathBuf}, + sync::{Arc, RwLock}, + time::{Duration, Instant}, +}; use clap::{Parser, Subcommand}; -use meowgb_core::gameboy::{Gameboy, serial::SerialWriter}; +use meowgb_core::gameboy::{serial::SerialWriter, Gameboy}; #[derive(Debug, Parser)] /// DMG Emulator @@ -9,27 +13,27 @@ pub struct CliArgs { /// game path pub rom: PathBuf, #[clap(subcommand)] - pub operation: Operation + pub operation: Operation, } #[derive(Debug, Subcommand)] pub enum Operation { Test { /// maximum M-cycles - #[clap(short='m', long)] + #[clap(short = 'm', long)] maximum_m_cycles: u64, /// path to expected serial output - #[clap(short='s', long)] + #[clap(short = 's', long)] expected_serial: PathBuf, }, GenerateOutput { /// M-cycles to run for - #[clap(short='m', long)] + #[clap(short = 'm', long)] m_cycles: u64, /// path to expected serial output - #[clap(short='s', long)] + #[clap(short = 's', long)] expected_serial: PathBuf, - } + }, } #[derive(Debug, thiserror::Error)] @@ -66,12 +70,16 @@ impl SyncWriter { } impl SerialWriter for SyncWriter { - fn write_byte(&mut self, byte: u8) { - self.0.write().unwrap().write_byte(byte); - } + fn write_byte(&mut self, byte: u8) { + self.0.write().unwrap().write_byte(byte); + } } -fn generate_output(rom: &Path, m_cycles: u64, expected_serial: &Path) -> Result { +fn generate_output( + rom: &Path, + m_cycles: u64, + expected_serial: &Path, +) -> Result { let rom = { if !rom.is_file() { return Err(DmgTestError::RomNotFound); @@ -93,13 +101,17 @@ fn generate_output(rom: &Path, m_cycles: u64, expected_serial: &Path) -> Result< drop(gameboy); let serial_content = sync_writer.into_inner(); - std::fs::write(expected_serial, &serial_content).map_err(DmgTestError::SerialOutputFileWrite)?; - + std::fs::write(expected_serial, &serial_content) + .map_err(DmgTestError::SerialOutputFileWrite)?; Ok(instant.elapsed()) } -fn run_test(rom: &Path, maximum_m_cycles: u64, expected_serial: &Path) -> Result<(u64, Duration), DmgTestError> { +fn run_test( + rom: &Path, + maximum_m_cycles: u64, + expected_serial: &Path, +) -> Result<(u64, Duration), DmgTestError> { let rom = { if !rom.is_file() { return Err(DmgTestError::RomNotFound); @@ -137,7 +149,10 @@ fn run_test(rom: &Path, maximum_m_cycles: u64, expected_serial: &Path) -> Result match sync_writer.compare(&expected_serial) { true => Ok((cycle_counter, instant.elapsed())), - false => Err(DmgTestError::SerialDifferent(expected_serial.into_iter().map(char::from).collect(), sync_writer.into_inner().into_iter().map(char::from).collect())), + false => Err(DmgTestError::SerialDifferent( + expected_serial.into_iter().map(char::from).collect(), + sync_writer.into_inner().into_iter().map(char::from).collect(), + )), } } @@ -145,25 +160,27 @@ fn main() { let args = CliArgs::parse(); match args.operation { - Operation::Test { maximum_m_cycles, expected_serial } => match run_test(args.rom.as_path(), maximum_m_cycles, expected_serial.as_path()) { - Ok((m_cycles, duration)) => { - println!("Success! Ran {} M-Cycles in {}ms", m_cycles, duration.as_millis()); - }, - Err(why) => { - eprintln!("{}", why); - std::process::exit(1); + Operation::Test { maximum_m_cycles, expected_serial } => { + match run_test(args.rom.as_path(), maximum_m_cycles, expected_serial.as_path()) { + Ok((m_cycles, duration)) => { + println!("Success! Ran {} M-Cycles in {}ms", m_cycles, duration.as_millis()); + } + Err(why) => { + eprintln!("{}", why); + std::process::exit(1); + } } - }, - Operation::GenerateOutput { m_cycles, expected_serial } => match generate_output(args.rom.as_path(), m_cycles, expected_serial.as_path()) { - Ok(duration) => { - println!("Successfully written serial output to {} in {} M-Cycles ({}ms), please verify it is correct", expected_serial.display(), m_cycles, duration.as_millis()); - }, - Err(why) => { - eprintln!("{}", why); - std::process::exit(1); + } + Operation::GenerateOutput { m_cycles, expected_serial } => { + match generate_output(args.rom.as_path(), m_cycles, expected_serial.as_path()) { + Ok(duration) => { + println!("Successfully written serial output to {} in {} M-Cycles ({}ms), please verify it is correct", expected_serial.display(), m_cycles, duration.as_millis()); + } + Err(why) => { + eprintln!("{}", why); + std::process::exit(1); + } } - }, + } } - - } diff --git a/meowgb/Cargo.toml b/meowgb/Cargo.toml index 972c030..3fb6f6c 100644 --- a/meowgb/Cargo.toml +++ b/meowgb/Cargo.toml @@ -15,5 +15,5 @@ serde = { version = "1.0.130", features = ["derive"] } thiserror = "1.0.30" winit = { version = "0.29.7", default-features = false, features = ["serde", "rwh_05"] } winit_input_helper = "0.15.1" -chrono = "0.4.31" log = "0.4.20" +time = "0.3.31" diff --git a/meowgb/src/main.rs b/meowgb/src/main.rs index 90b87da..083472b 100644 --- a/meowgb/src/main.rs +++ b/meowgb/src/main.rs @@ -7,9 +7,11 @@ use std::{ sync::mpsc::{channel, Receiver, Sender}, }; -use chrono::{Duration, Utc}; use clap::Parser; -use meowgb_core::gameboy::{Gameboy, bootrom::{BootromParseError, verify_parse_bootrom}}; +use meowgb_core::gameboy::{ + bootrom::{verify_parse_bootrom, BootromParseError}, + Gameboy, +}; use settings::DeemgeeConfig; use window::EmulatorWindowEvent; @@ -95,7 +97,7 @@ pub fn run_gameboy( gameboy.load_cartridge(rom) } - let mut goal = chrono::Utc::now() + Duration::milliseconds(1000 / 60); + let mut goal = time::OffsetDateTime::now_utc() + time::Duration::milliseconds(1000 / 60); let mut frame_counter = 0; 'outer: loop { @@ -127,7 +129,7 @@ pub fn run_gameboy( } window::EmulatorWindowEvent::Exit => break 'outer, window::EmulatorWindowEvent::DumpMemory => { - let timestamp = Utc::now().timestamp(); + let timestamp = time::OffsetDateTime::now_utc().unix_timestamp(); let contents = gameboy.dump_memory(); std::fs::write(format!("./memdump-{}.bin", timestamp), contents) .expect("Failed to write memory dump"); @@ -138,19 +140,19 @@ pub fn run_gameboy( let (redraw_needed, time_spent_debugging) = gameboy.tick_4(); if let Some(diff) = time_spent_debugging { - goal = goal + Duration::milliseconds(diff); + goal = goal + diff; } if redraw_needed { - let now = chrono::Utc::now(); + let now = time::OffsetDateTime::now_utc(); frame_counter += 1; tx.send(GameboyEvent::Framebuffer(gameboy.ppu.write_fb())).unwrap(); let delta = goal - now; - let delta_ms = delta.num_milliseconds(); + let delta_ms = delta.whole_milliseconds(); if delta_ms > 0 { std::thread::sleep(std::time::Duration::from_millis(delta_ms as u64)); } - goal = goal + Duration::milliseconds(1000 / 60); + goal = goal + time::Duration::milliseconds(1000 / 60); if frame_counter == 60 { log::debug!("Rendered 60 frames");