Exemple #1
0
        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;
        }