mirror of
				https://github.com/yuzu-emu/yuzu.git
				synced 2025-11-04 02:43:42 +00:00 
			
		
		
		
	citra-qt: Add pica framebuffer widget.
This commit is contained in:
		
							parent
							
								
									2793619dce
								
							
						
					
					
						commit
						55ce9aca71
					
				@ -10,6 +10,7 @@ set(SRCS
 | 
			
		||||
            debugger/graphics.cpp
 | 
			
		||||
            debugger/graphics_breakpoints.cpp
 | 
			
		||||
            debugger/graphics_cmdlists.cpp
 | 
			
		||||
            debugger/graphics_framebuffer.cpp
 | 
			
		||||
            debugger/ramview.cpp
 | 
			
		||||
            debugger/registers.cpp
 | 
			
		||||
            util/spinbox.cpp
 | 
			
		||||
@ -27,6 +28,7 @@ set(HEADERS
 | 
			
		||||
            debugger/graphics.hxx
 | 
			
		||||
            debugger/graphics_breakpoints.hxx
 | 
			
		||||
            debugger/graphics_cmdlists.hxx
 | 
			
		||||
            debugger/graphics_framebuffer.hxx
 | 
			
		||||
            debugger/ramview.hxx
 | 
			
		||||
            debugger/registers.hxx
 | 
			
		||||
            util/spinbox.hxx
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										282
									
								
								src/citra_qt/debugger/graphics_framebuffer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										282
									
								
								src/citra_qt/debugger/graphics_framebuffer.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,282 @@
 | 
			
		||||
// Copyright 2014 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#include <QBoxLayout>
 | 
			
		||||
#include <QComboBox>
 | 
			
		||||
#include <QDebug>
 | 
			
		||||
#include <QLabel>
 | 
			
		||||
#include <QMetaType>
 | 
			
		||||
#include <QPushButton>
 | 
			
		||||
#include <QSpinBox>
 | 
			
		||||
 | 
			
		||||
#include "video_core/pica.h"
 | 
			
		||||
 | 
			
		||||
#include "graphics_framebuffer.hxx"
 | 
			
		||||
 | 
			
		||||
#include "util/spinbox.hxx"
 | 
			
		||||
 | 
			
		||||
BreakPointObserverDock::BreakPointObserverDock(std::shared_ptr<Pica::DebugContext> debug_context,
 | 
			
		||||
                                               const QString& title, QWidget* parent)
 | 
			
		||||
    : QDockWidget(title, parent), BreakPointObserver(debug_context)
 | 
			
		||||
{
 | 
			
		||||
    qRegisterMetaType<Pica::DebugContext::Event>("Pica::DebugContext::Event");
 | 
			
		||||
 | 
			
		||||
    connect(this, SIGNAL(Resumed()), this, SLOT(OnResumed()));
 | 
			
		||||
 | 
			
		||||
    // NOTE: This signal is emitted from a non-GUI thread, but connect() takes
 | 
			
		||||
    //       care of delaying its handling to the GUI thread.
 | 
			
		||||
    connect(this, SIGNAL(BreakPointHit(Pica::DebugContext::Event,void*)),
 | 
			
		||||
            this, SLOT(OnBreakPointHit(Pica::DebugContext::Event,void*)),
 | 
			
		||||
            Qt::BlockingQueuedConnection);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BreakPointObserverDock::OnPicaBreakPointHit(Pica::DebugContext::Event event, void* data)
 | 
			
		||||
{
 | 
			
		||||
    emit BreakPointHit(event, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BreakPointObserverDock::OnPicaResume()
 | 
			
		||||
{
 | 
			
		||||
    emit Resumed();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GraphicsFramebufferWidget::GraphicsFramebufferWidget(std::shared_ptr<Pica::DebugContext> debug_context,
 | 
			
		||||
                                                     QWidget* parent)
 | 
			
		||||
    : BreakPointObserverDock(debug_context, tr("Pica Framebuffer"), parent),
 | 
			
		||||
      framebuffer_source(Source::PicaTarget)
 | 
			
		||||
{
 | 
			
		||||
    setObjectName("PicaFramebuffer");
 | 
			
		||||
 | 
			
		||||
    framebuffer_source_list = new QComboBox;
 | 
			
		||||
    framebuffer_source_list->addItem(tr("Active Render Target"));
 | 
			
		||||
    framebuffer_source_list->addItem(tr("Custom"));
 | 
			
		||||
    framebuffer_source_list->setCurrentIndex(static_cast<int>(framebuffer_source));
 | 
			
		||||
 | 
			
		||||
    framebuffer_address_control = new CSpinBox;
 | 
			
		||||
    framebuffer_address_control->SetBase(16);
 | 
			
		||||
    framebuffer_address_control->SetRange(0, 0xFFFFFFFF);
 | 
			
		||||
    framebuffer_address_control->SetPrefix("0x");
 | 
			
		||||
 | 
			
		||||
    framebuffer_width_control = new QSpinBox;
 | 
			
		||||
    framebuffer_width_control->setMinimum(1);
 | 
			
		||||
    framebuffer_width_control->setMaximum(std::numeric_limits<int>::max()); // TODO: Find actual maximum
 | 
			
		||||
 | 
			
		||||
    framebuffer_height_control = new QSpinBox;
 | 
			
		||||
    framebuffer_height_control->setMinimum(1);
 | 
			
		||||
    framebuffer_height_control->setMaximum(std::numeric_limits<int>::max()); // TODO: Find actual maximum
 | 
			
		||||
 | 
			
		||||
    framebuffer_format_control = new QComboBox;
 | 
			
		||||
    framebuffer_format_control->addItem(tr("RGBA8"));
 | 
			
		||||
    framebuffer_format_control->addItem(tr("RGB8"));
 | 
			
		||||
    framebuffer_format_control->addItem(tr("RGBA5551"));
 | 
			
		||||
    framebuffer_format_control->addItem(tr("RGB565"));
 | 
			
		||||
    framebuffer_format_control->addItem(tr("RGBA4"));
 | 
			
		||||
 | 
			
		||||
    // TODO: This QLabel should shrink the image to the available space rather than just expanding...
 | 
			
		||||
    framebuffer_picture_label = new QLabel;
 | 
			
		||||
 | 
			
		||||
    auto enlarge_button = new QPushButton(tr("Enlarge"));
 | 
			
		||||
 | 
			
		||||
    // Connections
 | 
			
		||||
    connect(this, SIGNAL(Update()), this, SLOT(OnUpdate()));
 | 
			
		||||
    connect(framebuffer_source_list, SIGNAL(currentIndexChanged(int)), this, SLOT(OnFramebufferSourceChanged(int)));
 | 
			
		||||
    connect(framebuffer_address_control, SIGNAL(ValueChanged(qint64)), this, SLOT(OnFramebufferAddressChanged(qint64)));
 | 
			
		||||
    connect(framebuffer_width_control, SIGNAL(valueChanged(int)), this, SLOT(OnFramebufferWidthChanged(int)));
 | 
			
		||||
    connect(framebuffer_height_control, SIGNAL(valueChanged(int)), this, SLOT(OnFramebufferHeightChanged(int)));
 | 
			
		||||
    connect(framebuffer_format_control, SIGNAL(currentIndexChanged(int)), this, SLOT(OnFramebufferFormatChanged(int)));
 | 
			
		||||
 | 
			
		||||
    auto main_widget = new QWidget;
 | 
			
		||||
    auto main_layout = new QVBoxLayout;
 | 
			
		||||
    {
 | 
			
		||||
        auto sub_layout = new QHBoxLayout;
 | 
			
		||||
        sub_layout->addWidget(new QLabel(tr("Source:")));
 | 
			
		||||
        sub_layout->addWidget(framebuffer_source_list);
 | 
			
		||||
        main_layout->addLayout(sub_layout);
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        auto sub_layout = new QHBoxLayout;
 | 
			
		||||
        sub_layout->addWidget(new QLabel(tr("Virtual Address:")));
 | 
			
		||||
        sub_layout->addWidget(framebuffer_address_control);
 | 
			
		||||
        main_layout->addLayout(sub_layout);
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        auto sub_layout = new QHBoxLayout;
 | 
			
		||||
        sub_layout->addWidget(new QLabel(tr("Width:")));
 | 
			
		||||
        sub_layout->addWidget(framebuffer_width_control);
 | 
			
		||||
        main_layout->addLayout(sub_layout);
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        auto sub_layout = new QHBoxLayout;
 | 
			
		||||
        sub_layout->addWidget(new QLabel(tr("Height:")));
 | 
			
		||||
        sub_layout->addWidget(framebuffer_height_control);
 | 
			
		||||
        main_layout->addLayout(sub_layout);
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        auto sub_layout = new QHBoxLayout;
 | 
			
		||||
        sub_layout->addWidget(new QLabel(tr("Format:")));
 | 
			
		||||
        sub_layout->addWidget(framebuffer_format_control);
 | 
			
		||||
        main_layout->addLayout(sub_layout);
 | 
			
		||||
    }
 | 
			
		||||
    main_layout->addWidget(framebuffer_picture_label);
 | 
			
		||||
    main_layout->addWidget(enlarge_button);
 | 
			
		||||
    main_widget->setLayout(main_layout);
 | 
			
		||||
    setWidget(main_widget);
 | 
			
		||||
 | 
			
		||||
    // Load current data - TODO: Make sure this works when emulation is not running
 | 
			
		||||
    emit Update();
 | 
			
		||||
    widget()->setEnabled(false); // TODO: Only enable if currently at breakpoint
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GraphicsFramebufferWidget::OnBreakPointHit(Pica::DebugContext::Event event, void* data)
 | 
			
		||||
{
 | 
			
		||||
    emit Update();
 | 
			
		||||
    widget()->setEnabled(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GraphicsFramebufferWidget::OnResumed()
 | 
			
		||||
{
 | 
			
		||||
    widget()->setEnabled(false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GraphicsFramebufferWidget::OnFramebufferSourceChanged(int new_value)
 | 
			
		||||
{
 | 
			
		||||
    framebuffer_source = static_cast<Source>(new_value);
 | 
			
		||||
    emit Update();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GraphicsFramebufferWidget::OnFramebufferAddressChanged(qint64 new_value)
 | 
			
		||||
{
 | 
			
		||||
    if (framebuffer_address != new_value) {
 | 
			
		||||
        framebuffer_address = static_cast<unsigned>(new_value);
 | 
			
		||||
 | 
			
		||||
        framebuffer_source_list->setCurrentIndex(static_cast<int>(Source::Custom));
 | 
			
		||||
        emit Update();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GraphicsFramebufferWidget::OnFramebufferWidthChanged(int new_value)
 | 
			
		||||
{
 | 
			
		||||
    if (framebuffer_width != new_value) {
 | 
			
		||||
        framebuffer_width = new_value;
 | 
			
		||||
 | 
			
		||||
        framebuffer_source_list->setCurrentIndex(static_cast<int>(Source::Custom));
 | 
			
		||||
        emit Update();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GraphicsFramebufferWidget::OnFramebufferHeightChanged(int new_value)
 | 
			
		||||
{
 | 
			
		||||
    if (framebuffer_height != new_value) {
 | 
			
		||||
        framebuffer_height = new_value;
 | 
			
		||||
 | 
			
		||||
        framebuffer_source_list->setCurrentIndex(static_cast<int>(Source::Custom));
 | 
			
		||||
        emit Update();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GraphicsFramebufferWidget::OnFramebufferFormatChanged(int new_value)
 | 
			
		||||
{
 | 
			
		||||
    if (framebuffer_format != static_cast<Format>(new_value)) {
 | 
			
		||||
        framebuffer_format = static_cast<Format>(new_value);
 | 
			
		||||
 | 
			
		||||
        framebuffer_source_list->setCurrentIndex(static_cast<int>(Source::Custom));
 | 
			
		||||
        emit Update();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GraphicsFramebufferWidget::OnUpdate()
 | 
			
		||||
{
 | 
			
		||||
    QPixmap pixmap;
 | 
			
		||||
 | 
			
		||||
    switch (framebuffer_source) {
 | 
			
		||||
    case Source::PicaTarget:
 | 
			
		||||
    {
 | 
			
		||||
        // TODO: Store a reference to the registers in the debug context instead of accessing them directly...
 | 
			
		||||
 | 
			
		||||
        auto framebuffer = Pica::registers.framebuffer;
 | 
			
		||||
        using Framebuffer = decltype(framebuffer);
 | 
			
		||||
 | 
			
		||||
        framebuffer_address = framebuffer.GetColorBufferAddress();
 | 
			
		||||
        framebuffer_width = framebuffer.GetWidth();
 | 
			
		||||
        framebuffer_height = framebuffer.GetHeight();
 | 
			
		||||
        framebuffer_format = static_cast<Format>(framebuffer.color_format);
 | 
			
		||||
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case Source::Custom:
 | 
			
		||||
    {
 | 
			
		||||
        // Keep user-specified values
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        qDebug() << "Unknown framebuffer source " << static_cast<int>(framebuffer_source);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (framebuffer_format) {
 | 
			
		||||
    case Format::RGBA8:
 | 
			
		||||
    {
 | 
			
		||||
        // TODO: Implement a good way to visualize the alpha component
 | 
			
		||||
 | 
			
		||||
        QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32);
 | 
			
		||||
        u32* color_buffer = (u32*)Memory::GetPointer(framebuffer_address);
 | 
			
		||||
        for (int y = 0; y < framebuffer_height; ++y) {
 | 
			
		||||
            for (int x = 0; x < framebuffer_width; ++x) {
 | 
			
		||||
                u32 value = *(color_buffer + x + y * framebuffer_width);
 | 
			
		||||
 | 
			
		||||
                decoded_image.setPixel(x, y, qRgba((value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, 255/*value >> 24*/));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        pixmap = QPixmap::fromImage(decoded_image);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case Format::RGB8:
 | 
			
		||||
    {
 | 
			
		||||
        QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32);
 | 
			
		||||
        u8* color_buffer = Memory::GetPointer(framebuffer_address);
 | 
			
		||||
        for (int y = 0; y < framebuffer_height; ++y) {
 | 
			
		||||
            for (int x = 0; x < framebuffer_width; ++x) {
 | 
			
		||||
                u8* pixel_pointer = color_buffer + x * 3 + y * 3 * framebuffer_width;
 | 
			
		||||
 | 
			
		||||
                decoded_image.setPixel(x, y, qRgba(pixel_pointer[0], pixel_pointer[1], pixel_pointer[2], 255/*value >> 24*/));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        pixmap = QPixmap::fromImage(decoded_image);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case Format::RGBA5551:
 | 
			
		||||
    {
 | 
			
		||||
        QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32);
 | 
			
		||||
        u32* color_buffer = (u32*)Memory::GetPointer(framebuffer_address);
 | 
			
		||||
        for (int y = 0; y < framebuffer_height; ++y) {
 | 
			
		||||
            for (int x = 0; x < framebuffer_width; ++x) {
 | 
			
		||||
                u16 value = *(u16*)(((u8*)color_buffer) + x * 2 + y * framebuffer_width * 2);
 | 
			
		||||
                u8 r = (value >> 11) & 0x1F;
 | 
			
		||||
                u8 g = (value >> 6) & 0x1F;
 | 
			
		||||
                u8 b = (value >> 1) & 0x1F;
 | 
			
		||||
                u8 a = value & 1;
 | 
			
		||||
 | 
			
		||||
                decoded_image.setPixel(x, y, qRgba(r, g, b, 255/*a*/));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        pixmap = QPixmap::fromImage(decoded_image);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
        qDebug() << "Unknown fb color format " << static_cast<int>(framebuffer_format);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    framebuffer_address_control->SetValue(framebuffer_address);
 | 
			
		||||
    framebuffer_width_control->setValue(framebuffer_width);
 | 
			
		||||
    framebuffer_height_control->setValue(framebuffer_height);
 | 
			
		||||
    framebuffer_format_control->setCurrentIndex(static_cast<int>(framebuffer_format));
 | 
			
		||||
    framebuffer_picture_label->setPixmap(pixmap);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										92
									
								
								src/citra_qt/debugger/graphics_framebuffer.hxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								src/citra_qt/debugger/graphics_framebuffer.hxx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,92 @@
 | 
			
		||||
// Copyright 2014 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2
 | 
			
		||||
// Refer to the license.txt file included.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <QDockWidget>
 | 
			
		||||
 | 
			
		||||
#include "video_core/debug_utils/debug_utils.h"
 | 
			
		||||
 | 
			
		||||
class QComboBox;
 | 
			
		||||
class QLabel;
 | 
			
		||||
class QSpinBox;
 | 
			
		||||
 | 
			
		||||
class CSpinBox;
 | 
			
		||||
 | 
			
		||||
// Utility class which forwards calls to OnPicaBreakPointHit and OnPicaResume to public slots.
 | 
			
		||||
// This is because the Pica breakpoint callbacks will called on a non-GUI thread, while
 | 
			
		||||
// the widget usually wants to perform reactions in the GUI thread.
 | 
			
		||||
class BreakPointObserverDock : public QDockWidget, Pica::DebugContext::BreakPointObserver {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    BreakPointObserverDock(std::shared_ptr<Pica::DebugContext> debug_context, const QString& title,
 | 
			
		||||
                           QWidget* parent = nullptr);
 | 
			
		||||
 | 
			
		||||
    void OnPicaBreakPointHit(Pica::DebugContext::Event event, void* data) override;
 | 
			
		||||
    void OnPicaResume() override;
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    virtual void OnBreakPointHit(Pica::DebugContext::Event event, void* data) = 0;
 | 
			
		||||
    virtual void OnResumed() = 0;
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void Resumed();
 | 
			
		||||
    void BreakPointHit(Pica::DebugContext::Event event, void* data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class GraphicsFramebufferWidget : public BreakPointObserverDock {
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
    using Event = Pica::DebugContext::Event;
 | 
			
		||||
 | 
			
		||||
    enum class Source {
 | 
			
		||||
        PicaTarget = 0,
 | 
			
		||||
        Custom = 1,
 | 
			
		||||
 | 
			
		||||
        // TODO: Add GPU framebuffer sources!
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum class Format {
 | 
			
		||||
        RGBA8    = 0,
 | 
			
		||||
        RGB8     = 1,
 | 
			
		||||
        RGBA5551 = 2,
 | 
			
		||||
        RGB565   = 3,
 | 
			
		||||
        RGBA4    = 4,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    GraphicsFramebufferWidget(std::shared_ptr<Pica::DebugContext> debug_context, QWidget* parent = nullptr);
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
    void OnFramebufferSourceChanged(int new_value);
 | 
			
		||||
    void OnFramebufferAddressChanged(qint64 new_value);
 | 
			
		||||
    void OnFramebufferWidthChanged(int new_value);
 | 
			
		||||
    void OnFramebufferHeightChanged(int new_value);
 | 
			
		||||
    void OnFramebufferFormatChanged(int new_value);
 | 
			
		||||
    void OnUpdate();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
    void OnBreakPointHit(Pica::DebugContext::Event event, void* data) override;
 | 
			
		||||
    void OnResumed() override;
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void Update();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
    QComboBox* framebuffer_source_list;
 | 
			
		||||
    CSpinBox* framebuffer_address_control;
 | 
			
		||||
    QSpinBox* framebuffer_width_control;
 | 
			
		||||
    QSpinBox* framebuffer_height_control;
 | 
			
		||||
    QComboBox* framebuffer_format_control;
 | 
			
		||||
 | 
			
		||||
    QLabel* framebuffer_picture_label;
 | 
			
		||||
 | 
			
		||||
    Source framebuffer_source;
 | 
			
		||||
    unsigned framebuffer_address;
 | 
			
		||||
    unsigned framebuffer_width;
 | 
			
		||||
    unsigned framebuffer_height;
 | 
			
		||||
    Format framebuffer_format;
 | 
			
		||||
};
 | 
			
		||||
@ -22,6 +22,7 @@
 | 
			
		||||
#include "debugger/graphics.hxx"
 | 
			
		||||
#include "debugger/graphics_breakpoints.hxx"
 | 
			
		||||
#include "debugger/graphics_cmdlists.hxx"
 | 
			
		||||
#include "debugger/graphics_framebuffer.hxx"
 | 
			
		||||
 | 
			
		||||
#include "core/settings.h"
 | 
			
		||||
#include "core/system.h"
 | 
			
		||||
@ -74,6 +75,10 @@ GMainWindow::GMainWindow()
 | 
			
		||||
    addDockWidget(Qt::RightDockWidgetArea, graphicsBreakpointsWidget);
 | 
			
		||||
    graphicsBreakpointsWidget->hide();
 | 
			
		||||
 | 
			
		||||
    auto graphicsFramebufferWidget = new GraphicsFramebufferWidget(Pica::g_debug_context, this);
 | 
			
		||||
    addDockWidget(Qt::RightDockWidgetArea, graphicsFramebufferWidget);
 | 
			
		||||
    graphicsFramebufferWidget->hide();
 | 
			
		||||
 | 
			
		||||
    QMenu* debug_menu = ui.menu_View->addMenu(tr("Debugging"));
 | 
			
		||||
    debug_menu->addAction(disasmWidget->toggleViewAction());
 | 
			
		||||
    debug_menu->addAction(registersWidget->toggleViewAction());
 | 
			
		||||
@ -81,6 +86,7 @@ GMainWindow::GMainWindow()
 | 
			
		||||
    debug_menu->addAction(graphicsWidget->toggleViewAction());
 | 
			
		||||
    debug_menu->addAction(graphicsCommandsWidget->toggleViewAction());
 | 
			
		||||
    debug_menu->addAction(graphicsBreakpointsWidget->toggleViewAction());
 | 
			
		||||
    debug_menu->addAction(graphicsFramebufferWidget->toggleViewAction());
 | 
			
		||||
 | 
			
		||||
    // Set default UI state
 | 
			
		||||
    // geometry: 55% of the window contents are in the upper screen half, 45% in the lower half
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user