Update before heading home
Some checks failed
Cargo Build & Test / Rust project - latest (stable) (push) Failing after 26s
Some checks failed
Cargo Build & Test / Rust project - latest (stable) (push) Failing after 26s
This commit is contained in:
158
src/main.rs
158
src/main.rs
@@ -1,8 +1,8 @@
|
||||
use std::{collections::HashMap, fmt};
|
||||
use std::{collections::HashMap, fmt, time::Duration};
|
||||
|
||||
use iced::{
|
||||
Color, Element, Font,
|
||||
Length::Fill,
|
||||
Length::{Fill, Shrink},
|
||||
Point, Renderer, Size, Subscription, Task, Theme, mouse,
|
||||
widget::{
|
||||
Canvas, button,
|
||||
@@ -16,7 +16,9 @@ use nes_emu::{
|
||||
debugger::{DebuggerMessage, DebuggerState},
|
||||
header_menu::header_menu,
|
||||
hex_view::{HexEvent, HexView},
|
||||
resize_watcher::resize_watcher,
|
||||
};
|
||||
use tokio::runtime::Runtime;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
const ROM_FILE: &str = concat!(env!("ROM_DIR"), "/", "even_odd.nes");
|
||||
@@ -33,13 +35,16 @@ fn main() -> Result<(), iced::Error> {
|
||||
.subscription(Emulator::subscriptions)
|
||||
.theme(Theme::Dark)
|
||||
.title(Emulator::title)
|
||||
.executor::<Runtime>()
|
||||
.run()
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum MemoryTy {
|
||||
Cpu,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum WindowType {
|
||||
Main,
|
||||
Memory(MemoryTy, HexView),
|
||||
@@ -51,10 +56,11 @@ enum WindowType {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum HeaderButton {
|
||||
OpenMemory,
|
||||
OpenTileMap,
|
||||
OpenTileViewer,
|
||||
OpenDebugger,
|
||||
// OpenMemory,
|
||||
// OpenTileMap,
|
||||
// OpenTileViewer,
|
||||
// OpenDebugger,
|
||||
Open(WindowType),
|
||||
Reset,
|
||||
PowerCycle,
|
||||
}
|
||||
@@ -62,10 +68,12 @@ enum HeaderButton {
|
||||
impl fmt::Display for HeaderButton {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Self::OpenMemory => write!(f, "Open Memory Viewer"),
|
||||
Self::OpenTileMap => write!(f, "Open TileMap Viewer"),
|
||||
Self::OpenTileViewer => write!(f, "Open Tile Viewer"),
|
||||
Self::OpenDebugger => write!(f, "Open Debugger"),
|
||||
Self::Open(WindowType::Memory(MemoryTy::Cpu, _)) => write!(f, "Open Memory Viewer"),
|
||||
Self::Open(WindowType::TileMap) => write!(f, "Open TileMap Viewer"),
|
||||
Self::Open(WindowType::TileViewer) => write!(f, "Open Tile Viewer"),
|
||||
Self::Open(WindowType::Debugger) => write!(f, "Open Debugger"),
|
||||
Self::Open(WindowType::Palette) => write!(f, "Open Palette"),
|
||||
Self::Open(WindowType::Main) => write!(f, "Create new Main window"),
|
||||
Self::Reset => write!(f, "Reset"),
|
||||
Self::PowerCycle => write!(f, "Power Cycle"),
|
||||
}
|
||||
@@ -76,6 +84,7 @@ struct Emulator {
|
||||
nes: NES,
|
||||
windows: HashMap<Id, WindowType>,
|
||||
debugger: DebuggerState,
|
||||
main_win_size: Size,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -85,25 +94,29 @@ enum Message {
|
||||
DMA,
|
||||
CPU,
|
||||
DebugInt,
|
||||
WindowOpened(Id),
|
||||
WindowClosed(Id),
|
||||
Header(HeaderButton),
|
||||
Hex(Id, HexEvent),
|
||||
Debugger(DebuggerMessage),
|
||||
SetSize(window::Id, Size),
|
||||
}
|
||||
|
||||
impl Emulator {
|
||||
fn new() -> (Self, Task<Message>) {
|
||||
let mut nes = nes_emu::NES::load_nes_file(ROM_FILE).expect("Failed to load nes file");
|
||||
nes.reset();
|
||||
let (win, task) = iced::window::open(Settings::default());
|
||||
let (win, task) = iced::window::open(Settings {
|
||||
min_size: None,
|
||||
..Settings::default()
|
||||
});
|
||||
(
|
||||
Self {
|
||||
nes,
|
||||
windows: HashMap::from_iter([(win, WindowType::Main)]),
|
||||
debugger: DebuggerState::new(),
|
||||
main_win_size: Size::new(0., 0.),
|
||||
},
|
||||
task.map(Message::WindowOpened),
|
||||
task.discard(),
|
||||
)
|
||||
}
|
||||
fn title(&self, win: Id) -> String {
|
||||
@@ -121,7 +134,7 @@ impl Emulator {
|
||||
fn open(&mut self, ty: WindowType) -> Task<Message> {
|
||||
let (win, task) = iced::window::open(Settings::default());
|
||||
self.windows.insert(win, ty);
|
||||
return task.map(Message::WindowOpened);
|
||||
return task.discard();
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Message) -> Task<Message> {
|
||||
@@ -135,25 +148,13 @@ impl Emulator {
|
||||
Message::DMA => while !self.nes.run_one_clock_cycle().dma {},
|
||||
Message::CPU => while !self.nes.run_one_clock_cycle().cpu_exec {},
|
||||
Message::DebugInt => while !self.nes.run_one_clock_cycle().dbg_int {},
|
||||
Message::WindowOpened(_id) => {
|
||||
// Window
|
||||
}
|
||||
Message::WindowClosed(id) => {
|
||||
if let Some(WindowType::Main) = self.windows.remove(&id) {
|
||||
return iced::exit();
|
||||
}
|
||||
}
|
||||
Message::Header(HeaderButton::OpenMemory) => {
|
||||
return self.open(WindowType::Memory(MemoryTy::Cpu, HexView::new()));
|
||||
}
|
||||
Message::Header(HeaderButton::OpenTileMap) => {
|
||||
return self.open(WindowType::TileMap);
|
||||
}
|
||||
Message::Header(HeaderButton::OpenTileViewer) => {
|
||||
return self.open(WindowType::TileViewer);
|
||||
}
|
||||
Message::Header(HeaderButton::OpenDebugger) => {
|
||||
return self.open(WindowType::Debugger);
|
||||
Message::Header(HeaderButton::Open(w)) => {
|
||||
return self.open(w);
|
||||
}
|
||||
Message::Hex(id, val) => {
|
||||
if let Some(WindowType::Memory(_, view)) = self.windows.get_mut(&id) {
|
||||
@@ -169,13 +170,31 @@ impl Emulator {
|
||||
Message::Debugger(debugger_message) => {
|
||||
self.debugger.update(debugger_message, &mut self.nes)
|
||||
}
|
||||
Message::SetSize(id, size) => {
|
||||
if let Some(WindowType::Main) = self.windows.get(&id) {
|
||||
self.main_win_size = size;
|
||||
}
|
||||
println!("New size for {:?}, {:?}", id, size);
|
||||
// return iced::window::set_min_size(id, size.into())
|
||||
// .then(move |_: ()| iced::window::resize(id, size));
|
||||
return Task::future(async {
|
||||
tokio::time::sleep(Duration::from_millis(50)).await;
|
||||
})
|
||||
.then(move |_| {
|
||||
iced::window::resize(id, size)
|
||||
});
|
||||
}
|
||||
}
|
||||
// self.image.0.clone_from(self.nes.image());
|
||||
Task::none()
|
||||
}
|
||||
|
||||
fn subscriptions(&self) -> Subscription<Message> {
|
||||
window::close_events().map(Message::WindowClosed)
|
||||
Subscription::batch([
|
||||
window::close_events().map(Message::WindowClosed),
|
||||
// window::events().map(Message::Window),
|
||||
// window::resize_events().map(Message::WindowResized),
|
||||
])
|
||||
}
|
||||
|
||||
fn view(&self, win: Id) -> Element<'_, Message> {
|
||||
@@ -183,12 +202,16 @@ impl Emulator {
|
||||
Some(WindowType::Main) => {
|
||||
let content = column![
|
||||
self.dropdowns(),
|
||||
Element::from(Canvas::new(self).width(Fill).height(255. * 2.)),
|
||||
self.cpu_state(),
|
||||
self.controls(),
|
||||
Element::from(Canvas::new(self).width(256. * 2.).height(240. * 2.)),
|
||||
// self.cpu_state(),
|
||||
// self.controls(),
|
||||
]
|
||||
.height(Fill);
|
||||
container(content).width(Fill).height(Fill).into()
|
||||
.height(Shrink);
|
||||
resize_watcher(content)
|
||||
.on_resize(move |s| Message::SetSize(win, s))
|
||||
.width(Shrink)
|
||||
.height(Shrink)
|
||||
.into()
|
||||
}
|
||||
Some(WindowType::Memory(ty, view)) => {
|
||||
let hex = match ty {
|
||||
@@ -211,12 +234,10 @@ impl Emulator {
|
||||
.height(Fill)
|
||||
.into()
|
||||
}
|
||||
Some(WindowType::Palette) => {
|
||||
container(Canvas::new(DbgImage::Palette(self.nes.ppu())))
|
||||
.width(Fill)
|
||||
.height(Fill)
|
||||
.into()
|
||||
}
|
||||
Some(WindowType::Palette) => container(Canvas::new(DbgImage::Palette(self.nes.ppu())))
|
||||
.width(Fill)
|
||||
.height(Fill)
|
||||
.into(),
|
||||
Some(WindowType::Debugger) => {
|
||||
container(self.debugger.view(&self.nes).map(Message::Debugger))
|
||||
.width(Fill)
|
||||
@@ -228,26 +249,26 @@ impl Emulator {
|
||||
}
|
||||
}
|
||||
|
||||
fn cpu_state(&self) -> Element<'_, Message> {
|
||||
row![column![
|
||||
// text!("Registers").font(Font::MONOSPACE),
|
||||
text!("{:?}", self.nes).font(Font::MONOSPACE),
|
||||
],]
|
||||
.width(Fill)
|
||||
.into()
|
||||
}
|
||||
// fn cpu_state(&self) -> Element<'_, Message> {
|
||||
// row![column![
|
||||
// // text!("Registers").font(Font::MONOSPACE),
|
||||
// text!("{:?}", self.nes).font(Font::MONOSPACE),
|
||||
// ],]
|
||||
// .width(Fill)
|
||||
// .into()
|
||||
// }
|
||||
|
||||
fn controls(&self) -> Element<'_, Message> {
|
||||
row![
|
||||
button("Clock tick").on_press(Message::Tick(1)),
|
||||
button("CPU tick").on_press(Message::CPU),
|
||||
button("Next Frame").on_press(Message::Frame),
|
||||
button("Next DMA").on_press(Message::DMA),
|
||||
button("Next DBG").on_press(Message::DebugInt),
|
||||
]
|
||||
.width(Fill)
|
||||
.into()
|
||||
}
|
||||
// fn controls(&self) -> Element<'_, Message> {
|
||||
// row![
|
||||
// button("Clock tick").on_press(Message::Tick(1)),
|
||||
// button("CPU tick").on_press(Message::CPU),
|
||||
// button("Next Frame").on_press(Message::Frame),
|
||||
// button("Next DMA").on_press(Message::DMA),
|
||||
// button("Next DBG").on_press(Message::DebugInt),
|
||||
// ]
|
||||
// .width(Fill)
|
||||
// .into()
|
||||
// }
|
||||
|
||||
fn dropdowns(&self) -> Element<'_, Message> {
|
||||
row![
|
||||
@@ -259,10 +280,11 @@ impl Emulator {
|
||||
header_menu(
|
||||
"Debugging",
|
||||
[
|
||||
HeaderButton::OpenDebugger,
|
||||
HeaderButton::OpenMemory,
|
||||
HeaderButton::OpenTileMap,
|
||||
HeaderButton::OpenTileViewer,
|
||||
HeaderButton::Open(WindowType::Debugger),
|
||||
HeaderButton::Open(WindowType::Memory(MemoryTy::Cpu, HexView {})),
|
||||
HeaderButton::Open(WindowType::TileMap),
|
||||
HeaderButton::Open(WindowType::TileViewer),
|
||||
HeaderButton::Open(WindowType::Palette),
|
||||
],
|
||||
Message::Header
|
||||
)
|
||||
@@ -280,16 +302,16 @@ impl Program<Message> for Emulator {
|
||||
_state: &Self::State,
|
||||
renderer: &Renderer,
|
||||
_theme: &Theme,
|
||||
_bounds: iced::Rectangle,
|
||||
bounds: iced::Rectangle,
|
||||
_cursor: mouse::Cursor,
|
||||
) -> Vec<iced::widget::canvas::Geometry<Renderer>> {
|
||||
// const SIZE: f32 = 2.;
|
||||
let mut frame = Frame::new(
|
||||
renderer,
|
||||
iced::Size {
|
||||
width: 256. * 2.,
|
||||
height: 240. * 2.,
|
||||
},
|
||||
bounds.size(), // iced::Size {
|
||||
// width: 256. * 2.,
|
||||
// height: 240. * 2.,
|
||||
// },
|
||||
);
|
||||
frame.scale(2.);
|
||||
for y in 0..240 {
|
||||
|
||||
Reference in New Issue
Block a user