all repos — mgba @ 2aac9da42b7514ddb3105becf46de8dee5c797f2

mGBA Game Boy Advance Emulator

Qt: Add Dolphin connector dialog
Vicki Pfau vi@endrift.com
Sun, 14 Feb 2021 22:10:33 -0800
commit

2aac9da42b7514ddb3105becf46de8dee5c797f2

parent

b1828dbc59b8a9cc080c8c7f9472c46a3d39e90c

M src/platform/qt/CMakeLists.txtsrc/platform/qt/CMakeLists.txt

@@ -127,6 +127,7 @@ AssetTile.ui

BattleChipView.ui CheatsView.ui DebuggerConsole.ui + DolphinConnector.ui FrameView.ui GIFView.ui IOViewer.ui

@@ -155,6 +156,7 @@ set(GBA_SRC

BattleChipModel.cpp BattleChipUpdater.cpp BattleChipView.cpp + DolphinConnector.cpp GBAOverride.cpp) set(GB_SRC
M src/platform/qt/CoreController.cppsrc/platform/qt/CoreController.cpp

@@ -117,7 +117,9 @@ mCoreSaveState(context->core, 0, controller->m_saveStateFlags);

} controller->clearMultiplayerController(); +#ifdef M_CORE_GBA controller->detachDolphin(); +#endif QMetaObject::invokeMethod(controller, "stopping"); };

@@ -362,14 +364,12 @@ }

return m_cacheSet.get(); } -bool CoreController::connectDolphin(uint32_t ipv4) { +#ifdef M_CORE_GBA +bool CoreController::attachDolphin(const Address& address) { if (platform() != mPLATFORM_GBA) { return false; } - Address ipaddr; - ipaddr.version = IPV4; - ipaddr.ipv4 = htonl(ipv4); - if (GBASIODolphinConnect(&m_dolphin, &ipaddr, 0, 0)) { + if (GBASIODolphinConnect(&m_dolphin, &address, 0, 0)) { GBA* gba = static_cast<GBA*>(m_threadContext.core->board); GBASIOSetDriver(&gba->sio, &m_dolphin.d, SIO_JOYBUS); return true;

@@ -384,6 +384,7 @@ GBASIOSetDriver(&gba->sio, nullptr, SIO_JOYBUS);

} GBASIODolphinDestroy(&m_dolphin); } +#endif void CoreController::setOverride(std::unique_ptr<Override> override) { Interrupter interrupter(this);
M src/platform/qt/CoreController.hsrc/platform/qt/CoreController.h

@@ -108,8 +108,9 @@ void setMultiplayerController(MultiplayerController*);

void clearMultiplayerController(); MultiplayerController* multiplayerController() { return m_multiplayer; } - bool connectDolphin(uint32_t ipv4); - void detachDolphin(); +#ifdef M_CORE_GBA + bool isDolphinConnected() const { return !SOCKET_FAILED(m_dolphin.data); } +#endif mCacheSet* graphicCaches(); int stateSlot() const { return m_stateSlot; }

@@ -180,6 +181,9 @@ void attachBattleChipGate();

void detachBattleChipGate(); void setBattleChipId(uint16_t id); void setBattleChipFlavor(int flavor); + + bool attachDolphin(const Address& address); + void detachDolphin(); #endif void setAVStream(mAVStream*);
A src/platform/qt/DolphinConnector.cpp

@@ -0,0 +1,65 @@

+/* Copyright (c) 2013-2021 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "DolphinConnector.h" + +#include "CoreController.h" +#include "Window.h" +#include "utils.h" + +using namespace QGBA; + +DolphinConnector::DolphinConnector(Window* window, QWidget* parent) + : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint) + , m_window(window) +{ + m_ui.setupUi(this); + + connect(window, &QObject::destroyed, this, &QWidget::close); + connect(m_ui.connect, &QAbstractButton::clicked, this, &DolphinConnector::attach); + connect(m_ui.disconnect, &QAbstractButton::clicked, this, &DolphinConnector::detach); + + updateAttached(); +} + +void DolphinConnector::attach() { + QHostAddress qaddress; + Address address; + if (m_ui.specLocal->isChecked()) { + qaddress.setAddress("127.0.0.1"); + } else if (m_ui.specIPAddr->isChecked()) { + if (!qaddress.setAddress(m_ui.ipAddr->text())) { + return; + } + + } + if (!m_window->controller()) { + m_window->bootBIOS(); + if (!m_window->controller() || m_window->controller()->platform() != mPLATFORM_GBA) { + return; + } + } + + convertAddress(&qaddress, &address); + CoreController::Interrupter interrupter(m_window->controller()); + m_window->controller()->attachDolphin(address); + + updateAttached(); +} + +void DolphinConnector::detach() { + if (m_window->controller()) { + m_window->controller()->detachDolphin(); + } + updateAttached(); +} + +void DolphinConnector::updateAttached() { + bool attached = m_window->controller() && m_window->controller()->isDolphinConnected(); + m_ui.connect->setDisabled(attached); + m_ui.disconnect->setEnabled(attached); + m_ui.specLocal->setDisabled(attached); + m_ui.specIPAddr->setDisabled(attached); +}
A src/platform/qt/DolphinConnector.h

@@ -0,0 +1,33 @@

+/* Copyright (c) 2013-2021 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#pragma once + +#include "ui_DolphinConnector.h" + +namespace QGBA { + +class Window; + +class DolphinConnector : public QDialog { +Q_OBJECT + +public: + DolphinConnector(Window* window, QWidget* parent = nullptr); + +public slots: + void attach(); + void detach(); + +private slots: + void updateAttached(); + +private: + Ui::DolphinConnector m_ui; + + Window* m_window; +}; + +}
A src/platform/qt/DolphinConnector.ui

@@ -0,0 +1,127 @@

+<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>DolphinConnector</class> + <widget class="QDialog" name="DolphinConnector"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>306</width> + <height>119</height> + </rect> + </property> + <property name="windowTitle"> + <string>Connect to Dolphin</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetFixedSize</enum> + </property> + <item row="0" column="0"> + <widget class="QRadioButton" name="specLocal"> + <property name="text"> + <string>Local computer</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <attribute name="buttonGroup"> + <string notr="true">buttonGroup</string> + </attribute> + </widget> + </item> + <item row="0" column="1"> + <widget class="QRadioButton" name="specIPAddr"> + <property name="text"> + <string>IP address</string> + </property> + <attribute name="buttonGroup"> + <string notr="true">buttonGroup</string> + </attribute> + </widget> + </item> + <item row="2" column="0" colspan="2"> + <widget class="QLineEdit" name="ipAddr"> + <property name="enabled"> + <bool>false</bool> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="connect"> + <property name="text"> + <string>Connect</string> + </property> + <property name="icon"> + <iconset theme="network-connect"/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="disconnect"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Disconnect</string> + </property> + <property name="icon"> + <iconset theme="network-disconnect"/> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="close"> + <property name="text"> + <string>Close</string> + </property> + <property name="icon"> + <iconset theme="window-close"/> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>close</sender> + <signal>clicked()</signal> + <receiver>DolphinConnector</receiver> + <slot>close()</slot> + <hints> + <hint type="sourcelabel"> + <x>256</x> + <y>119</y> + </hint> + <hint type="destinationlabel"> + <x>152</x> + <y>72</y> + </hint> + </hints> + </connection> + <connection> + <sender>specIPAddr</sender> + <signal>toggled(bool)</signal> + <receiver>ipAddr</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>152</x> + <y>43</y> + </hint> + <hint type="destinationlabel"> + <x>152</x> + <y>49</y> + </hint> + </hints> + </connection> + </connections> + <buttongroups> + <buttongroup name="buttonGroup"/> + </buttongroups> +</ui>
M src/platform/qt/Window.cppsrc/platform/qt/Window.cpp

@@ -29,6 +29,7 @@ #include "CoreController.h"

#include "DebuggerConsole.h" #include "DebuggerConsoleController.h" #include "Display.h" +#include "DolphinConnector.h" #include "CoreController.h" #include "FrameView.h" #include "GBAApp.h"

@@ -325,6 +326,10 @@ QString filename = GBAApp::app()->getOpenFileName(this, tr("Select ROM"), getFilters());

if (!filename.isEmpty()) { setController(m_manager->loadGame(filename), filename); } +} + +void Window::bootBIOS() { + setController(m_manager->loadBIOS(mPLATFORM_GBA, m_config->getOption("gba.bios")), QString()); } #ifdef USE_SQLITE3

@@ -1097,9 +1102,7 @@

m_actions.addAction(tr("Load &patch..."), "loadPatch", this, &Window::selectPatch, "file"); #ifdef M_CORE_GBA - m_actions.addAction(tr("Boot BIOS"), "bootBIOS", [this]() { - setController(m_manager->loadBIOS(mPLATFORM_GBA, m_config->getOption("gba.bios")), QString()); - }, "file"); + m_actions.addAction(tr("Boot BIOS"), "bootBIOS", this, &Window::bootBIOS, "file"); #endif addGameAction(tr("Replace ROM..."), "replaceROM", this, &Window::replaceROM, "file");

@@ -1192,16 +1195,10 @@ m_multiWindow = m_actions.addAction(tr("New multiplayer window"), "multiWindow", [this]() {

GBAApp::app()->newWindow(); }, "file"); - Action* dolphin = m_actions.addAction(tr("Connect to Dolphin"), "connectDolphin", [this]() { - CoreController::Interrupter interrupter; - if (m_controller) { - interrupter.interrupt(m_controller); - } else { - setController(m_manager->loadBIOS(mPLATFORM_GBA, m_config->getOption("gba.bios")), QString()); - } - m_controller->connectDolphin(0x0100007F); - }, "file"); +#ifdef M_CORE_GBA + Action* dolphin = m_actions.addAction(tr("Connect to Dolphin..."), "connectDolphin", openTView<DolphinConnector>(this), "file"); m_platformActions.insert(mPLATFORM_GBA, dolphin); +#endif #ifndef Q_OS_MAC m_actions.addSeparator("file");
M src/platform/qt/Window.hsrc/platform/qt/Window.h

@@ -72,6 +72,7 @@

public slots: void setController(CoreController* controller, const QString& fname); void selectROM(); + void bootBIOS(); #ifdef USE_SQLITE3 void selectROMInArchive(); void addDirToLibrary();