Skip to content

Commit

Permalink
Move Dolphin hook status to status bar.
Browse files Browse the repository at this point in the history
It reduces the clutter in the GUI by saving several lines of vertical
space in the main window.

Bonus: A state icon is now included for each of the four possible
states, as well as the game ID of the emulated game when present.

![DME - Unhooked](https://github.com/aldelaro5/dolphin-memory-engine/assets/1853278/506a223f-c90d-4d44-9a9b-57115ed56bd7)
![DME - Dolphin not detected](https://github.com/aldelaro5/dolphin-memory-engine/assets/1853278/4b9fd1ea-ea65-4d6b-9c56-3d37ec4702a1)
![DME - No game running](https://github.com/aldelaro5/dolphin-memory-engine/assets/1853278/91c8103e-257c-40c7-897a-157fe20da4df)
![DME - Hooked](https://github.com/aldelaro5/dolphin-memory-engine/assets/1853278/2e39c4e9-aee0-48b1-9f13-e25a294d8950)
  • Loading branch information
cristian64 committed May 27, 2024
1 parent bafe862 commit 589429c
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 41 deletions.
155 changes: 117 additions & 38 deletions Source/GUI/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <QIcon>
#include <QMenuBar>
#include <QShortcut>
#include <QStatusBar>
#include <QString>
#include <QTimer>
#include <QVBoxLayout>
Expand Down Expand Up @@ -165,12 +166,6 @@ void MainWindow::initialiseWidgets()
connect(m_watcher, &MemWatchWidget::mustUnhook, this, &MainWindow::onUnhook);

m_copier = new DlgCopy(this);

m_lblDolphinStatus = new QLabel("");
m_lblDolphinStatus->setAlignment(Qt::AlignHCenter);

m_lblMem2Status = new QLabel("");
m_lblMem2Status->setAlignment(Qt::AlignHCenter);
}

void MainWindow::makeLayouts()
Expand All @@ -187,15 +182,21 @@ void MainWindow::makeLayouts()

connect(m_splitter, &QSplitter::splitterMoved, this, &MainWindow::onSplitterMoved);

QVBoxLayout* mainLayout = new QVBoxLayout;
mainLayout->addWidget(m_lblDolphinStatus);
mainLayout->addWidget(m_lblMem2Status);
mainLayout->addWidget(separatorline);
mainLayout->addWidget(m_splitter);
m_statusIcon = new QLabel;
m_statusLabel = new QLabel;

QWidget* statusWidget{new QWidget};
QHBoxLayout* statusLayout{new QHBoxLayout(statusWidget)};
statusLayout->setContentsMargins(0, 0, 0, 0);
statusLayout->setContentsMargins(statusLayout->spacing(), 0, 0, 0);
statusLayout->addWidget(m_statusIcon);
statusLayout->addWidget(m_statusLabel);

QStatusBar* const statusBar{new QStatusBar};
statusBar->addWidget(statusWidget);

QWidget* mainWidget = new QWidget();
mainWidget->setLayout(mainLayout);
setCentralWidget(mainWidget);
setCentralWidget(m_splitter);
setStatusBar(statusBar);
}

void MainWindow::makeMemViewer()
Expand Down Expand Up @@ -254,34 +255,17 @@ void MainWindow::onOpenMemViewerWithAddress(u32 address)

void MainWindow::updateMem2Status()
{
QString strMem2 = QString();
bool mem2 = DolphinComm::DolphinAccessor::isMEM2Present();
if (mem2)
strMem2 = tr("The extended Wii-only memory is present");
else
strMem2 = tr("The extended Wii-only memory is absent");

QString strAram = QString();
if (!mem2)
{
if (DolphinComm::DolphinAccessor::isARAMAccessible())
strAram = tr(", the ARAM is accessible");
else
strAram = tr(", the ARAM is inaccessible, turn off MMU to use it");
}
m_lblMem2Status->setText(strMem2 + strAram);
updateStatusBar();
m_viewer->onMEM2StatusChanged(DolphinComm::DolphinAccessor::isMEM2Present());
}

void MainWindow::updateDolphinHookingStatus()
{
updateStatusBar();
switch (DolphinComm::DolphinAccessor::getStatus())
{
case DolphinComm::DolphinAccessor::DolphinStatus::hooked:
{
m_lblDolphinStatus->setText(
tr("Hooked successfully to Dolphin, current start address: ") +
QString::number(DolphinComm::DolphinAccessor::getEmuRAMAddressStart(), 16).toUpper());
m_scanner->setEnabled(true);
m_copier->setEnabled(true);
m_actMemoryViewer->setEnabled(true);
Expand All @@ -292,7 +276,6 @@ void MainWindow::updateDolphinHookingStatus()
}
case DolphinComm::DolphinAccessor::DolphinStatus::notRunning:
{
m_lblDolphinStatus->setText(tr("Cannot hook to Dolphin, the process is not running"));
m_scanner->setDisabled(true);
m_copier->setDisabled(true);
m_actMemoryViewer->setDisabled(true);
Expand All @@ -303,8 +286,6 @@ void MainWindow::updateDolphinHookingStatus()
}
case DolphinComm::DolphinAccessor::DolphinStatus::noEmu:
{
m_lblDolphinStatus->setText(
tr("Cannot hook to Dolphin, the process is running, but no emulation has been started"));
m_scanner->setDisabled(true);
m_copier->setDisabled(true);
m_actMemoryViewer->setDisabled(true);
Expand All @@ -315,7 +296,6 @@ void MainWindow::updateDolphinHookingStatus()
}
case DolphinComm::DolphinAccessor::DolphinStatus::unHooked:
{
m_lblDolphinStatus->setText(tr("Unhooked, press \"Hook\" to hook to Dolphin again"));
m_scanner->setDisabled(true);
m_copier->setDisabled(true);
m_actMemoryViewer->setDisabled(true);
Expand Down Expand Up @@ -350,7 +330,6 @@ void MainWindow::onUnhook()
m_watcher->getFreezeTimer()->stop();
m_viewer->getUpdateTimer()->stop();
m_viewer->hookStatusChanged(false);
m_lblMem2Status->setText(QString(""));
DolphinComm::DolphinAccessor::unHook();
updateDolphinHookingStatus();
}
Expand Down Expand Up @@ -583,3 +562,103 @@ void MainWindow::closeEvent(QCloseEvent* event)
m_viewer->close();
event->accept();
}

void MainWindow::updateStatusBar()
{
QIcon icon;
QStringList tags;
QStringList toolTipLines;

switch (DolphinComm::DolphinAccessor::getStatus())
{
case DolphinComm::DolphinAccessor::DolphinStatus::hooked:
{
static const QIcon s_icon(":/status_hooked.svg");
icon = s_icon;

tags << tr("Hooked");

const bool mem2{DolphinComm::DolphinAccessor::isMEM2Present()};
const bool aram{!mem2 && DolphinComm::DolphinAccessor::isARAMAccessible()};

std::array<char, sizeof("GM4E01")> gameID{};
if (DolphinComm::DolphinAccessor::readFromRAM(
Common::dolphinAddrToOffset(Common::MEM1_START, aram), gameID.data(), gameID.size(),
false))
{
for (char& c : gameID)
{
if (!std::isprint(c))
{
c = '?';
}
}
gameID.back() = '\0';
tags << QString(gameID.data());
}

toolTipLines
<< tr("Hooked to Dolphin successfully. Current start address: ") +
QString::number(DolphinComm::DolphinAccessor::getEmuRAMAddressStart(), 16).toUpper();

tags << tr("MEM1");
if (mem2)
{
tags << tr("MEM2");
toolTipLines << tr("The extended Wii-only memory is present.");
}
else
{
if (aram)
{
tags << tr("ARAM");
toolTipLines << tr("Dolphin's ARAM is accessible.");
}
else
{
toolTipLines << tr("Dolphin's ARAM is inaccessible; turn off MMU to use it.");
}
}

break;
}
case DolphinComm::DolphinAccessor::DolphinStatus::notRunning:
{
static const QIcon s_icon(":/status_absent.svg");
icon = s_icon;
tags << tr("Dolphin not detected");
toolTipLines << tr("Unable to hook to Dolphin. Dolphin does not appear to be running.");
break;
}
case DolphinComm::DolphinAccessor::DolphinStatus::noEmu:
{
static const QIcon s_icon(":/status_present.svg");
icon = s_icon;
tags << tr("No game running");
toolTipLines << tr("Unable to hook to Dolphin. The process appears to be running, but no "
"emulation has been started.");
break;
}
case DolphinComm::DolphinAccessor::DolphinStatus::unHooked:
{
static const QIcon s_icon(":/status_unhooked.svg");
icon = s_icon;
tags << tr("Unhooked");
toolTipLines << tr("Unhooked. Press <b>Dolphin > Hook</b> to hook to Dolphin.");
break;
}
}

const QSize actualIconSize{icon.actualSize(QSize(100, 100))};
const double aspectRatio{static_cast<double>(actualIconSize.width()) /
static_cast<double>(actualIconSize.height())};
const int fontHeight{fontMetrics().height()};
const int iconHeight{fontHeight};
const int iconWidth{static_cast<int>(std::round(static_cast<double>(iconHeight) * aspectRatio))};
m_statusIcon->setPixmap(icon.pixmap(iconWidth, iconHeight));

m_statusLabel->setText(tags.join(" | "));

const QString toolTip{toolTipLines.join("\n\n")};
m_statusLabel->parentWidget()->setToolTip(toolTip);
}
6 changes: 3 additions & 3 deletions Source/GUI/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class MainWindow : public QMainWindow
void initialiseWidgets();
void makeLayouts();
void makeMemViewer();
void updateStatusBar();

QSplitter* m_splitter{};

Expand All @@ -71,9 +72,6 @@ class MainWindow : public QMainWindow

QTimer m_autoHookTimer;

QLabel* m_lblDolphinStatus{};
QLabel* m_lblMem2Status{};

QMenu* m_menuFile{};
QMenu* m_menuEdit{};
QMenu* m_menuDolphin{};
Expand All @@ -94,4 +92,6 @@ class MainWindow : public QMainWindow
QAction* m_actScanner{};
QAction* m_actQuit{};
QAction* m_actAbout{};
QLabel* m_statusIcon{};
QLabel* m_statusLabel{};
};
4 changes: 4 additions & 0 deletions Source/Resources/resource.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,9 @@
<file>folder_empty.svg</file>
<file>folder.svg</file>
<file>logo.svg</file>
<file>status_absent.svg</file>
<file>status_hooked.svg</file>
<file>status_present.svg</file>
<file>status_unhooked.svg</file>
</qresource>
</RCC>
11 changes: 11 additions & 0 deletions Source/Resources/status_absent.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions Source/Resources/status_hooked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions Source/Resources/status_present.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions Source/Resources/status_unhooked.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 589429c

Please sign in to comment.