public DebugWindow(DebugWindowViewModel viewModel) { Title = "Debugger"; DataContext = viewModel; var layout = new DynamicLayout { DefaultSpacing = new Size(20, 10), Padding = new Padding(20, 10) }; layout.BeginVertical(); layout.BeginHorizontal(); var disassemblerTextBox = new AutoLoadingRichTextArea { Font = new Font("monospace", 10), Width = 300, ReadOnly = true }; disassemblerTextBox.TextBinding.BindDataContext <DebugWindowViewModel>(m => m.DisassembedProgramText); disassemblerTextBox.BindDataContext(t => t.BackgroundColor, Binding.Property <bool>(nameof(DebugWindowViewModel.EmulationIsRunning)) .Convert(m => m ? Colors.DarkGray : Colors.White)); layout.Add(disassemblerTextBox); layout.BeginVertical(); layout.BeginHorizontal(); layout.BeginVertical(); var runHaltButton = new Button(); runHaltButton.TextBinding.BindDataContext( Binding.Property <bool>(nameof(DebugWindowViewModel.EmulationIsRunning)) .Convert(b => b ? "Halt" : "Run")); runHaltButton.Command = new Command((s, a) => { if (viewModel.EmulationIsRunning) { viewModel.HaltEmulation(); } else { viewModel.StartEmulation(); } }); layout.Add(runHaltButton); var stepButton = new Button { Text = "Step", Command = new Command((s, a) => viewModel.Step()) }; stepButton.Bind(b => b.Enabled, viewModel, Binding.Property((DebugWindowViewModel m) => m.EmulationIsRunning).Convert(v => !v)); layout.Add(stepButton); layout.Add(null); _registerFieldControl = new RegisterFieldControl(viewModel.State.Registers); layout.Add(_registerFieldControl); viewModel.PropertyChanged += (s, e) => { if (e.PropertyName == "State") { _registerFieldControl.UpdateBindings(BindingUpdateMode.Destination); } }; layout.EndVertical(); layout.EndBeginHorizontal(); layout.EndBeginVertical(); var tilesetView = new ImageView(); tilesetView.BindDataContext(v => v.Image, (DebugWindowViewModel vm) => vm.Tileset, DualBindingMode.OneWay); layout.AddColumn(tilesetView, new Label { Text = "Tileset" }); layout.EndBeginVertical(); var tilemap0View = new ImageView(); tilemap0View.BindDataContext(v => v.Image, (DebugWindowViewModel vm) => vm.Tilemap0, DualBindingMode.OneWay); layout.AddColumn(tilemap0View, new Label { Text = "Tilemap #0" }); layout.EndBeginVertical(); var tilemap1View = new ImageView(); tilemap1View.BindDataContext(v => v.Image, (DebugWindowViewModel vm) => vm.Tilemap1, DualBindingMode.OneWay); layout.AddColumn(tilemap1View, new Label { Text = "Tilemap #1" }); layout.EndVertical(); layout.EndHorizontal(); layout.EndVertical(); Content = layout; viewModel.Refresh(); }
public EmulationWindow(LaunchDialogResult launchOptions) { var emulator = new EmulationEngine(launchOptions.BootromFile, launchOptions.RomFile) { Running = true }; Task.Run(() => emulator.Run()); // Debug window var debugViewModel = new DebugWindowViewModel(emulator.State, emulator); var debugWindow = new DebugWindow(debugViewModel); debugWindow.Show(); // Very basic key input handling KeyDown += (s, e) => { switch (e.Key) { case Keys.Up: emulator.Buttons.Up = true; break; case Keys.Down: emulator.Buttons.Down = true; break; case Keys.Left: emulator.Buttons.Left = true; break; case Keys.Right: emulator.Buttons.Right = true; break; case Keys.X: emulator.Buttons.A = true; break; case Keys.C: emulator.Buttons.B = true; break; case Keys.V: emulator.Buttons.Start = true; break; case Keys.B: emulator.Buttons.Select = true; break; } }; KeyUp += (s, e) => { switch (e.Key) { case Keys.Up: emulator.Buttons.Up = false; break; case Keys.Down: emulator.Buttons.Down = false; break; case Keys.Left: emulator.Buttons.Left = false; break; case Keys.Right: emulator.Buttons.Right = false; break; case Keys.X: emulator.Buttons.A = false; break; case Keys.C: emulator.Buttons.B = false; break; case Keys.V: emulator.Buttons.Start = false; break; case Keys.B: emulator.Buttons.Select = false; break; } }; var frameCount = 0; Task.Run(async() => { long last = emulator.ElapsedCycles; while (true) { await Task.Delay(1000); var elapsed = emulator.ElapsedCycles - last; if (emulator.Running) { var newTitle = $"Debugger ({(float)elapsed / 1000000} MHz, {frameCount} fps)"; Application.Instance.AsyncInvoke(() => { debugWindow.Title = newTitle; }); } last = emulator.ElapsedCycles; frameCount = 0; } }); var imageView = new ImageView(); emulator.FrameSource.NewFrame += (sender, args) => { frameCount++; Application.Instance.AsyncInvoke(() => { imageView.Image = args.Frame.ToEtoBitmap(); debugViewModel.Refresh(); }); }; Content = new Panel { Content = imageView, Size = new Size(160, 144) }; Resizable = false; }